diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2014-08-30 14:04:57 +0200 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2014-09-16 17:01:31 +0200 |
commit | 67c84e06f3cef3e555ddb74a1de9affdc3f0688f (patch) | |
tree | 8f7c1800f84ee5ca42b47621171918bd7f53d144 | |
parent | 5f2cf732ab8ecbfdf69cad48a52c14483c7aa15f (diff) | |
download | libgit2-67c84e06f3cef3e555ddb74a1de9affdc3f0688f.tar.gz |
winhttp: bring together request sending
We need to call WinHttpSendRequest() in three different places. Unify all in a single function to have a single place for the certificate check.
-rw-r--r-- | src/transports/winhttp.c | 76 |
1 files changed, 44 insertions, 32 deletions
diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index e6bd1c9e1..14afce282 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -212,6 +212,10 @@ static int certificate_check(winhttp_stream *s, int valid) PCERT_CONTEXT cert_ctx; DWORD cert_ctx_size = sizeof(cert_ctx); + /* If there is no override, we should fail if WinHTTP doesn't think it's fine */ + if (t->owner->certificate_check_cb == NULL && !valid) + return GIT_ECERTIFICATE; + if (t->owner->certificate_check_cb == NULL || !t->connection_data.use_ssl) return 0; @@ -411,8 +415,6 @@ static int winhttp_stream_connect(winhttp_stream *s) goto on_error; } - /* set up the certificate failure callback */ - /* We've done everything up to calling WinHttpSendRequest. */ error = 0; @@ -556,6 +558,38 @@ on_error: return error; } +static int send_request(winhttp_stream *s, size_t len, int ignore_length) +{ + int request_failed = 0, cert_valid = 1, error = 0; + + if (ignore_length) { + if (!WinHttpSendRequest(s->request, + WINHTTP_NO_ADDITIONAL_HEADERS, 0, + WINHTTP_NO_REQUEST_DATA, 0, + WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, 0)) { + request_failed = 1; + } + } else { + if (!WinHttpSendRequest(s->request, + WINHTTP_NO_ADDITIONAL_HEADERS, 0, + WINHTTP_NO_REQUEST_DATA, 0, + len, 0)) { + request_failed = 1; + } + } + + if (request_failed && GetLastError() == ERROR_WINHTTP_SECURE_FAILURE) + cert_valid = 0; + + giterr_clear(); + if ((error = certificate_check(s, cert_valid)) < 0) { + if (!giterr_last()) + giterr_set(GITERR_OS, "failed to send request"); + } + + return error; +} + static int winhttp_stream_read( git_smart_subtransport_stream *stream, char *buffer, @@ -583,22 +617,16 @@ replay: DWORD status_code, status_code_length, content_type_length, bytes_written; char expected_content_type_8[MAX_CONTENT_TYPE_LEN]; wchar_t expected_content_type[MAX_CONTENT_TYPE_LEN], content_type[MAX_CONTENT_TYPE_LEN]; + int request_failed = 0, cert_valid = 1; if (!s->sent_request) { - if (!WinHttpSendRequest(s->request, - WINHTTP_NO_ADDITIONAL_HEADERS, 0, - WINHTTP_NO_REQUEST_DATA, 0, - s->post_body_len, 0)) { - giterr_set(GITERR_OS, "Failed to send request"); - return -1; - } + + if ((error = send_request(s, s->post_body_len, 0)) < 0) + return error; s->sent_request = 1; } - if ((error = certificate_check(s, 1)) < 0) - return error; - if (s->chunked) { assert(s->verb == post_verb); @@ -859,19 +887,11 @@ static int winhttp_stream_write_single( return -1; } - if (!WinHttpSendRequest(s->request, - WINHTTP_NO_ADDITIONAL_HEADERS, 0, - WINHTTP_NO_REQUEST_DATA, 0, - (DWORD)len, 0)) { - giterr_set(GITERR_OS, "Failed to send request"); - return -1; - } + if ((error = send_request(s, len, 0)) < 0) + return error; s->sent_request = 1; - if ((error = certificate_check(s, 1)) < 0) - return error; - if (!WinHttpWriteData(s->request, (LPCVOID)buffer, (DWORD)len, @@ -1005,20 +1025,12 @@ static int winhttp_stream_write_chunked( return -1; } - if (!WinHttpSendRequest(s->request, - WINHTTP_NO_ADDITIONAL_HEADERS, 0, - WINHTTP_NO_REQUEST_DATA, 0, - WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, 0)) { - giterr_set(GITERR_OS, "Failed to send request"); - return -1; - } + if ((error = send_request(s, 0, 1)) < 0) + return error; s->sent_request = 1; } - if ((error = certificate_check(s, 1)) < 0) - return error; - if (len > CACHED_POST_BODY_BUF_SIZE) { /* Flush, if necessary */ if (s->chunk_buffer_len > 0) { |