diff options
Diffstat (limited to 'libs/libcurl/src/http_proxy.c')
-rw-r--r-- | libs/libcurl/src/http_proxy.c | 82 |
1 files changed, 58 insertions, 24 deletions
diff --git a/libs/libcurl/src/http_proxy.c b/libs/libcurl/src/http_proxy.c index a3a62c1cad..a7f7aa353f 100644 --- a/libs/libcurl/src/http_proxy.c +++ b/libs/libcurl/src/http_proxy.c @@ -61,7 +61,7 @@ static CURLcode https_proxy_connect(struct Curl_easy *data, int sockindex) if(!conn->bits.proxy_ssl_connected[sockindex]) { /* perform SSL initialization for this socket */ result = - Curl_ssl_connect_nonblocking(data, conn, sockindex, + Curl_ssl_connect_nonblocking(data, conn, TRUE, sockindex, &conn->bits.proxy_ssl_connected[sockindex]); if(result) /* a failed connection is marked for closure to prevent (bad) re-use or @@ -129,13 +129,13 @@ CURLcode Curl_proxy_connect(struct Curl_easy *data, int sockindex) bool Curl_connect_complete(struct connectdata *conn) { return !conn->connect_state || - (conn->connect_state->tunnel_state == TUNNEL_COMPLETE); + (conn->connect_state->tunnel_state >= TUNNEL_COMPLETE); } bool Curl_connect_ongoing(struct connectdata *conn) { return conn->connect_state && - (conn->connect_state->tunnel_state != TUNNEL_COMPLETE); + (conn->connect_state->tunnel_state <= TUNNEL_COMPLETE); } /* when we've sent a CONNECT to a proxy, we should rather either wait for the @@ -169,7 +169,7 @@ static CURLcode connect_init(struct Curl_easy *data, bool reinit) s = calloc(1, sizeof(struct http_connect_state)); if(!s) return CURLE_OUT_OF_MEMORY; - infof(data, "allocate connect buffer!\n"); + infof(data, "allocate connect buffer!"); conn->connect_state = s; Curl_dyn_init(&s->rcvbuf, DYN_PROXY_CONNECT_HEADERS); @@ -202,13 +202,16 @@ static void connect_done(struct Curl_easy *data) { struct connectdata *conn = data->conn; struct http_connect_state *s = conn->connect_state; - s->tunnel_state = TUNNEL_COMPLETE; - Curl_dyn_free(&s->rcvbuf); - Curl_dyn_free(&s->req); + if(s->tunnel_state != TUNNEL_EXIT) { + s->tunnel_state = TUNNEL_EXIT; + Curl_dyn_free(&s->rcvbuf); + Curl_dyn_free(&s->req); - /* retore the protocol pointer */ - data->req.p.http = s->prot_save; - infof(data, "CONNECT phase completed!\n"); + /* retore the protocol pointer */ + data->req.p.http = s->prot_save; + s->prot_save = NULL; + infof(data, "CONNECT phase completed!"); + } } static CURLcode CONNECT_host(struct Curl_easy *data, @@ -243,11 +246,11 @@ static CURLcode CONNECT_host(struct Curl_easy *data, return CURLE_OK; } +#ifndef USE_HYPER static CURLcode CONNECT(struct Curl_easy *data, int sockindex, const char *hostname, int remote_port) -#ifndef USE_HYPER { int subversion = 0; struct SingleRequest *k = &data->req; @@ -275,7 +278,7 @@ static CURLcode CONNECT(struct Curl_easy *data, char *hostheader = NULL; char *host = NULL; - infof(data, "Establish HTTP proxy tunnel to %s:%d\n", + infof(data, "Establish HTTP proxy tunnel to %s:%d", hostname, remote_port); /* This only happens if we've looped here due to authentication @@ -416,7 +419,7 @@ static CURLcode CONNECT(struct Curl_easy *data, /* proxy auth was requested and there was proxy auth available, then deem this as "mere" proxy disconnect */ conn->bits.proxy_connect_closed = TRUE; - infof(data, "Proxy CONNECT connection closed\n"); + infof(data, "Proxy CONNECT connection closed"); } else { error = SELECT_ERROR; @@ -451,7 +454,7 @@ static CURLcode CONNECT(struct Curl_easy *data, r = Curl_httpchunk_read(data, &byte, 1, &tookcareof, &extra); if(r == CHUNKE_STOP) { /* we're done reading chunks! */ - infof(data, "chunk reading DONE\n"); + infof(data, "chunk reading DONE"); s->keepon = KEEPON_DONE; /* we did the full CONNECT treatment, go COMPLETE */ s->tunnel_state = TUNNEL_COMPLETE; @@ -510,13 +513,13 @@ static CURLcode CONNECT(struct Curl_easy *data, if(s->cl) { infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T - " bytes of response-body\n", s->cl); + " bytes of response-body", s->cl); } else if(s->chunked_encoding) { CHUNKcode r; CURLcode extra; - infof(data, "Ignore chunked response-body\n"); + infof(data, "Ignore chunked response-body"); /* We set ignorebody true here since the chunked decoder function will acknowledge that. Pay attention so that this is @@ -533,7 +536,7 @@ static CURLcode CONNECT(struct Curl_easy *data, &extra); if(r == CHUNKE_STOP) { /* we're done reading chunks! */ - infof(data, "chunk reading DONE\n"); + infof(data, "chunk reading DONE"); s->keepon = KEEPON_DONE; /* we did the full CONNECT treatment, go to COMPLETE */ s->tunnel_state = TUNNEL_COMPLETE; @@ -579,7 +582,7 @@ static CURLcode CONNECT(struct Curl_easy *data, /* A client MUST ignore any Content-Length or Transfer-Encoding header fields received in a successful response to CONNECT. "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ - infof(data, "Ignoring Content-Length in CONNECT %03d response\n", + infof(data, "Ignoring Content-Length in CONNECT %03d response", k->httpcode); } else { @@ -595,11 +598,11 @@ static CURLcode CONNECT(struct Curl_easy *data, header fields received in a successful response to CONNECT. "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */ infof(data, "Ignoring Transfer-Encoding in " - "CONNECT %03d response\n", k->httpcode); + "CONNECT %03d response", k->httpcode); } else if(Curl_compareheader(linep, "Transfer-Encoding:", "chunked")) { - infof(data, "CONNECT responded chunked\n"); + infof(data, "CONNECT responded chunked"); s->chunked_encoding = TRUE; /* init our chunky engine */ Curl_httpchunk_init(data); @@ -657,7 +660,7 @@ static CURLcode CONNECT(struct Curl_easy *data, if(data->info.httpproxycode/100 != 2) { if(s->close_connection && data->req.newurl) { conn->bits.proxy_connect_closed = TRUE; - infof(data, "Connect me again please\n"); + infof(data, "Connect me again please"); connect_done(data); } else { @@ -692,7 +695,7 @@ static CURLcode CONNECT(struct Curl_easy *data, data->state.authproxy.done = TRUE; data->state.authproxy.multipass = FALSE; - infof(data, "Proxy replied %d to CONNECT request\n", + infof(data, "Proxy replied %d to CONNECT request", data->info.httpproxycode); data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */ conn->bits.rewindaftersend = FALSE; /* make sure this isn't set for the @@ -702,6 +705,10 @@ static CURLcode CONNECT(struct Curl_easy *data, } #else /* The Hyper version of CONNECT */ +static CURLcode CONNECT(struct Curl_easy *data, + int sockindex, + const char *hostname, + int remote_port) { struct connectdata *conn = data->conn; struct hyptransfer *h = &data->hyp; @@ -740,6 +747,8 @@ static CURLcode CONNECT(struct Curl_easy *data, hyper_io_set_write(io, Curl_hyper_send); conn->sockfd = tunnelsocket; + data->state.hconnect = TRUE; + /* create an executor to poll futures */ if(!h->exec) { h->exec = hyper_executor_new(); @@ -875,7 +884,6 @@ static CURLcode CONNECT(struct Curl_easy *data, goto error; if(!done) break; - fprintf(stderr, "done\n"); s->tunnel_state = TUNNEL_COMPLETE; if(h->exec) { hyper_executor_free(h->exec); @@ -897,6 +905,33 @@ static CURLcode CONNECT(struct Curl_easy *data, } while(data->req.newurl); result = CURLE_OK; + if(s->tunnel_state == TUNNEL_COMPLETE) { + data->info.httpproxycode = data->req.httpcode; + if(data->info.httpproxycode/100 != 2) { + if(conn->bits.close && data->req.newurl) { + conn->bits.proxy_connect_closed = TRUE; + infof(data, "Connect me again please"); + connect_done(data); + } + else { + free(data->req.newurl); + data->req.newurl = NULL; + /* failure, close this connection to avoid re-use */ + streamclose(conn, "proxy CONNECT failure"); + Curl_closesocket(data, conn, conn->sock[sockindex]); + conn->sock[sockindex] = CURL_SOCKET_BAD; + } + + /* to back to init state */ + s->tunnel_state = TUNNEL_INIT; + + if(!conn->bits.proxy_connect_closed) { + failf(data, "Received HTTP code %d from proxy after CONNECT", + data->req.httpcode); + result = CURLE_RECV_ERROR; + } + } + } error: free(host); free(hostheader); @@ -917,7 +952,6 @@ static CURLcode CONNECT(struct Curl_easy *data, } return result; } - #endif void Curl_connect_free(struct Curl_easy *data) |