summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2023-01-05 09:38:11 +0100
committerDaniel Stenberg <daniel@haxx.se>2023-01-05 23:43:02 +0100
commit3f3ddee0665176040b3eaf89a912a922726ecb18 (patch)
tree01023f36e2b245471228dbc001204432194865a7 /lib
parent446267c5559aaf7d3f622dbb15883aeec3bffef9 (diff)
downloadcurl-3f3ddee0665176040b3eaf89a912a922726ecb18.tar.gz
http_proxy: do not assign data->req.p.http use local copy
Avoid the tricky reusing of the data->req.p.http pointer for http proxy tunneling. Fixes #10194 Closes #10234
Diffstat (limited to 'lib')
-rw-r--r--lib/http.c32
-rw-r--r--lib/http.h3
-rw-r--r--lib/http_proxy.c25
-rw-r--r--lib/rtsp.c2
4 files changed, 29 insertions, 33 deletions
diff --git a/lib/http.c b/lib/http.c
index 10c62bf56..a33251e5d 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -1248,8 +1248,8 @@ static size_t readmoredata(char *buffer,
size_t nitems,
void *userp)
{
- struct Curl_easy *data = (struct Curl_easy *)userp;
- struct HTTP *http = data->req.p.http;
+ struct HTTP *http = (struct HTTP *)userp;
+ struct Curl_easy *data = http->backup.data;
size_t fullsize = size * nitems;
if(!http->postsize)
@@ -1301,6 +1301,7 @@ static size_t readmoredata(char *buffer,
*/
CURLcode Curl_buffer_send(struct dynbuf *in,
struct Curl_easy *data,
+ struct HTTP *http,
/* add the number of sent bytes to this
counter */
curl_off_t *bytes_written,
@@ -1313,7 +1314,6 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
char *ptr;
size_t size;
struct connectdata *conn = data->conn;
- struct HTTP *http = data->req.p.http;
size_t sendsize;
curl_socket_t sockfd;
size_t headersize;
@@ -1448,10 +1448,11 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
http->backup.fread_in = data->state.in;
http->backup.postdata = http->postdata;
http->backup.postsize = http->postsize;
+ http->backup.data = data;
/* set the new pointers for the request-sending */
data->state.fread_func = (curl_read_callback)readmoredata;
- data->state.in = (void *)data;
+ data->state.in = (void *)http;
http->postdata = ptr;
http->postsize = (curl_off_t)size;
@@ -1460,7 +1461,6 @@ CURLcode Curl_buffer_send(struct dynbuf *in,
http->send_buffer = *in; /* copy the whole struct */
http->sending = HTTPSEND_REQUEST;
-
return CURLE_OK;
}
http->sending = HTTPSEND_BODY;
@@ -2342,7 +2342,7 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
curl_off_t included_body = 0;
#else
/* from this point down, this function should not be used */
-#define Curl_buffer_send(a,b,c,d,e) CURLE_OK
+#define Curl_buffer_send(a,b,c,d,e,f) CURLE_OK
#endif
CURLcode result = CURLE_OK;
struct HTTP *http = data->req.p.http;
@@ -2386,7 +2386,8 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
Curl_pgrsSetUploadSize(data, http->postsize);
/* this sends the buffer and frees all the buffer resources */
- result = Curl_buffer_send(r, data, &data->info.request_size, 0,
+ result = Curl_buffer_send(r, data, data->req.p.http,
+ &data->info.request_size, 0,
FIRSTSOCKET);
if(result)
failf(data, "Failed sending PUT request");
@@ -2407,7 +2408,8 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
if(result)
return result;
- result = Curl_buffer_send(r, data, &data->info.request_size, 0,
+ result = Curl_buffer_send(r, data, data->req.p.http,
+ &data->info.request_size, 0,
FIRSTSOCKET);
if(result)
failf(data, "Failed sending POST request");
@@ -2478,7 +2480,8 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
http->sending = HTTPSEND_BODY;
/* this sends the buffer and frees all the buffer resources */
- result = Curl_buffer_send(r, data, &data->info.request_size, 0,
+ result = Curl_buffer_send(r, data, data->req.p.http,
+ &data->info.request_size, 0,
FIRSTSOCKET);
if(result)
failf(data, "Failed sending POST request");
@@ -2595,11 +2598,10 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
else {
/* A huge POST coming up, do data separate from the request */
http->postdata = data->set.postfields;
-
http->sending = HTTPSEND_BODY;
-
+ http->backup.data = data;
data->state.fread_func = (curl_read_callback)readmoredata;
- data->state.in = (void *)data;
+ data->state.in = (void *)http;
/* set the upload size to the progress meter */
Curl_pgrsSetUploadSize(data, http->postsize);
@@ -2638,7 +2640,8 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
}
}
/* issue the request */
- result = Curl_buffer_send(r, data, &data->info.request_size, included_body,
+ result = Curl_buffer_send(r, data, data->req.p.http,
+ &data->info.request_size, included_body,
FIRSTSOCKET);
if(result)
@@ -2654,7 +2657,8 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
return result;
/* issue the request */
- result = Curl_buffer_send(r, data, &data->info.request_size, 0,
+ result = Curl_buffer_send(r, data, data->req.p.http,
+ &data->info.request_size, 0,
FIRSTSOCKET);
if(result)
failf(data, "Failed sending HTTP request");
diff --git a/lib/http.h b/lib/http.h
index 8739290d9..99ec7169e 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -74,8 +74,10 @@ char *Curl_checkProxyheaders(struct Curl_easy *data,
const struct connectdata *conn,
const char *thisheader,
const size_t thislen);
+struct HTTP; /* see below */
CURLcode Curl_buffer_send(struct dynbuf *in,
struct Curl_easy *data,
+ struct HTTP *http,
curl_off_t *bytes_written,
curl_off_t included_body_bytes,
int socketindex);
@@ -198,6 +200,7 @@ struct HTTP {
void *fread_in; /* backup storage for fread_in pointer */
const char *postdata;
curl_off_t postsize;
+ struct Curl_easy *data;
} backup;
enum {
diff --git a/lib/http_proxy.c b/lib/http_proxy.c
index 4c05c66c8..1afea5491 100644
--- a/lib/http_proxy.c
+++ b/lib/http_proxy.c
@@ -74,8 +74,7 @@ struct tunnel_state {
int sockindex;
const char *hostname;
int remote_port;
- struct HTTP http_proxy;
- struct HTTP *prot_save;
+ struct HTTP CONNECT;
struct dynbuf rcvbuf;
struct dynbuf req;
size_t nsend;
@@ -160,17 +159,6 @@ static CURLcode tunnel_init(struct tunnel_state **pts,
Curl_dyn_init(&ts->rcvbuf, DYN_PROXY_CONNECT_HEADERS);
Curl_dyn_init(&ts->req, DYN_HTTP_REQUEST);
- /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
- * member conn->proto.http; we want [protocol] through HTTP and we have
- * to change the member temporarily for connecting to the HTTP
- * proxy. After Curl_proxyCONNECT we have to set back the member to the
- * original pointer
- *
- * This function might be called several times in the multi interface case
- * if the proxy's CONNECT response is not instant.
- */
- ts->prot_save = data->req.p.http;
- data->req.p.http = &ts->http_proxy;
*pts = ts;
connkeep(conn, "HTTP proxy CONNECT");
return tunnel_reinit(ts, conn, data);
@@ -227,7 +215,6 @@ static void tunnel_go_state(struct Curl_cfilter *cf,
Curl_dyn_reset(&ts->rcvbuf);
Curl_dyn_reset(&ts->req);
/* restore the protocol pointer */
- data->req.p.http = ts->prot_save;
data->info.httpcode = 0; /* clear it as it might've been used for the
proxy */
/* If a proxy-authorization header was used for the proxy, then we should
@@ -355,7 +342,8 @@ static CURLcode start_CONNECT(struct Curl_easy *data,
goto out;
/* Send the connect request to the proxy */
- result = Curl_buffer_send(&ts->req, data, &data->info.request_size, 0,
+ result = Curl_buffer_send(&ts->req, data, &ts->CONNECT,
+ &data->info.request_size, 0,
ts->sockindex);
ts->headerlines = 0;
@@ -373,7 +361,7 @@ static CURLcode send_CONNECT(struct Curl_easy *data,
bool *done)
{
struct SingleRequest *k = &data->req;
- struct HTTP *http = data->req.p.http;
+ struct HTTP *http = &ts->CONNECT;
CURLcode result = CURLE_OK;
if(http->sending != HTTPSEND_REQUEST)
@@ -394,7 +382,7 @@ static CURLcode send_CONNECT(struct Curl_easy *data,
result = Curl_write(data,
conn->writesockfd, /* socket to send to */
k->upload_fromhere, /* buffer pointer */
- ts->nsend, /* buffer size */
+ ts->nsend, /* buffer size */
&bytes_written); /* actually sent */
if(result)
goto out;
@@ -1158,8 +1146,9 @@ static int http_proxy_cf_get_select_socks(struct Curl_cfilter *cf,
wait for the socket to become readable to be able to get the
response headers or if we're still sending the request, wait
for write. */
- if(ts->http_proxy.sending == HTTPSEND_REQUEST)
+ if(ts->CONNECT.sending == HTTPSEND_REQUEST) {
return GETSOCK_WRITESOCK(0);
+ }
return GETSOCK_READSOCK(0);
}
return GETSOCK_WRITESOCK(0);
diff --git a/lib/rtsp.c b/lib/rtsp.c
index 3069f3f99..9d27929e8 100644
--- a/lib/rtsp.c
+++ b/lib/rtsp.c
@@ -563,7 +563,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
}
/* issue the request */
- result = Curl_buffer_send(&req_buffer, data,
+ result = Curl_buffer_send(&req_buffer, data, data->req.p.http,
&data->info.request_size, 0, FIRSTSOCKET);
if(result) {
failf(data, "Failed sending RTSP request");