Browse Source

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
Daniel Stenberg 1 year ago
parent
commit
3f3ddee066
4 changed files with 29 additions and 33 deletions
  1. 18 14
      lib/http.c
  2. 3 0
      lib/http.h
  3. 7 18
      lib/http_proxy.c
  4. 1 1
      lib/rtsp.c

+ 18 - 14
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");

+ 3 - 0
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 {

+ 7 - 18
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);

+ 1 - 1
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");