summaryrefslogtreecommitdiff
path: root/src/transports/http.c
Commit message (Collapse)AuthorAgeFilesLines
* str: introduce `git_str` for internal, `git_buf` is externalethomson/gitstrEdward Thomson2021-10-171-3/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | libgit2 has two distinct requirements that were previously solved by `git_buf`. We require: 1. A general purpose string class that provides a number of utility APIs for manipulating data (eg, concatenating, truncating, etc). 2. A structure that we can use to return strings to callers that they can take ownership of. By using a single class (`git_buf`) for both of these purposes, we have confused the API to the point that refactorings are difficult and reasoning about correctness is also difficult. Move the utility class `git_buf` to be called `git_str`: this represents its general purpose, as an internal string buffer class. The name also is an homage to Junio Hamano ("gitstr"). The public API remains `git_buf`, and has a much smaller footprint. It is generally only used as an "out" param with strict requirements that follow the documentation. (Exceptions exist for some legacy APIs to avoid breaking callers unnecessarily.) Utility functions exist to convert a user-specified `git_buf` to a `git_str` so that we can call internal functions, then converting it back again.
* remote: refactor proxy detectionEdward Thomson2021-09-011-3/+1
| | | | | | | | | | Update the proxy detection for a remote. 1. Honor `http.<url>.proxy` syntax for a remote's direct URL and parent URLs. 2. Honor an empty configuration URL to override a proxy configuration. Add tests to ensure that configuration specificity is honored.
* Add NO_PROXY env supportMathieu Parent2021-09-011-1/+1
| | | | | | Item 2 of 3 from #4164 Signed-off-by: Mathieu Parent <math.parent@gmail.com>
* Merge branch 'main' into http-use-eauthEdward Thomson2021-08-291-8/+12
|\
| * http: don't require a passwordethomson/http_empty_passwordEdward Thomson2021-08-051-2/+6
| | | | | | | | | | | | | | | | Attempt authentication when a username is presented but a password is not; this can happen in particular when users are doing token authentication and specifying the token in the URL itself. For example, `https://token@host/` is a valid URI and should be treated as a username of `token` with an empty password.
| * transports: use GIT_ASSERTEdward Thomson2020-11-271-5/+6
| |
| * runtime: move init/shutdown into the "runtime"Edward Thomson2020-10-111-1/+0
| | | | | | | | | | Provide a mechanism for system components to register for initialization and shutdown of the libgit2 runtime.
* | transports: use GIT_EAUTH for authentication failuresJosh Bleecher Snyder2020-02-071-6/+6
|/ | | | | | | | | When the failure is clearly an auth failure (as opposed to possibly an auth failure), use the error code GIT_EAUTH instead of GIT_ERROR. While we're here, fix a typo and improve an error message. Fixes #5389.
* transports: http: fix custom headers not being appliedPatrick Steinhardt2020-02-071-0/+1
| | | | | | | | | | | | | | In commit b9c5b15a7 (http: use the new httpclient, 2019-12-22), the HTTP code got refactored to extract a generic HTTP client that operates independently of the Git protocol. Part of refactoring was the creation of a new `git_http_request` struct that encapsulates the generation of requests. Our Git-specific HTTP transport was converted to use that in `generate_request`, but during the process we forgot to set up custom headers for the `git_http_request` and as a result we do not send out these headers anymore. Fix the issue by correctly setting up the request's custom headers and add a test to verify we correctly send them.
* credential: change git_cred to git_credentialethomson/credtypeEdward Thomson2020-01-261-11/+11
| | | | | | | | | | | | | | | | We avoid abbreviations where possible; rename git_cred to git_credential. In addition, we have standardized on a trailing `_t` for enum types, instead of using "type" in the name. So `git_credtype_t` has become `git_credential_t` and its members have become `GIT_CREDENTIAL` instead of `GIT_CREDTYPE`. Finally, the source and header files have been renamed to `credential` instead of `cred`. Keep previous name and values as deprecated, and include the new header files from the previous ones.
* http: introduce GIT_ERROR_HTTPethomson/gssapiEdward Thomson2020-01-241-12/+12
| | | | | Disambiguate between general network problems and HTTP problems in error codes.
* httpclient: use defines for status codesEdward Thomson2020-01-241-4/+5
|
* http: send probe packetsEdward Thomson2020-01-241-2/+67
| | | | | | | | | | | | | | | | | | | | | | When we're authenticating with a connection-based authentication scheme (NTLM, Negotiate), we need to make sure that we're still connected between the initial GET where we did the authentication and the POST that we're about to send. Our keep-alive session may have not kept alive, but more likely, some servers do not authenticate the entire keep-alive connection and may have "forgotten" that we were authenticated, namely Apache and nginx. Send a "probe" packet, that is an HTTP POST request to the upload-pack or receive-pack endpoint, that consists of an empty git pkt ("0000"). If we're authenticated, we'll get a 200 back. If we're not, we'll get a 401 back, and then we'll resend that probe packet with the first step of our authentication (asking to start authentication with the given scheme). We expect _yet another_ 401 back, with the authentication challenge. Finally, we will send our authentication response with the actual POST data. This will allow us to authenticate without draining the POST data in the initial request that gets us a 401.
* http: use the new httpclientEdward Thomson2020-01-241-1374/+406
| | | | | Untangle the notion of the http transport from the actual http implementation. The http transport now uses the httpclient.
* httpclient: support expect/continueEdward Thomson2020-01-241-1/+6
| | | | | | | | | | | | | Allow users to opt-in to expect/continue handling when sending a POST and we're authenticated with a "connection-based" authentication mechanism like NTLM or Negotiate. If the response is a 100, return to the caller (to allow them to post their body). If the response is *not* a 100, buffer the response for the caller. HTTP expect/continue is generally safe, but some legacy servers have not implemented it correctly. Require it to be opt-in.
* net: refactor gitno redirect handlingEdward Thomson2020-01-241-12/+1
| | | | Move the redirect handling into `git_net_url` for consistency.
* auth: update enum type name for consistencyethomson/typetEdward Thomson2020-01-181-4/+4
| | | | | libgit2 does not use `type_t` suffixes as it's redundant; thus, rename `git_http_authtype_t` to `git_http_auth_t` for consistency.
* http: avoid generating double slashes in urlJosh Bleecher Snyder2019-12-131-2/+6
| | | | | | | | Prior to this change, given a remote url with a trailing slash, such as http://localhost/a/, service requests would contain a double slash: http://localhost/a//info/refs?service=git-receive-pack. Detect and prevent that. Updates #5321
* cred: separate public interface from low-level detailsEtienne Samson2019-09-131-0/+1
|
* Merge pull request #5212 from libgit2/ethomson/creds_for_schemeEdward Thomson2019-09-091-8/+16
|\ | | | | Use an HTTP scheme that supports the given credentials
| * http: ensure the scheme supports the credentialsethomson/creds_for_schemeIan Hattendorf2019-08-231-4/+9
| | | | | | | | | | | | When a server responds with multiple scheme support - for example, Negotiate and NTLM are commonly used together - we need to ensure that we choose a scheme that supports the credentials.
| * http: allow dummy negotiation scheme to fail to actEdward Thomson2019-08-211-4/+7
| | | | | | | | | | | | | | | | | | | | | | The dummy negotiation scheme is used for known authentication strategies that do not wish to act. For example, when a server requests the "Negotiate" scheme but libgit2 is not built with Negotiate support, and will use the "dummy" strategy which will simply not act. Instead of setting `out` to NULL and returning a successful code, return `GIT_PASSTHROUGH` to indicate that it did not act and catch that error code.
* | transports: http: check for memory allocation failuresPatrick Steinhardt2019-08-231-1/+3
|/ | | | | | | | When allocating a chunk that is used to write to HTTP streams, we do not check for memory allocation errors. This may lead us to write to a `NULL` pointer and thus cause a segfault. Fix this by adding a call to `GIT_ERROR_CHECK_ALLOC`.
* Rename opt init functions to `options_init`Edward Thomson2019-06-141-1/+1
| | | | | | | | | | | | | In libgit2 nomenclature, when we need to verb a direct object, we name a function `git_directobject_verb`. Thus, if we need to init an options structure named `git_foo_options`, then the name of the function that does that should be `git_foo_options_init`. The previous names of `git_foo_init_options` is close - it _sounds_ as if it's initializing the options of a `foo`, but in fact `git_foo_options` is its own noun that should be respected. Deprecate the old names; they'll now call directly to the new ones.
* http: free auth context on failureethomson/netrefactorEdward Thomson2019-06-101-50/+63
| | | | | | | When we send HTTP credentials but the server rejects them, tear down the authentication context so that we can start fresh. To maintain this state, additionally move all of the authentication handling into `on_auth_required`.
* http: reconnect to proxy on connection closeEdward Thomson2019-06-101-3/+15
| | | | | | When we're issuing a CONNECT to a proxy, we expect to keep-alive to the proxy. However, during authentication negotiations, the proxy may close the connection. Reconnect if the server closes the connection.
* http: allow server to drop a keepalive connectionEdward Thomson2019-06-101-0/+15
| | | | | | | When we have a keep-alive connection to the server, that server may legally drop the connection for any reason once a successful request and response has occurred. It's common for servers to drop the connection after some amount of time or number of requests have occurred.
* http: stop on server EOFEdward Thomson2019-06-101-2/+12
| | | | | | | | We stop the read loop when we have read all the data. We should also consider the server's feelings. If the server hangs up on us, we need to stop our read loop. Otherwise, we'll try to read from the server - and fail - ad infinitum.
* http: teach auth mechanisms about connection affinityEdward Thomson2019-06-101-1/+1
| | | | | | Instead of using `is_complete` to decide whether we have connection or request affinity for authentication mechanisms, set a boolean on the mechanism definition itself.
* http: maintain authentication across connectionsEdward Thomson2019-06-101-6/+38
| | | | | | | | | | For request-based authentication mechanisms (Basic, Digest) we should keep the authentication context alive across socket connections, since the authentication headers must be transmitted with every request. However, we should continue to remove authentication contexts for mechanisms with connection affinity (NTLM, Negotiate) since we need to reauthenticate for every socket connection.
* http: simplify authentication mechanismsEdward Thomson2019-06-101-166/+156
| | | | | | | | | | | | | | | | | | | | | Hold an individual authentication context instead of trying to maintain all the contexts; we can select the preferred context during the initial negotiation. Subsequent authentication steps will re-use the chosen authentication (until such time as it's rejected) instead of trying to manage multiple contexts when all but one will never be used (since we can only authenticate with a single mechanism at a time.) Also, when we're given a 401 or 407 in the middle of challenge/response handling, short-circuit immediately without incrementing the retry count. The multi-step authentication is expected, and not a "retry" and should not be penalized as such. This means that we don't need to keep the contexts around and ensures that we do not unnecessarily fail for too many retries when we have challenge/response auth on a proxy and a server and potentially redirects in play as well.
* http: don't set the header in the auth tokenEdward Thomson2019-06-101-10/+20
|
* http: don't reset replay count after connectionEdward Thomson2019-06-101-1/+0
| | | | | | A "connection" to a server is transient, and we may reconnect to a server in the midst of authentication failures (if the remote indicates that we should, via `Connection: close`) or in a redirect.
* http: provide an NTLM authentication providerEdward Thomson2019-06-101-0/+2
|
* http: validate server's authentication typesEdward Thomson2019-06-101-42/+97
| | | | | | | | | | Ensure that the server supports the particular credential type that we're specifying. Previously we considered credential types as an input to an auth mechanism - since the HTTP transport only supported default credentials (via negotiate) and username/password credentials (via basic), this worked. However, if we are to add another mechanism that uses username/password credentials, we'll need to be careful to identify the types that are accepted.
* http: consume body on proxy auth failureEdward Thomson2019-06-101-4/+9
| | | | | | | | | | | We must always consume the full parser body if we're going to keep-alive. So in the authentication failure case, continue advancing the http message parser until it's complete, then we can retry the connection. Not doing so would mean that we have to tear the connection down and start over. Advancing through fully (even though we don't use the data) will ensure that we can retry a connection with keep-alive.
* http: always consume body on auth failureEdward Thomson2019-06-101-26/+25
| | | | | | | | | | | | | | | | | | | | | When we get an authentication failure, we must consume the entire body of the response. If we only read half of the body (on the assumption that we can ignore the rest) then we will never complete the parsing of the message. This means that we will never set the complete flag, and our replay must actually tear down the connection and try again. This is particularly problematic for stateful authentication mechanisms (SPNEGO, NTLM) that require that we keep the connection alive. Note that the prior code is only a problem when the 401 that we are parsing is too large to be read in a single chunked read from the http parser. But now we will continue to invoke the http parser until we've got a complete message in the authentication failed scenario. Note that we need not do anything with the message, so when we get an authentication failed, we'll stop adding data to our buffer, we'll simply loop in the parser and let it advance its internal state.
* http: don't realloc the requestEdward Thomson2019-06-101-33/+29
|
* http: examine keepalive status at message endEdward Thomson2019-06-101-3/+4
| | | | | | | | | | | | | | We cannot examine the keep-alive status of the http parser in `http_connect`; it's too late and the critical information about whether keep-alive is supported has been destroyed. Per the documentation for `http_should_keep_alive`: > If http_should_keep_alive() in the on_headers_complete or > on_message_complete callback returns 0, then this should be > the last message on the connection. Query then and set the state.
* http: increase the replay countEdward Thomson2019-06-101-1/+1
| | | | | | | | | Increase the permissible replay count; with multiple-step authentication schemes (NTLM, Negotiate), proxy authentication and redirects, we need to be mindful of the number of steps it takes to get connected. 7 seems high but can be exhausted quickly with just a single authentication failure over a redirected multi-state authentication pipeline.
* http: support https for proxiesEdward Thomson2019-06-101-8/+1
|
* net: rename gitno_connection_data to git_net_urlEdward Thomson2019-06-101-24/+24
| | | | | | | | | | "Connection data" is an imprecise and largely incorrect name; these structures are actually parsed URLs. Provide a parser that takes a URL string and produces a URL structure (if it is valid). Separate the HTTP redirect handling logic from URL parsing, keeping a `gitno_connection_data_handle_redirect` whose only job is redirect handling logic and does not parse URLs itself.
* transports: make use of the `GIT_CONTAINER_OF` macroEtienne Samson2019-04-161-6/+6
|
* streams: fix callers potentially only writing partial dataPatrick Steinhardt2019-01-311-13/+13
| | | | | | | | | | | | | | | | | | | | | Similar to the write(3) function, implementations of `git_stream_write` do not guarantee that all bytes are written. Instead, they return the number of bytes that actually have been written, which may be smaller than the total number of bytes. Furthermore, due to an interface design issue, we cannot ever write more than `SSIZE_MAX` bytes at once, as otherwise we cannot represent the number of bytes written to the caller. Unfortunately, no caller of `git_stream_write` ever checks the return value, except to verify that no error occurred. Due to this, they are susceptible to the case where only partial data has been written. Fix this by introducing a new function `git_stream__write_full`. In contrast to `git_stream_write`, it will always return either success or failure, without returning the number of bytes written. Thus, it is able to write all `SIZE_MAX` bytes and loop around `git_stream_write` until all data has been written. Adjust all callers except the BIO callbacks in our mbedtls and OpenSSL streams, which already do the right thing and require the amount of bytes written.
* git_error: use new names in internal APIs and usageEdward Thomson2019-01-221-31/+31
| | | | | Move to the `git_error` name in the internal API for error-related functions.
* proxy: fix crash on remote connection with GIT_PROXY_AUTO but no proxy is ↵Jason Haslam2019-01-141-0/+3
| | | | detected
* http: reset replay_count upon connectionethomson/proxyEdward Thomson2018-11-281-0/+1
| | | | | | | | | Reset the replay_count upon a successful connection. It's possible that we could encounter a situation where we connect successfully but need to replay a request - for example, a connection and initial request succeeds without authentication but a subsequent call does require authentication. Reset the replay count upon any successful request to afford subsequent replays room to manuever.
* http: don't allow SSL connections to a proxyEdward Thomson2018-11-281-1/+9
| | | | | Temporarily disallow SSL connections to a proxy until we can understand the valgrind warnings when tunneling OpenSSL over OpenSSL.
* http: only load proxy configuration during connectionEdward Thomson2018-11-281-2/+4
| | | | | | | | | | | | Only load the proxy configuration during connection; we need this data when we're going to connect to the server, however we may mutate it after connection (connecting through a CONNECT proxy means that we should send requests like normal). If we reload the proxy configuration but do not actually reconnect (because we're in a keep-alive session) then we will reload the proxy configuration that we should have mutated. Thus, only load the proxy configuration when we know that we're going to reconnect.
* http: disallow repeated headers from serversEdward Thomson2018-11-281-9/+18
| | | | | Don't allow servers to send us multiple Content-Type, Content-Length or Location headers.