http: move header storage to Curl_easy from connectdata

Since the connection can be used by many independent requests (using
HTTP/2 or HTTP/3), things like user-agent and other transfer-specific
data MUST NOT be kept connection oriented as it could lead to requests
getting the wrong string for their requests. This struct data was
lingering like this due to old HTTP1 legacy thinking where it didn't
mattered..

Fixes #5566
Closes #5567
diff --git a/lib/curl_ntlm_wb.c b/lib/curl_ntlm_wb.c
index 9c80049..17a92f8 100644
--- a/lib/curl_ntlm_wb.c
+++ b/lib/curl_ntlm_wb.c
@@ -376,8 +376,7 @@
  * This is for creating ntlm header output by delegating challenge/response
  * to Samba's winbind daemon helper ntlm_auth.
  */
-CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
-                              bool proxy)
+CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy)
 {
   /* point to the address of the pointer that holds the string to send to the
      server, which is for a plain host or for a HTTP proxy */
@@ -387,6 +386,7 @@
   struct ntlmdata *ntlm;
   curlntlm *state;
   struct auth *authp;
+  struct Curl_easy *data = conn->data;
 
   CURLcode res = CURLE_OK;
 
@@ -395,7 +395,7 @@
 
   if(proxy) {
 #ifndef CURL_DISABLE_PROXY
-    allocuserpwd = &conn->allocptr.proxyuserpwd;
+    allocuserpwd = &data->state.aptr.proxyuserpwd;
     userp = conn->http_proxy.user;
     ntlm = &conn->proxyntlm;
     state = &conn->proxy_ntlm_state;
@@ -405,7 +405,7 @@
 #endif
   }
   else {
-    allocuserpwd = &conn->allocptr.userpwd;
+    allocuserpwd = &data->state.aptr.userpwd;
     userp = conn->user;
     ntlm = &conn->ntlm;
     state = &conn->http_ntlm_state;
diff --git a/lib/http.c b/lib/http.c
index 9f9a1ba..482f9ad 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -293,7 +293,7 @@
 
   if(proxy) {
 #ifndef CURL_DISABLE_PROXY
-    userp = &conn->allocptr.proxyuserpwd;
+    userp = &data->state.aptr.proxyuserpwd;
     user = conn->http_proxy.user;
     pwd = conn->http_proxy.passwd;
 #else
@@ -301,7 +301,7 @@
 #endif
   }
   else {
-    userp = &conn->allocptr.userpwd;
+    userp = &data->state.aptr.userpwd;
     user = conn->user;
     pwd = conn->passwd;
   }
@@ -344,8 +344,9 @@
 {
   char **userp;
   CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
 
-  userp = &conn->allocptr.userpwd;
+  userp = &data->state.aptr.userpwd;
   free(*userp);
   *userp = aprintf("Authorization: Bearer %s\r\n",
                    conn->data->set.str[STRING_BEARER]);
@@ -1769,7 +1770,7 @@
           CURLcode result = CURLE_OK;
           char *compare = semicolonp ? semicolonp : headers->data;
 
-          if(conn->allocptr.host &&
+          if(data->state.aptr.host &&
              /* a Host: header was sent already, don't pass on any custom Host:
                 header as that will produce *two* in the same request! */
              checkprefix("Host:", compare))
@@ -1787,7 +1788,7 @@
                      we will force length zero then */
                   checkprefix("Content-Length:", compare))
             ;
-          else if(conn->allocptr.te &&
+          else if(data->state.aptr.te &&
                   /* when asking for Transfer-Encoding, don't pass on a custom
                      Connection: */
                   checkprefix("Connection:", compare))
@@ -2030,8 +2031,8 @@
      with the user-agent string specified, we erase the previously made string
      here. */
   if(Curl_checkheaders(conn, "User-Agent")) {
-    free(conn->allocptr.uagent);
-    conn->allocptr.uagent = NULL;
+    free(data->state.aptr.uagent);
+    data->state.aptr.uagent = NULL;
   }
 
   /* setup the authentication headers */
@@ -2059,14 +2060,14 @@
   else
     conn->bits.authneg = FALSE;
 
-  Curl_safefree(conn->allocptr.ref);
+  Curl_safefree(data->state.aptr.ref);
   if(data->change.referer && !Curl_checkheaders(conn, "Referer")) {
-    conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
-    if(!conn->allocptr.ref)
+    data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
+    if(!data->state.aptr.ref)
       return CURLE_OUT_OF_MEMORY;
   }
   else
-    conn->allocptr.ref = NULL;
+    data->state.aptr.ref = NULL;
 
 #if !defined(CURL_DISABLE_COOKIES)
   if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie"))
@@ -2075,15 +2076,15 @@
 
   if(!Curl_checkheaders(conn, "Accept-Encoding") &&
      data->set.str[STRING_ENCODING]) {
-    Curl_safefree(conn->allocptr.accept_encoding);
-    conn->allocptr.accept_encoding =
+    Curl_safefree(data->state.aptr.accept_encoding);
+    data->state.aptr.accept_encoding =
       aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
-    if(!conn->allocptr.accept_encoding)
+    if(!data->state.aptr.accept_encoding)
       return CURLE_OUT_OF_MEMORY;
   }
   else {
-    Curl_safefree(conn->allocptr.accept_encoding);
-    conn->allocptr.accept_encoding = NULL;
+    Curl_safefree(data->state.aptr.accept_encoding);
+    data->state.aptr.accept_encoding = NULL;
   }
 
 #ifdef HAVE_LIBZ
@@ -2099,7 +2100,7 @@
     char *cptr = Curl_checkheaders(conn, "Connection");
 #define TE_HEADER "TE: gzip\r\n"
 
-    Curl_safefree(conn->allocptr.te);
+    Curl_safefree(data->state.aptr.te);
 
     if(cptr) {
       cptr = Curl_copy_header_value(cptr);
@@ -2108,11 +2109,11 @@
     }
 
     /* Create the (updated) Connection: header */
-    conn->allocptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER,
+    data->state.aptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER,
                                 cptr ? cptr : "", (cptr && *cptr) ? ", ":"");
 
     free(cptr);
-    if(!conn->allocptr.te)
+    if(!data->state.aptr.te)
       return CURLE_OUT_OF_MEMORY;
   }
 #endif
@@ -2195,7 +2196,7 @@
       te = "Transfer-Encoding: chunked\r\n";
   }
 
-  Curl_safefree(conn->allocptr.host);
+  Curl_safefree(data->state.aptr.host);
 
   ptr = Curl_checkheaders(conn, "Host");
   if(ptr && (!data->state.this_is_a_follow ||
@@ -2230,19 +2231,19 @@
         if(colon)
           *colon = 0; /* The host must not include an embedded port number */
       }
-      Curl_safefree(conn->allocptr.cookiehost);
-      conn->allocptr.cookiehost = cookiehost;
+      Curl_safefree(data->state.aptr.cookiehost);
+      data->state.aptr.cookiehost = cookiehost;
     }
 #endif
 
     if(strcmp("Host:", ptr)) {
-      conn->allocptr.host = aprintf("Host:%s\r\n", &ptr[5]);
-      if(!conn->allocptr.host)
+      data->state.aptr.host = aprintf("Host:%s\r\n", &ptr[5]);
+      if(!data->state.aptr.host)
         return CURLE_OUT_OF_MEMORY;
     }
     else
       /* when clearing the header */
-      conn->allocptr.host = NULL;
+      data->state.aptr.host = NULL;
   }
   else {
     /* When building Host: headers, we must put the host name within
@@ -2254,18 +2255,18 @@
         (conn->remote_port == PORT_HTTP)) )
       /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
          the port number in the host string */
-      conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
+      data->state.aptr.host = aprintf("Host: %s%s%s\r\n",
                                     conn->bits.ipv6_ip?"[":"",
                                     host,
                                     conn->bits.ipv6_ip?"]":"");
     else
-      conn->allocptr.host = aprintf("Host: %s%s%s:%d\r\n",
+      data->state.aptr.host = aprintf("Host: %s%s%s:%d\r\n",
                                     conn->bits.ipv6_ip?"[":"",
                                     host,
                                     conn->bits.ipv6_ip?"]":"",
                                     conn->remote_port);
 
-    if(!conn->allocptr.host)
+    if(!data->state.aptr.host)
       /* without Host: we can't make a nice request */
       return CURLE_OUT_OF_MEMORY;
   }
@@ -2436,21 +2437,21 @@
     if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
        !Curl_checkheaders(conn, "Range")) {
       /* if a line like this was already allocated, free the previous one */
-      free(conn->allocptr.rangeline);
-      conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
+      free(data->state.aptr.rangeline);
+      data->state.aptr.rangeline = aprintf("Range: bytes=%s\r\n",
                                          data->state.range);
     }
     else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) &&
             !Curl_checkheaders(conn, "Content-Range")) {
 
       /* if a line like this was already allocated, free the previous one */
-      free(conn->allocptr.rangeline);
+      free(data->state.aptr.rangeline);
 
       if(data->set.set_resume_from < 0) {
         /* Upload resume was asked for, but we don't know the size of the
            remote part so we tell the server (and act accordingly) that we
            upload the whole file (again) */
-        conn->allocptr.rangeline =
+        data->state.aptr.rangeline =
           aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
                   "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
                   data->state.infilesize - 1, data->state.infilesize);
@@ -2460,7 +2461,7 @@
         /* This is because "resume" was selected */
         curl_off_t total_expected_size =
           data->state.resume_from + data->state.infilesize;
-        conn->allocptr.rangeline =
+        data->state.aptr.rangeline =
           aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
                   "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
                   data->state.range, total_expected_size-1,
@@ -2469,11 +2470,11 @@
       else {
         /* Range was selected and then we just pass the incoming range and
            append total size */
-        conn->allocptr.rangeline =
+        data->state.aptr.rangeline =
           aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
                   data->state.range, data->state.infilesize);
       }
