Skip to content

Commit e15e513

Browse files
committed
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
1 parent 350a99b commit e15e513

10 files changed

Lines changed: 137 additions & 130 deletions

File tree

lib/curl_ntlm_wb.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,8 +376,7 @@ CURLcode Curl_input_ntlm_wb(struct connectdata *conn,
376376
* This is for creating ntlm header output by delegating challenge/response
377377
* to Samba's winbind daemon helper ntlm_auth.
378378
*/
379-
CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
380-
bool proxy)
379+
CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy)
381380
{
382381
/* point to the address of the pointer that holds the string to send to the
383382
server, which is for a plain host or for a HTTP proxy */
@@ -387,6 +386,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
387386
struct ntlmdata *ntlm;
388387
curlntlm *state;
389388
struct auth *authp;
389+
struct Curl_easy *data = conn->data;
390390

391391
CURLcode res = CURLE_OK;
392392

@@ -395,7 +395,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
395395

396396
if(proxy) {
397397
#ifndef CURL_DISABLE_PROXY
398-
allocuserpwd = &conn->allocptr.proxyuserpwd;
398+
allocuserpwd = &data->state.aptr.proxyuserpwd;
399399
userp = conn->http_proxy.user;
400400
ntlm = &conn->proxyntlm;
401401
state = &conn->proxy_ntlm_state;
@@ -405,7 +405,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
405405
#endif
406406
}
407407
else {
408-
allocuserpwd = &conn->allocptr.userpwd;
408+
allocuserpwd = &data->state.aptr.userpwd;
409409
userp = conn->user;
410410
ntlm = &conn->ntlm;
411411
state = &conn->http_ntlm_state;

lib/http.c

Lines changed: 55 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -293,15 +293,15 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
293293

294294
if(proxy) {
295295
#ifndef CURL_DISABLE_PROXY
296-
userp = &conn->allocptr.proxyuserpwd;
296+
userp = &data->state.aptr.proxyuserpwd;
297297
user = conn->http_proxy.user;
298298
pwd = conn->http_proxy.passwd;
299299
#else
300300
return CURLE_NOT_BUILT_IN;
301301
#endif
302302
}
303303
else {
304-
userp = &conn->allocptr.userpwd;
304+
userp = &data->state.aptr.userpwd;
305305
user = conn->user;
306306
pwd = conn->passwd;
307307
}
@@ -344,8 +344,9 @@ static CURLcode http_output_bearer(struct connectdata *conn)
344344
{
345345
char **userp;
346346
CURLcode result = CURLE_OK;
347+
struct Curl_easy *data = conn->data;
347348

348-
userp = &conn->allocptr.userpwd;
349+
userp = &data->state.aptr.userpwd;
349350
free(*userp);
350351
*userp = aprintf("Authorization: Bearer %s\r\n",
351352
conn->data->set.str[STRING_BEARER]);
@@ -1769,7 +1770,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
17691770
CURLcode result = CURLE_OK;
17701771
char *compare = semicolonp ? semicolonp : headers->data;
17711772

1772-
if(conn->allocptr.host &&
1773+
if(data->state.aptr.host &&
17731774
/* a Host: header was sent already, don't pass on any custom Host:
17741775
header as that will produce *two* in the same request! */
17751776
checkprefix("Host:", compare))
@@ -1787,7 +1788,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
17871788
we will force length zero then */
17881789
checkprefix("Content-Length:", compare))
17891790
;
1790-
else if(conn->allocptr.te &&
1791+
else if(data->state.aptr.te &&
17911792
/* when asking for Transfer-Encoding, don't pass on a custom
17921793
Connection: */
17931794
checkprefix("Connection:", compare))
@@ -2030,8 +2031,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
20302031
with the user-agent string specified, we erase the previously made string
20312032
here. */
20322033
if(Curl_checkheaders(conn, "User-Agent")) {
2033-
free(conn->allocptr.uagent);
2034-
conn->allocptr.uagent = NULL;
2034+
free(data->state.aptr.uagent);
2035+
data->state.aptr.uagent = NULL;
20352036
}
20362037

20372038
/* setup the authentication headers */
@@ -2059,14 +2060,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
20592060
else
20602061
conn->bits.authneg = FALSE;
20612062

2062-
Curl_safefree(conn->allocptr.ref);
2063+
Curl_safefree(data->state.aptr.ref);
20632064
if(data->change.referer && !Curl_checkheaders(conn, "Referer")) {
2064-
conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
2065-
if(!conn->allocptr.ref)
2065+
data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
2066+
if(!data->state.aptr.ref)
20662067
return CURLE_OUT_OF_MEMORY;
20672068
}
20682069
else
2069-
conn->allocptr.ref = NULL;
2070+
data->state.aptr.ref = NULL;
20702071

20712072
#if !defined(CURL_DISABLE_COOKIES)
20722073
if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie"))
@@ -2075,15 +2076,15 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
20752076

20762077
if(!Curl_checkheaders(conn, "Accept-Encoding") &&
20772078
data->set.str[STRING_ENCODING]) {
2078-
Curl_safefree(conn->allocptr.accept_encoding);
2079-
conn->allocptr.accept_encoding =
2079+
Curl_safefree(data->state.aptr.accept_encoding);
2080+
data->state.aptr.accept_encoding =
20802081
aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
2081-
if(!conn->allocptr.accept_encoding)
2082+
if(!data->state.aptr.accept_encoding)
20822083
return CURLE_OUT_OF_MEMORY;
20832084
}
20842085
else {
2085-
Curl_safefree(conn->allocptr.accept_encoding);
2086-
conn->allocptr.accept_encoding = NULL;
2086+
Curl_safefree(data->state.aptr.accept_encoding);
2087+
data->state.aptr.accept_encoding = NULL;
20872088
}
20882089

20892090
#ifdef HAVE_LIBZ
@@ -2099,7 +2100,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
20992100
char *cptr = Curl_checkheaders(conn, "Connection");
21002101
#define TE_HEADER "TE: gzip\r\n"
21012102

2102-
Curl_safefree(conn->allocptr.te);
2103+
Curl_safefree(data->state.aptr.te);
21032104

21042105
if(cptr) {
21052106
cptr = Curl_copy_header_value(cptr);
@@ -2108,11 +2109,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
21082109
}
21092110

21102111
/* Create the (updated) Connection: header */
2111-
conn->allocptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER,
2112+
data->state.aptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER,
21122113
cptr ? cptr : "", (cptr && *cptr) ? ", ":"");
21132114

21142115
free(cptr);
2115-
if(!conn->allocptr.te)
2116+
if(!data->state.aptr.te)
21162117
return CURLE_OUT_OF_MEMORY;
21172118
}
21182119
#endif
@@ -2195,7 +2196,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
21952196
te = "Transfer-Encoding: chunked\r\n";
21962197
}
21972198

2198-
Curl_safefree(conn->allocptr.host);
2199+
Curl_safefree(data->state.aptr.host);
21992200

22002201
ptr = Curl_checkheaders(conn, "Host");
22012202
if(ptr && (!data->state.this_is_a_follow ||
@@ -2230,19 +2231,19 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
22302231
if(colon)
22312232
*colon = 0; /* The host must not include an embedded port number */
22322233
}
2233-
Curl_safefree(conn->allocptr.cookiehost);
2234-
conn->allocptr.cookiehost = cookiehost;
2234+
Curl_safefree(data->state.aptr.cookiehost);
2235+
data->state.aptr.cookiehost = cookiehost;
22352236
}
22362237
#endif
22372238

22382239
if(strcmp("Host:", ptr)) {
2239-
conn->allocptr.host = aprintf("Host:%s\r\n", &ptr[5]);
2240-
if(!conn->allocptr.host)
2240+
data->state.aptr.host = aprintf("Host:%s\r\n", &ptr[5]);
2241+
if(!data->state.aptr.host)
22412242
return CURLE_OUT_OF_MEMORY;
22422243
}
22432244
else
22442245
/* when clearing the header */
2245-
conn->allocptr.host = NULL;
2246+
data->state.aptr.host = NULL;
22462247
}
22472248
else {
22482249
/* When building Host: headers, we must put the host name within
@@ -2254,18 +2255,18 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
22542255
(conn->remote_port == PORT_HTTP)) )
22552256
/* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
22562257
the port number in the host string */
2257-
conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
2258+
data->state.aptr.host = aprintf("Host: %s%s%s\r\n",
22582259
conn->bits.ipv6_ip?"[":"",
22592260
host,
22602261
conn->bits.ipv6_ip?"]":"");
22612262
else
2262-
conn->allocptr.host = aprintf("Host: %s%s%s:%d\r\n",
2263+
data->state.aptr.host = aprintf("Host: %s%s%s:%d\r\n",
22632264
conn->bits.ipv6_ip?"[":"",
22642265
host,
22652266
conn->bits.ipv6_ip?"]":"",
22662267
conn->remote_port);
22672268

2268-
if(!conn->allocptr.host)
2269+
if(!data->state.aptr.host)
22692270
/* without Host: we can't make a nice request */
22702271
return CURLE_OUT_OF_MEMORY;
22712272
}
@@ -2436,21 +2437,21 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
24362437
if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
24372438
!Curl_checkheaders(conn, "Range")) {
24382439
/* if a line like this was already allocated, free the previous one */
2439-
free(conn->allocptr.rangeline);
2440-
conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
2440+
free(data->state.aptr.rangeline);
2441+
data->state.aptr.rangeline = aprintf("Range: bytes=%s\r\n",
24412442
data->state.range);
24422443
}
24432444
else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) &&
24442445
!Curl_checkheaders(conn, "Content-Range")) {
24452446

24462447
/* if a line like this was already allocated, free the previous one */
2447-
free(conn->allocptr.rangeline);
2448+
free(data->state.aptr.rangeline);
24482449

24492450
if(data->set.set_resume_from < 0) {
24502451
/* Upload resume was asked for, but we don't know the size of the
24512452
remote part so we tell the server (and act accordingly) that we
24522453
upload the whole file (again) */
2453-
conn->allocptr.rangeline =
2454+
data->state.aptr.rangeline =
24542455
aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
24552456
"/%" CURL_FORMAT_CURL_OFF_T "\r\n",
24562457
data->state.infilesize - 1, data->state.infilesize);
@@ -2460,7 +2461,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
24602461
/* This is because "resume" was selected */
24612462
curl_off_t total_expected_size =
24622463
data->state.resume_from + data->state.infilesize;
2463-
conn->allocptr.rangeline =
2464+
data->state.aptr.rangeline =
24642465
aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
24652466
"/%" CURL_FORMAT_CURL_OFF_T "\r\n",
24662467
data->state.range, total_expected_size-1,
@@ -2469,11 +2470,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
24692470
else {
24702471
/* Range was selected and then we just pass the incoming range and
24712472
append total size */
2472-
conn->allocptr.rangeline =
2473+
data->state.aptr.rangeline =
24732474
aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
24742475
data->state.range, data->state.infilesize);
24752476
}
2476-
if(!conn->allocptr.rangeline)
2477+
if(!data->state.aptr.rangeline)
24772478
return CURLE_OUT_OF_MEMORY;
24782479
}
24792480
}
@@ -2545,24 +2546,24 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
25452546

