diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2020-01-11 23:53:45 +0000 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2020-01-24 10:39:56 -0600 |
commit | e9cef7c4b16b2cb572ac19fcd39217f7934cfa99 (patch) | |
tree | b847c846e79c815c329ea6e7b843bdbf6ef82c86 | |
parent | 7fd9b3f597d1910effd43149157d49127244a238 (diff) | |
download | libgit2-e9cef7c4b16b2cb572ac19fcd39217f7934cfa99.tar.gz |
http: introduce GIT_ERROR_HTTPethomson/gssapi
Disambiguate between general network problems and HTTP problems in error
codes.
-rw-r--r-- | include/git2/errors.h | 3 | ||||
-rw-r--r-- | src/transports/http.c | 24 | ||||
-rw-r--r-- | src/transports/httpclient.c | 50 | ||||
-rw-r--r-- | src/transports/winhttp.c | 38 |
4 files changed, 58 insertions, 57 deletions
diff --git a/include/git2/errors.h b/include/git2/errors.h index 4e19f8925..370b6ac49 100644 --- a/include/git2/errors.h +++ b/include/git2/errors.h @@ -106,7 +106,8 @@ typedef enum { GIT_ERROR_FILESYSTEM, GIT_ERROR_PATCH, GIT_ERROR_WORKTREE, - GIT_ERROR_SHA1 + GIT_ERROR_SHA1, + GIT_ERROR_HTTP } git_error_t; /** diff --git a/src/transports/http.c b/src/transports/http.c index 65435d1db..36f038ead 100644 --- a/src/transports/http.c +++ b/src/transports/http.c @@ -158,7 +158,7 @@ static int handle_auth( } if (error > 0) { - git_error_set(GIT_ERROR_NET, "%s authentication required but no callback set", server_type); + git_error_set(GIT_ERROR_HTTP, "%s authentication required but no callback set", server_type); error = -1; } @@ -175,7 +175,7 @@ GIT_INLINE(int) handle_remote_auth( http_subtransport *transport = OWNING_SUBTRANSPORT(stream); if (response->server_auth_credtypes == 0) { - git_error_set(GIT_ERROR_NET, "server requires authentication that we do not support"); + git_error_set(GIT_ERROR_HTTP, "server requires authentication that we do not support"); return -1; } @@ -197,7 +197,7 @@ GIT_INLINE(int) handle_proxy_auth( http_subtransport *transport = OWNING_SUBTRANSPORT(stream); if (response->proxy_auth_credtypes == 0) { - git_error_set(GIT_ERROR_NET, "proxy requires authentication that we do not support"); + git_error_set(GIT_ERROR_HTTP, "proxy requires authentication that we do not support"); return -1; } @@ -226,7 +226,7 @@ static int handle_response( if (allow_replay && git_http_response_is_redirect(response)) { if (!response->location) { - git_error_set(GIT_ERROR_NET, "redirect without location"); + git_error_set(GIT_ERROR_HTTP, "redirect without location"); return -1; } @@ -236,7 +236,7 @@ static int handle_response( return 0; } else if (git_http_response_is_redirect(response)) { - git_error_set(GIT_ERROR_NET, "unexpected redirect"); + git_error_set(GIT_ERROR_HTTP, "unexpected redirect"); return -1; } @@ -255,24 +255,24 @@ static int handle_response( return git_http_client_skip_body(transport->http_client); } else if (response->status == GIT_HTTP_STATUS_UNAUTHORIZED || response->status == GIT_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED) { - git_error_set(GIT_ERROR_NET, "unexpected authentication failure"); + git_error_set(GIT_ERROR_HTTP, "unexpected authentication failure"); return -1; } if (response->status != GIT_HTTP_STATUS_OK) { - git_error_set(GIT_ERROR_NET, "unexpected http status code: %d", response->status); + git_error_set(GIT_ERROR_HTTP, "unexpected http status code: %d", response->status); return -1; } /* The response must contain a Content-Type header. */ if (!response->content_type) { - git_error_set(GIT_ERROR_NET, "no content-type header in response"); + git_error_set(GIT_ERROR_HTTP, "no content-type header in response"); return -1; } /* The Content-Type header must match our expectation. */ if (strcmp(response->content_type, stream->service->response_type) != 0) { - git_error_set(GIT_ERROR_NET, "invalid content-type: '%s'", response->content_type); + git_error_set(GIT_ERROR_HTTP, "invalid content-type: '%s'", response->content_type); return -1; } @@ -411,7 +411,7 @@ static int http_stream_read( } if (stream->state == HTTP_STATE_SENDING_REQUEST) { - git_error_set(GIT_ERROR_NET, "too many redirects or authentication replays"); + git_error_set(GIT_ERROR_HTTP, "too many redirects or authentication replays"); error = -1; goto done; } @@ -548,7 +548,7 @@ static int http_stream_write( } if (stream->state == HTTP_STATE_NONE) { - git_error_set(GIT_ERROR_NET, + git_error_set(GIT_ERROR_HTTP, "too many redirects or authentication replays"); error = -1; goto done; @@ -653,7 +653,7 @@ static int http_action( return error; if ((service = select_service(action)) == NULL) { - git_error_set(GIT_ERROR_NET, "invalid action"); + git_error_set(GIT_ERROR_HTTP, "invalid action"); return -1; } diff --git a/src/transports/httpclient.c b/src/transports/httpclient.c index b565bf59b..7f44a26dc 100644 --- a/src/transports/httpclient.c +++ b/src/transports/httpclient.c @@ -154,7 +154,7 @@ static int on_header_complete(http_parser *parser) if (!strcasecmp("Content-Type", name->ptr)) { if (response->content_type) { - git_error_set(GIT_ERROR_NET, + git_error_set(GIT_ERROR_HTTP, "multiple content-type headers"); return -1; } @@ -166,14 +166,14 @@ static int on_header_complete(http_parser *parser) int64_t len; if (response->content_length) { - git_error_set(GIT_ERROR_NET, + git_error_set(GIT_ERROR_HTTP, "multiple content-length headers"); return -1; } if (git__strntol64(&len, value->ptr, value->size, NULL, 10) < 0 || len < 0) { - git_error_set(GIT_ERROR_NET, + git_error_set(GIT_ERROR_HTTP, "invalid content-length"); return -1; } @@ -196,7 +196,7 @@ static int on_header_complete(http_parser *parser) return -1; } else if (!strcasecmp("Location", name->ptr)) { if (response->location) { - git_error_set(GIT_ERROR_NET, + git_error_set(GIT_ERROR_HTTP, "multiple location headers"); return -1; } @@ -235,7 +235,7 @@ static int on_header_field(http_parser *parser, const char *str, size_t len) break; default: - git_error_set(GIT_ERROR_NET, + git_error_set(GIT_ERROR_HTTP, "header name seen at unexpected time"); return ctx->parse_status = PARSE_STATUS_ERROR; } @@ -258,7 +258,7 @@ static int on_header_value(http_parser *parser, const char *str, size_t len) break; default: - git_error_set(GIT_ERROR_NET, + git_error_set(GIT_ERROR_HTTP, "header value seen at unexpected time"); return ctx->parse_status = PARSE_STATUS_ERROR; } @@ -348,7 +348,7 @@ static int on_headers_complete(http_parser *parser) break; default: - git_error_set(GIT_ERROR_NET, + git_error_set(GIT_ERROR_HTTP, "header completion at unexpected time"); return ctx->parse_status = PARSE_STATUS_ERROR; } @@ -511,14 +511,14 @@ static const char *init_auth_context( int error; if (!best_scheme_and_challenge(&scheme, &challenge, challenges, credentials)) { - git_error_set(GIT_ERROR_NET, "could not find appropriate mechanism for credentials"); + git_error_set(GIT_ERROR_HTTP, "could not find appropriate mechanism for credentials"); return NULL; } error = scheme->init_context(&server->auth_context, &server->url); if (error == GIT_PASSTHROUGH) { - git_error_set(GIT_ERROR_NET, "'%s' authentication is not supported", scheme->name); + git_error_set(GIT_ERROR_HTTP, "'%s' authentication is not supported", scheme->name); return NULL; } @@ -585,7 +585,7 @@ static int apply_credentials( if (auth->connection_affinity) free_auth_context(server); } else if (!token.size) { - git_error_set(GIT_ERROR_NET, "failed to respond to authentication challange"); + git_error_set(GIT_ERROR_HTTP, "failed to respond to authentication challange"); error = -1; goto done; } @@ -745,7 +745,7 @@ static int check_certificate( else if (error == GIT_PASSTHROUGH) error = 0; else if (error && !git_error_last()) - git_error_set(GIT_ERROR_NET, + git_error_set(GIT_ERROR_HTTP, "user rejected certificate for %s", url->host); git_error_state_free(&last_error); @@ -864,7 +864,7 @@ GIT_INLINE(int) server_create_stream(git_http_server *server) else if (strcasecmp(url->scheme, "http") == 0) return git_socket_stream_new(&server->stream, url->host, url->port); - git_error_set(GIT_ERROR_NET, "unknown http scheme '%s'", url->scheme); + git_error_set(GIT_ERROR_HTTP, "unknown http scheme '%s'", url->scheme); return -1; } @@ -920,7 +920,7 @@ static int proxy_connect( error = GIT_RETRY; goto done; } else if (response.status != GIT_HTTP_STATUS_OK) { - git_error_set(GIT_ERROR_NET, "proxy returned unexpected status: %d", response.status); + git_error_set(GIT_ERROR_HTTP, "proxy returned unexpected status: %d", response.status); error = -1; goto done; } @@ -1044,7 +1044,7 @@ GIT_INLINE(int) client_read(git_http_client *client) max_len = min(max_len, INT_MAX); if (max_len == 0) { - git_error_set(GIT_ERROR_NET, "no room in output buffer"); + git_error_set(GIT_ERROR_HTTP, "no room in output buffer"); return -1; } @@ -1101,12 +1101,12 @@ GIT_INLINE(int) client_read_and_parse(git_http_client *client) http_errno = client->parser.http_errno; if (parsed_len > INT_MAX) { - git_error_set(GIT_ERROR_NET, "unexpectedly large parse"); + git_error_set(GIT_ERROR_HTTP, "unexpectedly large parse"); return -1; } if (parser->upgrade) { - git_error_set(GIT_ERROR_NET, "server requested upgrade"); + git_error_set(GIT_ERROR_HTTP, "server requested upgrade"); return -1; } @@ -1140,14 +1140,14 @@ GIT_INLINE(int) client_read_and_parse(git_http_client *client) /* Most failures will be reported in http_errno */ else if (parser->http_errno != HPE_OK) { - git_error_set(GIT_ERROR_NET, "http parser error: %s", + git_error_set(GIT_ERROR_HTTP, "http parser error: %s", http_errno_description(http_errno)); return -1; } /* Otherwise we should have consumed the entire buffer. */ else if (parsed_len != client->read_buf.size) { - git_error_set(GIT_ERROR_NET, + git_error_set(GIT_ERROR_HTTP, "http parser did not consume entire buffer: %s", http_errno_description(http_errno)); return -1; @@ -1155,7 +1155,7 @@ GIT_INLINE(int) client_read_and_parse(git_http_client *client) /* recv returned 0, the server hung up on us */ else if (!parsed_len) { - git_error_set(GIT_ERROR_NET, "unexpected EOF"); + git_error_set(GIT_ERROR_HTTP, "unexpected EOF"); return -1; } @@ -1281,7 +1281,7 @@ int git_http_client_send_body( return 0; if (client->state != SENDING_BODY) { - git_error_set(GIT_ERROR_NET, "client is in invalid state"); + git_error_set(GIT_ERROR_HTTP, "client is in invalid state"); return -1; } @@ -1317,7 +1317,7 @@ static int complete_request(git_http_client *client) assert(client && client->state == SENDING_BODY); if (client->request_body_len && client->request_body_remain) { - git_error_set(GIT_ERROR_NET, "truncated write"); + git_error_set(GIT_ERROR_HTTP, "truncated write"); error = -1; } else if (client->request_chunked) { error = stream_write(&client->server, "0\r\n\r\n", 5); @@ -1349,7 +1349,7 @@ int git_http_client_read_response( } if (client->state != SENT_REQUEST) { - git_error_set(GIT_ERROR_NET, "client is in invalid state"); + git_error_set(GIT_ERROR_HTTP, "client is in invalid state"); error = -1; goto done; } @@ -1392,7 +1392,7 @@ int git_http_client_read_body( return 0; if (client->state != READING_BODY) { - git_error_set(GIT_ERROR_NET, "client is in invalid state"); + git_error_set(GIT_ERROR_HTTP, "client is in invalid state"); return -1; } @@ -1438,7 +1438,7 @@ int git_http_client_skip_body(git_http_client *client) return 0; if (client->state != READING_BODY) { - git_error_set(GIT_ERROR_NET, "client is in invalid state"); + git_error_set(GIT_ERROR_HTTP, "client is in invalid state"); return -1; } @@ -1451,7 +1451,7 @@ int git_http_client_skip_body(git_http_client *client) if (parser_context.error != HPE_OK || (parser_context.parse_status != PARSE_STATUS_OK && parser_context.parse_status != PARSE_STATUS_NO_OUTPUT)) { - git_error_set(GIT_ERROR_NET, + git_error_set(GIT_ERROR_HTTP, "unexpected data handled in callback"); error = -1; } diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index d8623bfff..e9e53ae86 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -145,7 +145,7 @@ static int apply_userpass_credentials(HINTERNET request, DWORD target, int mecha } else if (mechanisms & GIT_WINHTTP_AUTH_BASIC) { native_scheme = WINHTTP_AUTH_SCHEME_BASIC; } else { - git_error_set(GIT_ERROR_NET, "invalid authentication scheme"); + git_error_set(GIT_ERROR_HTTP, "invalid authentication scheme"); error = -1; goto done; } @@ -184,7 +184,7 @@ static int apply_default_credentials(HINTERNET request, DWORD target, int mechan } else if ((mechanisms & GIT_WINHTTP_AUTH_NTLM) != 0) { native_scheme = WINHTTP_AUTH_SCHEME_NTLM; } else { - git_error_set(GIT_ERROR_NET, "invalid authentication scheme"); + git_error_set(GIT_ERROR_HTTP, "invalid authentication scheme"); return -1; } @@ -287,7 +287,7 @@ static int certificate_check(winhttp_stream *s, int valid) /* If there is no override, we should fail if WinHTTP doesn't think it's fine */ if (t->owner->certificate_check_cb == NULL && !valid) { if (!git_error_last()) - git_error_set(GIT_ERROR_NET, "unknown certificate check failure"); + git_error_set(GIT_ERROR_HTTP, "unknown certificate check failure"); return GIT_ECERTIFICATE; } @@ -311,7 +311,7 @@ static int certificate_check(winhttp_stream *s, int valid) error = valid ? 0 : GIT_ECERTIFICATE; if (error < 0 && !git_error_last()) - git_error_set(GIT_ERROR_NET, "user cancelled certificate check"); + git_error_set(GIT_ERROR_HTTP, "user cancelled certificate check"); return error; } @@ -440,7 +440,7 @@ static int winhttp_stream_connect(winhttp_stream *s) goto on_error; if (strcmp(t->proxy.url.scheme, "http") != 0 && strcmp(t->proxy.url.scheme, "https") != 0) { - git_error_set(GIT_ERROR_NET, "invalid URL: '%s'", proxy_url); + git_error_set(GIT_ERROR_HTTP, "invalid URL: '%s'", proxy_url); error = -1; goto on_error; } @@ -713,21 +713,21 @@ static void CALLBACK winhttp_status( status = *((DWORD *)info); if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID)) - git_error_set(GIT_ERROR_NET, "SSL certificate issued for different common name"); + git_error_set(GIT_ERROR_HTTP, "SSL certificate issued for different common name"); else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID)) - git_error_set(GIT_ERROR_NET, "SSL certificate has expired"); + git_error_set(GIT_ERROR_HTTP, "SSL certificate has expired"); else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA)) - git_error_set(GIT_ERROR_NET, "SSL certificate signed by unknown CA"); + git_error_set(GIT_ERROR_HTTP, "SSL certificate signed by unknown CA"); else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT)) - git_error_set(GIT_ERROR_NET, "SSL certificate is invalid"); + git_error_set(GIT_ERROR_HTTP, "SSL certificate is invalid"); else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED)) - git_error_set(GIT_ERROR_NET, "certificate revocation check failed"); + git_error_set(GIT_ERROR_HTTP, "certificate revocation check failed"); else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED)) - git_error_set(GIT_ERROR_NET, "SSL certificate was revoked"); + git_error_set(GIT_ERROR_HTTP, "SSL certificate was revoked"); else if ((status & WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR)) - git_error_set(GIT_ERROR_NET, "security libraries could not be loaded"); + git_error_set(GIT_ERROR_HTTP, "security libraries could not be loaded"); else - git_error_set(GIT_ERROR_NET, "unknown security error %lu", status); + git_error_set(GIT_ERROR_HTTP, "unknown security error %lu", status); } static int winhttp_connect( @@ -971,7 +971,7 @@ static int winhttp_stream_read( replay: /* Enforce a reasonable cap on the number of replays */ if (replay_count++ >= GIT_HTTP_REPLAY_MAX) { - git_error_set(GIT_ERROR_NET, "too many redirects or authentication replays"); + git_error_set(GIT_ERROR_HTTP, "too many redirects or authentication replays"); return -1; } @@ -1177,7 +1177,7 @@ replay: } if (HTTP_STATUS_OK != status_code) { - git_error_set(GIT_ERROR_NET, "request failed with status code: %lu", status_code); + git_error_set(GIT_ERROR_HTTP, "request failed with status code: %lu", status_code); return -1; } @@ -1204,7 +1204,7 @@ replay: } if (wcscmp(expected_content_type, content_type)) { - git_error_set(GIT_ERROR_NET, "received unexpected content-type"); + git_error_set(GIT_ERROR_HTTP, "received unexpected content-type"); return -1; } @@ -1239,7 +1239,7 @@ static int winhttp_stream_write_single( /* This implementation of write permits only a single call. */ if (s->sent_request) { - git_error_set(GIT_ERROR_NET, "subtransport configured for only one write"); + git_error_set(GIT_ERROR_HTTP, "subtransport configured for only one write"); return -1; } @@ -1270,12 +1270,12 @@ static int put_uuid_string(LPWSTR buffer, size_t buffer_len_cch) if (RPC_S_OK != status && RPC_S_UUID_LOCAL_ONLY != status && RPC_S_UUID_NO_ADDRESS != status) { - git_error_set(GIT_ERROR_NET, "unable to generate name for temp file"); + git_error_set(GIT_ERROR_HTTP, "unable to generate name for temp file"); return -1; } if (buffer_len_cch < UUID_LENGTH_CCH + 1) { - git_error_set(GIT_ERROR_NET, "buffer too small for name of temp file"); + git_error_set(GIT_ERROR_HTTP, "buffer too small for name of temp file"); return -1; } |