-      if(!conn->allocptr.rangeline)
+      if(!data->state.aptr.rangeline)
         return CURLE_OUT_OF_MEMORY;
     }
   }
@@ -2545,24 +2546,24 @@
 
                   ftp_typecode,
                   httpstring,
-                  (conn->allocptr.host?conn->allocptr.host:""),
-                  conn->allocptr.proxyuserpwd?
-                  conn->allocptr.proxyuserpwd:"",
-                  conn->allocptr.userpwd?conn->allocptr.userpwd:"",
-                  (data->state.use_range && conn->allocptr.rangeline)?
-                  conn->allocptr.rangeline:"",
+                  (data->state.aptr.host?data->state.aptr.host:""),
+                  data->state.aptr.proxyuserpwd?
+                  data->state.aptr.proxyuserpwd:"",
+                  data->state.aptr.userpwd?data->state.aptr.userpwd:"",
+                  (data->state.use_range && data->state.aptr.rangeline)?
+                  data->state.aptr.rangeline:"",
                   (data->set.str[STRING_USERAGENT] &&
                    *data->set.str[STRING_USERAGENT] &&
-                   conn->allocptr.uagent)?
-                  conn->allocptr.uagent:"",
+                   data->state.aptr.uagent)?
+                  data->state.aptr.uagent:"",
                   http->p_accept?http->p_accept:"",
