diff options
Diffstat (limited to 'Utilities/cmcurl/lib/cf-h1-proxy.c')
-rw-r--r-- | Utilities/cmcurl/lib/cf-h1-proxy.c | 178 |
1 files changed, 94 insertions, 84 deletions
diff --git a/Utilities/cmcurl/lib/cf-h1-proxy.c b/Utilities/cmcurl/lib/cf-h1-proxy.c index b42c4e6..e9bc13d 100644 --- a/Utilities/cmcurl/lib/cf-h1-proxy.c +++ b/Utilities/cmcurl/lib/cf-h1-proxy.c @@ -41,7 +41,7 @@ #include "cfilters.h" #include "cf-h1-proxy.h" #include "connect.h" -#include "curl_log.h" +#include "curl_trc.h" #include "curlx.h" #include "vtls/vtls.h" #include "transfer.h" @@ -54,16 +54,16 @@ typedef enum { - TUNNEL_INIT, /* init/default/no tunnel state */ - TUNNEL_CONNECT, /* CONNECT request is being send */ - TUNNEL_RECEIVE, /* CONNECT answer is being received */ - TUNNEL_RESPONSE, /* CONNECT response received completely */ - TUNNEL_ESTABLISHED, - TUNNEL_FAILED -} tunnel_state; + H1_TUNNEL_INIT, /* init/default/no tunnel state */ + H1_TUNNEL_CONNECT, /* CONNECT request is being send */ + H1_TUNNEL_RECEIVE, /* CONNECT answer is being received */ + H1_TUNNEL_RESPONSE, /* CONNECT response received completely */ + H1_TUNNEL_ESTABLISHED, + H1_TUNNEL_FAILED +} h1_tunnel_state; /* struct for HTTP CONNECT tunneling */ -struct tunnel_state { +struct h1_tunnel_state { int sockindex; const char *hostname; int remote_port; @@ -78,23 +78,23 @@ struct tunnel_state { KEEPON_IGNORE } keepon; curl_off_t cl; /* size of content to read and ignore */ - tunnel_state tunnel_state; + h1_tunnel_state tunnel_state; BIT(chunked_encoding); BIT(close_connection); }; -static bool tunnel_is_established(struct tunnel_state *ts) +static bool tunnel_is_established(struct h1_tunnel_state *ts) { - return ts && (ts->tunnel_state == TUNNEL_ESTABLISHED); + return ts && (ts->tunnel_state == H1_TUNNEL_ESTABLISHED); } -static bool tunnel_is_failed(struct tunnel_state *ts) +static bool tunnel_is_failed(struct h1_tunnel_state *ts) { - return ts && (ts->tunnel_state == TUNNEL_FAILED); + return ts && (ts->tunnel_state == H1_TUNNEL_FAILED); } -static CURLcode tunnel_reinit(struct tunnel_state *ts, +static CURLcode tunnel_reinit(struct h1_tunnel_state *ts, struct connectdata *conn, struct Curl_easy *data) { @@ -102,7 +102,7 @@ static CURLcode tunnel_reinit(struct tunnel_state *ts, DEBUGASSERT(ts); Curl_dyn_reset(&ts->rcvbuf); Curl_dyn_reset(&ts->req); - ts->tunnel_state = TUNNEL_INIT; + ts->tunnel_state = H1_TUNNEL_INIT; ts->keepon = KEEPON_CONNECT; ts->cl = 0; ts->close_connection = FALSE; @@ -124,12 +124,12 @@ static CURLcode tunnel_reinit(struct tunnel_state *ts, return CURLE_OK; } -static CURLcode tunnel_init(struct tunnel_state **pts, +static CURLcode tunnel_init(struct h1_tunnel_state **pts, struct Curl_easy *data, struct connectdata *conn, int sockindex) { - struct tunnel_state *ts; + struct h1_tunnel_state *ts; CURLcode result; if(conn->handler->flags & PROTOPT_NOTCPPROXY) { @@ -157,16 +157,16 @@ static CURLcode tunnel_init(struct tunnel_state **pts, return tunnel_reinit(ts, conn, data); } -static void tunnel_go_state(struct Curl_cfilter *cf, - struct tunnel_state *ts, - tunnel_state new_state, - struct Curl_easy *data) +static void h1_tunnel_go_state(struct Curl_cfilter *cf, + struct h1_tunnel_state *ts, + h1_tunnel_state new_state, + struct Curl_easy *data) { if(ts->tunnel_state == new_state) return; /* leaving this one */ switch(ts->tunnel_state) { - case TUNNEL_CONNECT: + case H1_TUNNEL_CONNECT: data->req.ignorebody = FALSE; break; default: @@ -174,37 +174,37 @@ static void tunnel_go_state(struct Curl_cfilter *cf, } /* entering this one */ switch(new_state) { - case TUNNEL_INIT: - DEBUGF(LOG_CF(data, cf, "new tunnel state 'init'")); + case H1_TUNNEL_INIT: + CURL_TRC_CF(data, cf, "new tunnel state 'init'"); tunnel_reinit(ts, cf->conn, data); break; - case TUNNEL_CONNECT: - DEBUGF(LOG_CF(data, cf, "new tunnel state 'connect'")); - ts->tunnel_state = TUNNEL_CONNECT; + case H1_TUNNEL_CONNECT: + CURL_TRC_CF(data, cf, "new tunnel state 'connect'"); + ts->tunnel_state = H1_TUNNEL_CONNECT; ts->keepon = KEEPON_CONNECT; Curl_dyn_reset(&ts->rcvbuf); break; - case TUNNEL_RECEIVE: - DEBUGF(LOG_CF(data, cf, "new tunnel state 'receive'")); - ts->tunnel_state = TUNNEL_RECEIVE; + case H1_TUNNEL_RECEIVE: + CURL_TRC_CF(data, cf, "new tunnel state 'receive'"); + ts->tunnel_state = H1_TUNNEL_RECEIVE; break; - case TUNNEL_RESPONSE: - DEBUGF(LOG_CF(data, cf, "new tunnel state 'response'")); - ts->tunnel_state = TUNNEL_RESPONSE; + case H1_TUNNEL_RESPONSE: + CURL_TRC_CF(data, cf, "new tunnel state 'response'"); + ts->tunnel_state = H1_TUNNEL_RESPONSE; break; - case TUNNEL_ESTABLISHED: - DEBUGF(LOG_CF(data, cf, "new tunnel state 'established'")); + case H1_TUNNEL_ESTABLISHED: + CURL_TRC_CF(data, cf, "new tunnel state 'established'"); infof(data, "CONNECT phase completed"); data->state.authproxy.done = TRUE; data->state.authproxy.multipass = FALSE; /* FALLTHROUGH */ - case TUNNEL_FAILED: - if(new_state == TUNNEL_FAILED) - DEBUGF(LOG_CF(data, cf, "new tunnel state 'failed'")); + case H1_TUNNEL_FAILED: + if(new_state == H1_TUNNEL_FAILED) + CURL_TRC_CF(data, cf, "new tunnel state 'failed'"); ts->tunnel_state = new_state; Curl_dyn_reset(&ts->rcvbuf); Curl_dyn_reset(&ts->req); @@ -225,9 +225,9 @@ static void tunnel_go_state(struct Curl_cfilter *cf, static void tunnel_free(struct Curl_cfilter *cf, struct Curl_easy *data) { - struct tunnel_state *ts = cf->ctx; + struct h1_tunnel_state *ts = cf->ctx; if(ts) { - tunnel_go_state(cf, ts, TUNNEL_FAILED, data); + h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data); Curl_dyn_free(&ts->rcvbuf); Curl_dyn_free(&ts->req); free(ts); @@ -270,7 +270,7 @@ static CURLcode CONNECT_host(struct Curl_easy *data, #ifndef USE_HYPER static CURLcode start_CONNECT(struct Curl_cfilter *cf, struct Curl_easy *data, - struct tunnel_state *ts) + struct h1_tunnel_state *ts) { struct connectdata *conn = cf->conn; char *hostheader = NULL; @@ -351,7 +351,7 @@ out: static CURLcode send_CONNECT(struct Curl_easy *data, struct connectdata *conn, - struct tunnel_state *ts, + struct h1_tunnel_state *ts, bool *done) { struct SingleRequest *k = &data->req; @@ -399,7 +399,7 @@ out: static CURLcode on_resp_header(struct Curl_cfilter *cf, struct Curl_easy *data, - struct tunnel_state *ts, + struct h1_tunnel_state *ts, const char *header) { CURLcode result = CURLE_OK; @@ -416,7 +416,7 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf, if(!auth) return CURLE_OUT_OF_MEMORY; - DEBUGF(LOG_CF(data, cf, "CONNECT: fwd auth header '%s'", header)); + CURL_TRC_CF(data, cf, "CONNECT: fwd auth header '%s'", header); result = Curl_http_input_auth(data, proxy, auth); free(auth); @@ -475,7 +475,7 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf, static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, struct Curl_easy *data, - struct tunnel_state *ts, + struct h1_tunnel_state *ts, bool *done) { CURLcode result = CURLE_OK; @@ -587,7 +587,9 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, return result; } - data->info.header_size += (long)perline; + result = Curl_bump_headersize(data, perline, TRUE); + if(result) + return result; /* Newlines are CRLF, so the CR is ignored as the line isn't really terminated until the LF comes. Treat a following CR @@ -636,7 +638,7 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, /* without content-length or chunked encoding, we can't keep the connection alive since the close is the end signal so we bail out at once instead */ - DEBUGF(LOG_CF(data, cf, "CONNECT: no content-length or chunked")); + CURL_TRC_CF(data, cf, "CONNECT: no content-length or chunked"); ts->keepon = KEEPON_DONE; } } @@ -671,7 +673,7 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, /* The Hyper version of CONNECT */ static CURLcode start_CONNECT(struct Curl_cfilter *cf, struct Curl_easy *data, - struct tunnel_state *ts) + struct h1_tunnel_state *ts) { struct connectdata *conn = cf->conn; struct hyptransfer *h = &data->hyp; @@ -713,14 +715,13 @@ static CURLcode start_CONNECT(struct Curl_cfilter *cf, } options = hyper_clientconn_options_new(); - hyper_clientconn_options_set_preserve_header_case(options, 1); - hyper_clientconn_options_set_preserve_header_order(options, 1); - if(!options) { failf(data, "Couldn't create hyper client options"); result = CURLE_OUT_OF_MEMORY; goto error; } + hyper_clientconn_options_set_preserve_header_case(options, 1); + hyper_clientconn_options_set_preserve_header_order(options, 1); hyper_clientconn_options_exec(options, h->exec); @@ -751,6 +752,7 @@ static CURLcode start_CONNECT(struct Curl_cfilter *cf, client = hyper_task_value(task); hyper_task_free(task); + req = hyper_request_new(); if(!req) { failf(data, "Couldn't hyper_request_new"); @@ -859,12 +861,17 @@ static CURLcode start_CONNECT(struct Curl_cfilter *cf, result = CURLE_OUT_OF_MEMORY; goto error; } + req = NULL; if(HYPERE_OK != hyper_executor_push(h->exec, sendtask)) { failf(data, "Couldn't hyper_executor_push the send"); result = CURLE_OUT_OF_MEMORY; goto error; } + sendtask = NULL; /* ownership passed on */ + + hyper_clientconn_free(client); + client = NULL; error: free(host); @@ -877,12 +884,15 @@ error: hyper_task_free(handshake); if(client) hyper_clientconn_free(client); + if(req) + hyper_request_free(req); + return result; } static CURLcode send_CONNECT(struct Curl_easy *data, struct connectdata *conn, - struct tunnel_state *ts, + struct h1_tunnel_state *ts, bool *done) { struct hyptransfer *h = &data->hyp; @@ -919,7 +929,7 @@ error: static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, struct Curl_easy *data, - struct tunnel_state *ts, + struct h1_tunnel_state *ts, bool *done) { struct hyptransfer *h = &data->hyp; @@ -949,9 +959,9 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf, #endif /* USE_HYPER */ -static CURLcode CONNECT(struct Curl_cfilter *cf, - struct Curl_easy *data, - struct tunnel_state *ts) +static CURLcode H1_CONNECT(struct Curl_cfilter *cf, + struct Curl_easy *data, + struct h1_tunnel_state *ts) { struct connectdata *conn = cf->conn; CURLcode result; @@ -973,27 +983,27 @@ static CURLcode CONNECT(struct Curl_cfilter *cf, } switch(ts->tunnel_state) { - case TUNNEL_INIT: + case H1_TUNNEL_INIT: /* Prepare the CONNECT request and make a first attempt to send. */ - DEBUGF(LOG_CF(data, cf, "CONNECT start")); + CURL_TRC_CF(data, cf, "CONNECT start"); result = start_CONNECT(cf, data, ts); if(result) goto out; - tunnel_go_state(cf, ts, TUNNEL_CONNECT, data); + h1_tunnel_go_state(cf, ts, H1_TUNNEL_CONNECT, data); /* FALLTHROUGH */ - case TUNNEL_CONNECT: + case H1_TUNNEL_CONNECT: /* see that the request is completely sent */ - DEBUGF(LOG_CF(data, cf, "CONNECT send")); + CURL_TRC_CF(data, cf, "CONNECT send"); result = send_CONNECT(data, cf->conn, ts, &done); if(result || !done) goto out; - tunnel_go_state(cf, ts, TUNNEL_RECEIVE, data); + h1_tunnel_go_state(cf, ts, H1_TUNNEL_RECEIVE, data); /* FALLTHROUGH */ - case TUNNEL_RECEIVE: + case H1_TUNNEL_RECEIVE: /* read what is there */ - DEBUGF(LOG_CF(data, cf, "CONNECT receive")); + CURL_TRC_CF(data, cf, "CONNECT receive"); result = recv_CONNECT_resp(cf, data, ts, &done); if(Curl_pgrsUpdate(data)) { result = CURLE_ABORTED_BY_CALLBACK; @@ -1003,11 +1013,11 @@ static CURLcode CONNECT(struct Curl_cfilter *cf, if(result || !done) goto out; /* got it */ - tunnel_go_state(cf, ts, TUNNEL_RESPONSE, data); + h1_tunnel_go_state(cf, ts, H1_TUNNEL_RESPONSE, data); /* FALLTHROUGH */ - case TUNNEL_RESPONSE: - DEBUGF(LOG_CF(data, cf, "CONNECT response")); + case H1_TUNNEL_RESPONSE: + CURL_TRC_CF(data, cf, "CONNECT response"); if(data->req.newurl) { /* not the "final" response, we need to do a follow up request. * If the other side indicated a connection close, or if someone @@ -1019,7 +1029,7 @@ static CURLcode CONNECT(struct Curl_cfilter *cf, * reset our tunnel state. To avoid recursion, we return * and expect to be called again. */ - DEBUGF(LOG_CF(data, cf, "CONNECT need to close+open")); + CURL_TRC_CF(data, cf, "CONNECT need to close+open"); infof(data, "Connect me again please"); Curl_conn_cf_close(cf, data); connkeep(conn, "HTTP proxy CONNECT"); @@ -1028,7 +1038,7 @@ static CURLcode CONNECT(struct Curl_cfilter *cf, } else { /* staying on this connection, reset state */ - tunnel_go_state(cf, ts, TUNNEL_INIT, data); + h1_tunnel_go_state(cf, ts, H1_TUNNEL_INIT, data); } } break; @@ -1039,25 +1049,25 @@ static CURLcode CONNECT(struct Curl_cfilter *cf, } while(data->req.newurl); - DEBUGASSERT(ts->tunnel_state == TUNNEL_RESPONSE); + DEBUGASSERT(ts->tunnel_state == H1_TUNNEL_RESPONSE); if(data->info.httpproxycode/100 != 2) { /* a non-2xx response and we have no next url to try. */ Curl_safefree(data->req.newurl); - /* failure, close this connection to avoid re-use */ + /* failure, close this connection to avoid reuse */ streamclose(conn, "proxy CONNECT failure"); - tunnel_go_state(cf, ts, TUNNEL_FAILED, data); + h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data); failf(data, "CONNECT tunnel failed, response %d", data->req.httpcode); return CURLE_RECV_ERROR; } /* 2xx response, SUCCESS! */ - tunnel_go_state(cf, ts, TUNNEL_ESTABLISHED, data); + h1_tunnel_go_state(cf, ts, H1_TUNNEL_ESTABLISHED, data); infof(data, "CONNECT tunnel established, response %d", data->info.httpproxycode); result = CURLE_OK; out: if(result) - tunnel_go_state(cf, ts, TUNNEL_FAILED, data); + h1_tunnel_go_state(cf, ts, H1_TUNNEL_FAILED, data); return result; } @@ -1066,15 +1076,15 @@ static CURLcode cf_h1_proxy_connect(struct Curl_cfilter *cf, bool blocking, bool *done) { CURLcode result; - struct tunnel_state *ts = cf->ctx; + struct h1_tunnel_state *ts = cf->ctx; if(cf->connected) { *done = TRUE; return CURLE_OK; } - DEBUGF(LOG_CF(data, cf, "connect")); - result = cf->next->cft->connect(cf->next, data, blocking, done); + CURL_TRC_CF(data, cf, "connect"); + result = cf->next->cft->do_connect(cf->next, data, blocking, done); if(result || !*done) return result; @@ -1089,7 +1099,7 @@ static CURLcode cf_h1_proxy_connect(struct Curl_cfilter *cf, /* TODO: can we do blocking? */ /* We want "seamless" operations through HTTP proxy tunnel */ - result = CONNECT(cf, data, ts); + result = H1_CONNECT(cf, data, ts); if(result) goto out; Curl_safefree(data->state.aptr.proxyuserpwd); @@ -1107,7 +1117,7 @@ static int cf_h1_proxy_get_select_socks(struct Curl_cfilter *cf, struct Curl_easy *data, curl_socket_t *socks) { - struct tunnel_state *ts = cf->ctx; + struct h1_tunnel_state *ts = cf->ctx; int fds; fds = cf->next->cft->get_select_socks(cf->next, data, socks); @@ -1133,20 +1143,20 @@ static int cf_h1_proxy_get_select_socks(struct Curl_cfilter *cf, static void cf_h1_proxy_destroy(struct Curl_cfilter *cf, struct Curl_easy *data) { - DEBUGF(LOG_CF(data, cf, "destroy")); + CURL_TRC_CF(data, cf, "destroy"); tunnel_free(cf, data); } static void cf_h1_proxy_close(struct Curl_cfilter *cf, struct Curl_easy *data) { - DEBUGF(LOG_CF(data, cf, "close")); + CURL_TRC_CF(data, cf, "close"); cf->connected = FALSE; if(cf->ctx) { - tunnel_go_state(cf, cf->ctx, TUNNEL_INIT, data); + h1_tunnel_go_state(cf, cf->ctx, H1_TUNNEL_INIT, data); } if(cf->next) - cf->next->cft->close(cf->next, data); + cf->next->cft->do_close(cf->next, data); } |