summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2020-01-11 23:53:45 +0000
committerEdward Thomson <ethomson@edwardthomson.com>2020-01-24 10:39:56 -0600
commite9cef7c4b16b2cb572ac19fcd39217f7934cfa99 (patch)
treeb847c846e79c815c329ea6e7b843bdbf6ef82c86
parent7fd9b3f597d1910effd43149157d49127244a238 (diff)
downloadlibgit2-ethomson/gssapi.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.h3
-rw-r--r--src/transports/http.c24
-rw-r--r--src/transports/httpclient.c50
-rw-r--r--src/transports/winhttp.c38
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;
}