-                  conn->allocptr.te?conn->allocptr.te:"",
+                  data->state.aptr.te?data->state.aptr.te:"",
                   (data->set.str[STRING_ENCODING] &&
                    *data->set.str[STRING_ENCODING] &&
-                   conn->allocptr.accept_encoding)?
-                  conn->allocptr.accept_encoding:"",
-                  (data->change.referer && conn->allocptr.ref)?
-                  conn->allocptr.ref:"" /* Referer: <data> */,
+                   data->state.aptr.accept_encoding)?
+                  data->state.aptr.accept_encoding:"",
+                  (data->change.referer && data->state.aptr.ref)?
+                  data->state.aptr.ref:"" /* Referer: <data> */,
 #ifndef CURL_DISABLE_PROXY
                   (conn->bits.httpproxy &&
                    !conn->bits.tunnel_proxy &&
@@ -2577,8 +2578,8 @@
 
   /* clear userpwd and proxyuserpwd to avoid re-using old credentials
    * from re-used connections */
-  Curl_safefree(conn->allocptr.userpwd);
-  Curl_safefree(conn->allocptr.proxyuserpwd);
+  Curl_safefree(data->state.aptr.userpwd);
+  Curl_safefree(data->state.aptr.proxyuserpwd);
   free(altused);
 
   if(result)
@@ -2602,8 +2603,8 @@
     if(data->cookies && data->state.cookie_engine) {
       Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
       co = Curl_cookie_getlist(data->cookies,
-                               conn->allocptr.cookiehost?
-                               conn->allocptr.cookiehost:host,
+                               data->state.aptr.cookiehost?
+                               data->state.aptr.cookiehost:host,
                                data->state.up.path,
                                (conn->handler->protocol&CURLPROTO_HTTPS)?
                                TRUE:FALSE);
@@ -3915,8 +3916,8 @@
                       data->cookies, TRUE, FALSE, headp + 11,
                       /* If there is a custom-set Host: name, use it
                          here, or else use real peer host name. */
-                      conn->allocptr.cookiehost?
-                      conn->allocptr.cookiehost:conn->host.name,
+                      data->state.aptr.cookiehost?
+                      data->state.aptr.cookiehost:conn->host.name,
                       data->state.up.path,
                       (conn->handler->protocol&CURLPROTO_HTTPS)?
                       TRUE:FALSE);
diff --git a/lib/http_digest.c b/lib/http_digest.c
index 52e6830..b06dc0d 100644
--- a/lib/http_digest.c
+++ b/lib/http_digest.c
@@ -98,7 +98,7 @@
     return CURLE_NOT_BUILT_IN;
 #else
     digest = &data->state.proxydigest;
-    allocuserpwd = &conn->allocptr.proxyuserpwd;
+    allocuserpwd = &data->state.aptr.proxyuserpwd;
     userp = conn->http_proxy.user;
     passwdp = conn->http_proxy.passwd;
     authp = &data->state.authproxy;
@@ -106,7 +106,7 @@
   }
   else {
     digest = &data->state.digest;
-    allocuserpwd = &conn->allocptr.userpwd;
+    allocuserpwd = &data->state.aptr.userpwd;
     userp = conn->user;
     passwdp = conn->passwd;
     authp = &data->state.authhost;
diff --git a/lib/http_digest.h b/lib/http_digest.h
index 73410ae..96e39a7 100644
--- a/lib/http_digest.h
+++ b/lib/http_digest.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index 915be06..0a19ec2 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -123,7 +123,8 @@
   struct auth *authp = proxy ? &conn->data->state.authproxy :
     &conn->data->state.authhost;
   curlnegotiate *state = proxy ? &conn->proxy_negotiate_state :
-                                 &conn->http_negotiate_state;
+    &conn->http_negotiate_state;
+  struct Curl_easy *data = conn->data;
   char *base64 = NULL;
   size_t len = 0;
   char *userp;
@@ -168,15 +169,15 @@
       return result;
 
     userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
-      base64);
+                    base64);
 
     if(proxy) {
-      Curl_safefree(conn->allocptr.proxyuserpwd);
-      conn->allocptr.proxyuserpwd = userp;
+      Curl_safefree(data->state.aptr.proxyuserpwd);
+      data->state.aptr.proxyuserpwd = userp;
     }
     else {
-      Curl_safefree(conn->allocptr.userpwd);
-      conn->allocptr.userpwd = userp;
+      Curl_safefree(data->state.aptr.userpwd);
+      data->state.aptr.userpwd = userp;
     }
 
     free(base64);
diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c
index f3b8a20..cab543c 100644
--- a/lib/http_ntlm.c
+++ b/lib/http_ntlm.c
@@ -131,13 +131,15 @@
   struct ntlmdata *ntlm;
   curlntlm *state;
   struct auth *authp;
+  struct Curl_easy *data = conn->data;
+
 
   DEBUGASSERT(conn);
-  DEBUGASSERT(conn->data);
+  DEBUGASSERT(data);
 
   if(proxy) {
 #ifndef CURL_DISABLE_PROXY
-    allocuserpwd = &conn->allocptr.proxyuserpwd;
+    allocuserpwd = &data->state.aptr.proxyuserpwd;
     userp = conn->http_proxy.user;
     passwdp = conn->http_proxy.passwd;
     service = conn->data->set.str[STRING_PROXY_SERVICE_NAME] ?
@@ -151,7 +153,7 @@
 #endif
   }
   else {
-    allocuserpwd = &conn->allocptr.userpwd;
+    allocuserpwd = &data->state.aptr.userpwd;
     userp = conn->user;
     passwdp = conn->passwd;
     service = conn->data->set.str[STRING_SERVICE_NAME] ?
diff --git a/lib/http_proxy.c b/lib/http_proxy.c
index ad968e6..f188cbf 100644
--- a/lib/http_proxy.c
+++ b/lib/http_proxy.c
@@ -72,6 +72,7 @@
 
 CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
 {
+  struct Curl_easy *data = conn->data;
   if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
     const CURLcode result = https_proxy_connect(conn, sockindex);
     if(result)
@@ -127,7 +128,7 @@
     conn->data->req.protop = prot_save;
     if(CURLE_OK != result)
       return result;
-    Curl_safefree(conn->allocptr.proxyuserpwd);
+    Curl_safefree(data->state.aptr.proxyuserpwd);
 #else
     return CURLE_NOT_BUILT_IN;
 #endif
@@ -234,8 +235,8 @@
         char *host = NULL;
         const char *proxyconn = "";
         const char *useragent = "";
-        const char *http = (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ?
-          "1.0" : "1.1";
+        const char *httpv =
+          (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ? "1.0" : "1.1";
         bool ipv6_ip = conn->bits.ipv6_ip;
         char *hostheader;
 
@@ -263,7 +264,7 @@
 
         if(!Curl_checkProxyheaders(conn, "User-Agent") &&
            data->set.str[STRING_USERAGENT])
-          useragent = conn->allocptr.uagent;
+          useragent = data->state.aptr.uagent;
 
         result =
           Curl_dyn_addf(&req,
@@ -273,10 +274,10 @@
                         "%s"  /* User-Agent */
                         "%s", /* Proxy-Connection */
                         hostheader,
-                        http,
+                        httpv,
                         host?host:"",
-                        conn->allocptr.proxyuserpwd?
-                        conn->allocptr.proxyuserpwd:"",
+                        data->state.aptr.proxyuserpwd?
+                        data->state.aptr.proxyuserpwd:"",
                         useragent,
                         proxyconn);
 
@@ -615,8 +616,8 @@
   /* If a proxy-authorization header was used for the proxy, then we should
      make sure that it isn't accidentally used for the document request
      after we've connected. So let's free and clear it here. */
-  Curl_safefree(conn->allocptr.proxyuserpwd);
-  conn->allocptr.proxyuserpwd = NULL;
+  Curl_safefree(data->state.aptr.proxyuserpwd);
+  data->state.aptr.proxyuserpwd = NULL;
 
   data->state.authproxy.done = TRUE;
   data->state.authproxy.multipass = FALSE;
diff --git a/lib/rtsp.c b/lib/rtsp.c
index 2a9c683..dbd7dc6 100644
--- a/lib/rtsp.c
+++ b/lib/rtsp.c
@@ -333,12 +333,12 @@
   if(rtspreq == RTSPREQ_SETUP && !p_transport) {
     /* New Transport: setting? */
     if(data->set.str[STRING_RTSP_TRANSPORT]) {
-      Curl_safefree(conn->allocptr.rtsp_transport);
+      Curl_safefree(data->state.aptr.rtsp_transport);
 
-      conn->allocptr.rtsp_transport =
+      data->state.aptr.rtsp_transport =
         aprintf("Transport: %s\r\n",
                 data->set.str[STRING_RTSP_TRANSPORT]);
-      if(!conn->allocptr.rtsp_transport)
+      if(!data->state.aptr.rtsp_transport)
         return CURLE_OUT_OF_MEMORY;
     }
     else {
@@ -347,7 +347,7 @@
       return CURLE_BAD_FUNCTION_ARGUMENT;
     }
 
-    p_transport = conn->allocptr.rtsp_transport;
+    p_transport = data->state.aptr.rtsp_transport;
   }
 
   /* Accept Headers for DESCRIBE requests */
@@ -359,14 +359,14 @@
     /* Accept-Encoding header */
     if(!Curl_checkheaders(conn, "Accept-Encoding") &&
        data->set.str[STRING_ENCODING]) {
-      Curl_safefree(conn->allocptr.accept_encoding);
-      conn->allocptr.accept_encoding =
+      Curl_safefree(data->state.aptr.accept_encoding);
+      data->state.aptr.accept_encoding =
         aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
 
-      if(!conn->allocptr.accept_encoding)
+      if(!data->state.aptr.accept_encoding)
         return CURLE_OUT_OF_MEMORY;
 
-      p_accept_encoding = conn->allocptr.accept_encoding;
+      p_accept_encoding = data->state.aptr.accept_encoding;
     }
   }
 
@@ -374,13 +374,13 @@
      it might have been used in the proxy connect, but if we have got a header
      with the user-agent string specified, we erase the previously made string
      here. */
-  if(Curl_checkheaders(conn, "User-Agent") && conn->allocptr.uagent) {
-    Curl_safefree(conn->allocptr.uagent);
-    conn->allocptr.uagent = NULL;
+  if(Curl_checkheaders(conn, "User-Agent") && data->state.aptr.uagent) {
+    Curl_safefree(data->state.aptr.uagent);
+    data->state.aptr.uagent = NULL;
   }
   else if(!Curl_checkheaders(conn, "User-Agent") &&
           data->set.str[STRING_USERAGENT]) {
-    p_uagent = conn->allocptr.uagent;
+    p_uagent = data->state.aptr.uagent;
   }
 
   /* setup the authentication headers */
@@ -388,17 +388,17 @@
   if(result)
     return result;
 
-  p_proxyuserpwd = conn->allocptr.proxyuserpwd;
-  p_userpwd = conn->allocptr.userpwd;
+  p_proxyuserpwd = data->state.aptr.proxyuserpwd;
+  p_userpwd = data->state.aptr.userpwd;
 
   /* Referrer */
-  Curl_safefree(conn->allocptr.ref);
+  Curl_safefree(data->state.aptr.ref);
   if(data->change.referer && !Curl_checkheaders(conn, "Referer"))
-    conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
+    data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
   else
-    conn->allocptr.ref = NULL;
+    data->state.aptr.ref = NULL;
 
-  p_referrer = conn->allocptr.ref;
+  p_referrer = data->state.aptr.ref;
 
   /*
    * Range Header
@@ -411,9 +411,9 @@
 
     /* Check to see if there is a range set in the custom headers */
     if(!Curl_checkheaders(conn, "Range") && data->state.range) {
-      Curl_safefree(conn->allocptr.rangeline);
-      conn->allocptr.rangeline = aprintf("Range: %s\r\n", data->state.range);
-      p_range = conn->allocptr.rangeline;
+      Curl_safefree(data->state.aptr.rangeline);
+      data->state.aptr.rangeline = aprintf("Range: %s\r\n", data->state.range);
+      p_range = data->state.aptr.rangeline;
     }
   }
 
@@ -476,8 +476,8 @@
    * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
    * with basic and digest, it will be freed anyway by the next request
    */
-  Curl_safefree(conn->allocptr.userpwd);
-  conn->allocptr.userpwd = NULL;
+  Curl_safefree(data->state.aptr.userpwd);
+  data->state.aptr.userpwd = NULL;
 
   if(result)
     return result;
diff --git a/lib/url.c b/lib/url.c
index 27943a3..4021c5d 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -416,6 +416,17 @@
     Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
   }
 
+  Curl_safefree(data->state.aptr.proxyuserpwd);
+  Curl_safefree(data->state.aptr.uagent);
+  Curl_safefree(data->state.aptr.userpwd);
+  Curl_safefree(data->state.aptr.accept_encoding);
+  Curl_safefree(data->state.aptr.te);
+  Curl_safefree(data->state.aptr.rangeline);
+  Curl_safefree(data->state.aptr.ref);
+  Curl_safefree(data->state.aptr.host);
+  Curl_safefree(data->state.aptr.cookiehost);
+  Curl_safefree(data->state.aptr.rtsp_transport);
+
 #ifndef CURL_DISABLE_DOH
   Curl_dyn_free(&data->req.doh.probe[0].serverdoh);
   Curl_dyn_free(&data->req.doh.probe[1].serverdoh);
@@ -723,16 +734,6 @@
   Curl_safefree(conn->passwd);
   Curl_safefree(conn->sasl_authzid);
   Curl_safefree(conn->options);
-  Curl_safefree(conn->allocptr.proxyuserpwd);
-  Curl_safefree(conn->allocptr.uagent);
-  Curl_safefree(conn->allocptr.userpwd);
-  Curl_safefree(conn->allocptr.accept_encoding);
-  Curl_safefree(conn->allocptr.te);
-  Curl_safefree(conn->allocptr.rangeline);
-  Curl_safefree(conn->allocptr.ref);
-  Curl_safefree(conn->allocptr.host);
-  Curl_safefree(conn->allocptr.cookiehost);
-  Curl_safefree(conn->allocptr.rtsp_transport);
   Curl_dyn_free(&conn->trailer);
   Curl_safefree(conn->host.rawalloc); /* host name buffer */
   Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
@@ -3884,10 +3885,10 @@
    * protocol.
    */
   if(data->set.str[STRING_USERAGENT]) {
-    Curl_safefree(conn->allocptr.uagent);
-    conn->allocptr.uagent =
+    Curl_safefree(data->state.aptr.uagent);
+    data->state.aptr.uagent =
       aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
-    if(!conn->allocptr.uagent)
+    if(!data->state.aptr.uagent)
       return CURLE_OUT_OF_MEMORY;
   }
 
diff --git a/lib/urldata.h b/lib/urldata.h
index 1882914..33ec160 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1003,21 +1003,6 @@
                                 well be the same we read from.
                                 CURL_SOCKET_BAD disables */
 
-  /** Dynamically allocated strings, MUST be freed before this **/
-  /** struct is killed.                                      **/
-  struct dynamically_allocated_data {
-    char *proxyuserpwd;
-    char *uagent;
-    char *accept_encoding;
-    char *userpwd;
-    char *rangeline;
-    char *ref;
-    char *host;
-    char *cookiehost;
-    char *rtsp_transport;
-    char *te; /* TE: request header */
-  } allocptr;
-
 #ifdef HAVE_GSSAPI
   BIT(sec_complete); /* if Kerberos is enabled for this connection */
   enum protection_level command_prot;
@@ -1396,6 +1381,22 @@
 #endif
   trailers_state trailers_state; /* whether we are sending trailers
                                        and what stage are we at */
+
+  /* Dynamically allocated strings, MUST be freed before this struct is
+     killed. */
+  struct dynamically_allocated_data {
+    char *proxyuserpwd;
+    char *uagent;
+    char *accept_encoding;
+    char *userpwd;
+    char *rangeline;
+    char *ref;
+    char *host;
+    char *cookiehost;
+    char *rtsp_transport;
+    char *te; /* TE: request header */
+  } aptr;
+
 #ifdef CURLDEBUG
   BIT(conncache_lock);
 #endif