summaryrefslogtreecommitdiffstats
path: root/Utilities/cmcurl/lib/cf-h1-proxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcurl/lib/cf-h1-proxy.c')
-rw-r--r--Utilities/cmcurl/lib/cf-h1-proxy.c178
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);
}