25462547
ftp_typecode,
25472548
httpstring,
2548-
(conn->allocptr.host?conn->allocptr.host:""),
2549-
conn->allocptr.proxyuserpwd?
2550-
conn->allocptr.proxyuserpwd:"",
2551-
conn->allocptr.userpwd?conn->allocptr.userpwd:"",
2552-
(data->state.use_range && conn->allocptr.rangeline)?
2553-
conn->allocptr.rangeline:"",
2549+
(data->state.aptr.host?data->state.aptr.host:""),
2550+
data->state.aptr.proxyuserpwd?
2551+
data->state.aptr.proxyuserpwd:"",
2552+
data->state.aptr.userpwd?data->state.aptr.userpwd:"",
2553+
(data->state.use_range && data->state.aptr.rangeline)?
2554+
data->state.aptr.rangeline:"",
25542555
(data->set.str[STRING_USERAGENT] &&
25552556
*data->set.str[STRING_USERAGENT] &&
2556-
conn->allocptr.uagent)?
2557-
conn->allocptr.uagent:"",
2557+
data->state.aptr.uagent)?
2558+
data->state.aptr.uagent:"",
25582559
http->p_accept?http->p_accept:"",
2559-
conn->allocptr.te?conn->allocptr.te:"",
2560+
data->state.aptr.te?data->state.aptr.te:"",
25602561
(data->set.str[STRING_ENCODING] &&
25612562
*data->set.str[STRING_ENCODING] &&
2562-
conn->allocptr.accept_encoding)?
2563-
conn->allocptr.accept_encoding:"",
2564-
(data->change.referer && conn->allocptr.ref)?
2565-
conn->allocptr.ref:"" /* Referer: <data> */,
2563+
data->state.aptr.accept_encoding)?
2564+
data->state.aptr.accept_encoding:"",
2565+
(data->change.referer && data->state.aptr.ref)?
2566+
data->state.aptr.ref:"" /* Referer: <data> */,
25662567
#ifndef CURL_DISABLE_PROXY
25672568
(conn->bits.httpproxy &&
25682569
!conn->bits.tunnel_proxy &&
@@ -2577,8 +2578,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
25772578

25782579
/* clear userpwd and proxyuserpwd to avoid re-using old credentials
25792580
* from re-used connections */
2580-
Curl_safefree(conn->allocptr.userpwd);
2581-
Curl_safefree(conn->allocptr.proxyuserpwd);
2581+
Curl_safefree(data->state.aptr.userpwd);
2582+
Curl_safefree(data->state.aptr.proxyuserpwd);
25822583
free(altused);
25832584

25842585
if(result)
@@ -2602,8 +2603,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
26022603
if(data->cookies && data->state.cookie_engine) {
26032604
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
26042605
co = Curl_cookie_getlist(data->cookies,
2605-
conn->allocptr.cookiehost?
2606-
conn->allocptr.cookiehost:host,
2606+
data->state.aptr.cookiehost?
2607+
data->state.aptr.cookiehost:host,
26072608
data->state.up.path,
26082609
(conn->handler->protocol&CURLPROTO_HTTPS)?
26092610
TRUE:FALSE);
@@ -3915,8 +3916,8 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
39153916
data->cookies, TRUE, FALSE, headp + 11,
39163917
/* If there is a custom-set Host: name, use it
39173918
here, or else use real peer host name. */
3918-
conn->allocptr.cookiehost?
3919-
conn->allocptr.cookiehost:conn->host.name,
3919+
data->state.aptr.cookiehost?
3920+
data->state.aptr.cookiehost:conn->host.name,
39203921
data->state.up.path,
39213922
(conn->handler->protocol&CURLPROTO_HTTPS)?
39223923
TRUE:FALSE);

lib/http_digest.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,15 @@ CURLcode Curl_output_digest(struct connectdata *conn,
9898
return CURLE_NOT_BUILT_IN;
9999
#else
100100
digest = &data->state.proxydigest;
101-
allocuserpwd = &conn->allocptr.proxyuserpwd;
101+
allocuserpwd = &data->state.aptr.proxyuserpwd;
102102
userp = conn->http_proxy.user;
103103
passwdp = conn->http_proxy.passwd;
104104
authp = &data->state.authproxy;
105105
#endif
106106
}
107107
else {
108108
digest = &data->state.digest;
109-
allocuserpwd = &conn->allocptr.userpwd;
109+
allocuserpwd = &data->state.aptr.userpwd;
110110
userp = conn->user;
111111
passwdp = conn->passwd;
112112
authp = &data->state.authhost;

lib/http_digest.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* | (__| |_| | _ <| |___
88
* \___|\___/|_| \_\_____|
99
*
10-
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
10+
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
1111
*
1212
* This software is licensed as described in the file COPYING, which
1313
* you should have received as part of this distribution. The terms

lib/http_negotiate.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
123123
struct auth *authp = proxy ? &conn->data->state.authproxy :
124124
&conn->data->state.authhost;
125125
curlnegotiate *state = proxy ? &conn->proxy_negotiate_state :
126-
&conn->http_negotiate_state;
126+
&conn->http_negotiate_state;
127+
struct Curl_easy *data = conn->data;
127128
char *base64 = NULL;
128129
size_t len = 0;
129130
char *userp;
@@ -168,15 +169,15 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
168169
return result;
169170

170171
userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
171-
base64);
172+
base64);
172173

173174
if(proxy) {
174-
Curl_safefree(conn->allocptr.proxyuserpwd);
175-
conn->allocptr.proxyuserpwd = userp;
175+
Curl_safefree(data->state.aptr.proxyuserpwd);
176+
data->state.aptr.proxyuserpwd = userp;
176177
}
177178
else {
178-
Curl_safefree(conn->allocptr.userpwd);
179-
conn->allocptr.userpwd = userp;
179+
Curl_safefree(data->state.aptr.userpwd);
180+
data->state.aptr.userpwd = userp;
180181
}
181182

182183
free(base64);

0 commit comments

Comments
 (0)