|
| 1 | +From 3a19987a87f393d9394fe5acc7643f6c263c92db Mon Sep 17 00:00:00 2001 |
| 2 | +From: Daniel Stenberg <daniel@haxx.se> |
| 3 | +Date: Tue, 14 Apr 2026 08:51:44 +0200 |
| 4 | +Subject: [PATCH] urldata: move cookiehost to struct SingleRequest |
| 5 | + |
| 6 | +To make it scoped for the single request appropriately. |
| 7 | + |
| 8 | +Reported-by: Muhamad Arga Reksapati |
| 9 | + |
| 10 | +Verify with libtest 2504: a custom Host *disabled* on reused handle |
| 11 | + |
| 12 | +Closes #21312 |
| 13 | + |
| 14 | +Upstream Patch Reference: https://github.com/curl/curl/commit/3a19987a87f393d9394fe5acc7643f6c263c92db |
| 15 | +--- |
| 16 | + lib/http.c | 14 +++--- |
| 17 | + lib/request.c | 3 ++ |
| 18 | + lib/request.h | 3 ++ |
| 19 | + lib/url.c | 2 +- |
| 20 | + lib/urldata.h | 3 -- |
| 21 | + tests/data/Makefile.am | 2 +- |
| 22 | + tests/data/test2504 | 52 +++++++++++++++++++++ |
| 23 | + tests/libtest/Makefile.inc | 5 +- |
| 24 | + tests/libtest/lib2504.c | 93 ++++++++++++++++++++++++++++++++++++++ |
| 25 | + 9 files changed, 165 insertions(+), 12 deletions(-) |
| 26 | + create mode 100644 tests/data/test2504 |
| 27 | + create mode 100644 tests/libtest/lib2504.c |
| 28 | + |
| 29 | +diff --git a/lib/http.c b/lib/http.c |
| 30 | +index 4de1667..7d328e0 100644 |
| 31 | +--- a/lib/http.c |
| 32 | ++++ b/lib/http.c |
| 33 | +@@ -1543,6 +1543,9 @@ CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn) |
| 34 | + data->state.first_remote_protocol = conn->handler->protocol; |
| 35 | + } |
| 36 | + Curl_safefree(aptr->host); |
| 37 | ++#ifndef CURL_DISABLE_COOKIES |
| 38 | ++ Curl_safefree(data->req.cookiehost); |
| 39 | ++#endif |
| 40 | + |
| 41 | + ptr = Curl_checkheaders(data, STRCONST("Host")); |
| 42 | + if(ptr && (!data->state.this_is_a_follow || |
| 43 | +@@ -1577,8 +1580,7 @@ CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn) |
| 44 | + if(colon) |
| 45 | + *colon = 0; /* The host must not include an embedded port number */ |
| 46 | + } |
| 47 | +- Curl_safefree(aptr->cookiehost); |
| 48 | +- aptr->cookiehost = cookiehost; |
| 49 | ++ data->req.cookiehost = cookiehost; |
| 50 | + } |
| 51 | + #endif |
| 52 | + |
| 53 | +@@ -2097,8 +2099,8 @@ CURLcode Curl_http_cookies(struct Curl_easy *data, |
| 54 | + int rc = 1; |
| 55 | + |
| 56 | + if(data->cookies && data->state.cookie_engine) { |
| 57 | +- const char *host = data->state.aptr.cookiehost ? |
| 58 | +- data->state.aptr.cookiehost : conn->host.name; |
| 59 | ++ const char *host = data->req.cookiehost ? |
| 60 | ++ data->req.cookiehost : conn->host.name; |
| 61 | + const bool secure_context = |
| 62 | + conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) || |
| 63 | + strcasecompare("localhost", host) || |
| 64 | +@@ -2920,8 +2922,8 @@ CURLcode Curl_http_header(struct Curl_easy *data, |
| 65 | + if(v) { |
| 66 | + /* If there is a custom-set Host: name, use it here, or else use |
| 67 | + * real peer hostname. */ |
| 68 | +- const char *host = data->state.aptr.cookiehost ? |
| 69 | +- data->state.aptr.cookiehost : conn->host.name; |
| 70 | ++ const char *host = data->req.cookiehost ? |
| 71 | ++ data->req.cookiehost : conn->host.name; |
| 72 | + const bool secure_context = |
| 73 | + conn->handler->protocol&(CURLPROTO_HTTPS|CURLPROTO_WSS) || |
| 74 | + strcasecompare("localhost", host) || |
| 75 | +diff --git a/lib/request.c b/lib/request.c |
| 76 | +index 310e4ea..088425d 100644 |
| 77 | +--- a/lib/request.c |
| 78 | ++++ b/lib/request.c |
| 79 | +@@ -124,6 +124,9 @@ void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data) |
| 80 | + |
| 81 | + #ifndef CURL_DISABLE_DOH |
| 82 | + Curl_doh_close(data); |
| 83 | ++#endif |
| 84 | ++#ifndef CURL_DISABLE_COOKIES |
| 85 | ++ Curl_safefree(req->cookiehost); |
| 86 | + #endif |
| 87 | + /* Can no longer memset() this struct as we need to keep some state */ |
| 88 | + req->size = -1; |
| 89 | +diff --git a/lib/request.h b/lib/request.h |
| 90 | +index bb72247..90cb0ae 100644 |
| 91 | +--- a/lib/request.h |
| 92 | ++++ b/lib/request.h |
| 93 | +@@ -119,6 +119,9 @@ struct SingleRequest { |
| 94 | + #ifndef CURL_DISABLE_DOH |
| 95 | + struct doh_probes *doh; /* DoH specific data for this request */ |
| 96 | + #endif |
| 97 | ++#ifndef CURL_DISABLE_COOKIES |
| 98 | ++ char *cookiehost; |
| 99 | ++#endif |
| 100 | + #ifndef CURL_DISABLE_COOKIES |
| 101 | + unsigned char setcookies; |
| 102 | + #endif |
| 103 | +diff --git a/lib/url.c b/lib/url.c |
| 104 | +index 2ba5311..6ea7b30 100644 |
| 105 | +--- a/lib/url.c |
| 106 | ++++ b/lib/url.c |
| 107 | +@@ -317,7 +317,7 @@ CURLcode Curl_close(struct Curl_easy **datap) |
| 108 | + Curl_safefree(data->state.aptr.ref); |
| 109 | + Curl_safefree(data->state.aptr.host); |
| 110 | + #ifndef CURL_DISABLE_COOKIES |
| 111 | +- Curl_safefree(data->state.aptr.cookiehost); |
| 112 | ++ Curl_safefree(data->req.cookiehost); |
| 113 | + #endif |
| 114 | + #ifndef CURL_DISABLE_RTSP |
| 115 | + Curl_safefree(data->state.aptr.rtsp_transport); |
| 116 | +diff --git a/lib/urldata.h b/lib/urldata.h |
| 117 | +index 704fb7a..026fa2a 100644 |
| 118 | +--- a/lib/urldata.h |
| 119 | ++++ b/lib/urldata.h |
| 120 | +@@ -1331,9 +1331,6 @@ struct UrlState { |
| 121 | + char *rangeline; |
| 122 | + char *ref; |
| 123 | + char *host; |
| 124 | +-#ifndef CURL_DISABLE_COOKIES |
| 125 | +- char *cookiehost; |
| 126 | +-#endif |
| 127 | + #ifndef CURL_DISABLE_RTSP |
| 128 | + char *rtsp_transport; |
| 129 | + #endif |
| 130 | +diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am |
| 131 | +index 26e015f..b0d1b0a 100644 |
| 132 | +--- a/tests/data/Makefile.am |
| 133 | ++++ b/tests/data/Makefile.am |
| 134 | +@@ -259,7 +259,7 @@ test2308 test2309 \ |
| 135 | + \ |
| 136 | + test2400 test2401 test2402 test2403 test2404 test2405 test2406 \ |
| 137 | + \ |
| 138 | +-test2500 test2501 test2502 test2503 \ |
| 139 | ++test2500 test2501 test2502 test2503 test2504 \ |
| 140 | + \ |
| 141 | + test2600 test2601 test2602 test2603 test2604 \ |
| 142 | + \ |
| 143 | +diff --git a/tests/data/test2504 b/tests/data/test2504 |
| 144 | +new file mode 100644 |
| 145 | +index 0000000..8cec1c8 |
| 146 | +--- /dev/null |
| 147 | ++++ b/tests/data/test2504 |
| 148 | +@@ -0,0 +1,52 @@ |
| 149 | ++<?xml version="1.0" encoding="US-ASCII"?> |
| 150 | ++<testcase> |
| 151 | ++<info> |
| 152 | ++<keywords> |
| 153 | ++HTTP |
| 154 | ++cookies |
| 155 | ++</keywords> |
| 156 | ++</info> |
| 157 | ++ |
| 158 | ++# Server-side |
| 159 | ++<reply> |
| 160 | ++<data crlf="headers" nocheck="yes"> |
| 161 | ++HTTP/1.1 200 OK |
| 162 | ++Date: Tue, 09 Nov 2010 14:49:00 GMT |
| 163 | ++Server: server.example.com |
| 164 | ++Content-Length: 47 |
| 165 | ++Set-Cookie: sid=SECRET123; Path=/ |
| 166 | ++ |
| 167 | ++file contents should appear once for each file |
| 168 | ++</data> |
| 169 | ++</reply> |
| 170 | ++ |
| 171 | ++# Client-side |
| 172 | ++<client> |
| 173 | ++<server> |
| 174 | ++http |
| 175 | ++</server> |
| 176 | ++<tool> |
| 177 | ++lib%TESTNUMBER |
| 178 | ++</tool> |
| 179 | ++<name> |
| 180 | ++custom Host with cookie, handle reuse, no custom Host: |
| 181 | ++</name> |
| 182 | ++<command> |
| 183 | ++http://%HOSTIP:%HTTPPORT |
| 184 | ++</command> |
| 185 | ++</client> |
| 186 | ++ |
| 187 | ++# Verify data after the test has been "shot" |
| 188 | ++<verify> |
| 189 | ++<protocol crlf="headers"> |
| 190 | ++GET / HTTP/1.1 |
| 191 | ++Host: victim.internal |
| 192 | ++Accept: */* |
| 193 | ++ |
| 194 | ++GET / HTTP/1.1 |
| 195 | ++Host: %HOSTIP:%HTTPPORT |
| 196 | ++Accept: */* |
| 197 | ++ |
| 198 | ++</protocol> |
| 199 | ++</verify> |
| 200 | ++</testcase> |
| 201 | +diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc |
| 202 | +index 8f58fd6..b393665 100644 |
| 203 | +--- a/tests/libtest/Makefile.inc |
| 204 | ++++ b/tests/libtest/Makefile.inc |
| 205 | +@@ -79,7 +79,7 @@ LIBTESTPROGS = libauthretry libntlmconnect libprereq \ |
| 206 | + lib1970 lib1971 lib1972 lib1973 lib1974 lib1975 \ |
| 207 | + lib2301 lib2302 lib2304 lib2305 lib2306 lib2308 lib2309 \ |
| 208 | + lib2402 lib2404 lib2405 \ |
| 209 | +- lib2502 \ |
| 210 | ++ lib2502 lib2504 \ |
| 211 | + lib3010 lib3025 lib3026 lib3027 \ |
| 212 | + lib3100 lib3101 lib3102 lib3103 lib3207 |
| 213 | + |
| 214 | +@@ -698,6 +698,9 @@ lib2405_LDADD = $(TESTUTIL_LIBS) |
| 215 | + lib2502_SOURCES = lib2502.c $(SUPPORTFILES) $(TESTUTIL) $(TSTTRACE) $(WARNLESS) |
| 216 | + lib2502_LDADD = $(TESTUTIL_LIBS) |
| 217 | + |
| 218 | ++lib2504_SOURCES = lib2504.c $(SUPPORTFILES) $(TESTUTIL) $(TSTTRACE) |
| 219 | ++lib2504_LDADD = $(TESTUTIL_LIBS) |
| 220 | ++ |
| 221 | + lib3010_SOURCES = lib3010.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) |
| 222 | + lib3010_LDADD = $(TESTUTIL_LIBS) |
| 223 | + |
| 224 | +diff --git a/tests/libtest/lib2504.c b/tests/libtest/lib2504.c |
| 225 | +new file mode 100644 |
| 226 | +index 0000000..72b965d |
| 227 | +--- /dev/null |
| 228 | ++++ b/tests/libtest/lib2504.c |
| 229 | +@@ -0,0 +1,93 @@ |
| 230 | ++/*************************************************************************** |
| 231 | ++ * _ _ ____ _ |
| 232 | ++ * Project ___| | | | _ \| | |
| 233 | ++ * / __| | | | |_) | | |
| 234 | ++ * | (__| |_| | _ <| |___ |
| 235 | ++ * \___|\___/|_| \_\_____| |
| 236 | ++ * |
| 237 | ++ * Copyright (C) Linus Nielsen Feltzing <linus@haxx.se> |
| 238 | ++ * |
| 239 | ++ * This software is licensed as described in the file COPYING, which |
| 240 | ++ * you should have received as part of this distribution. The terms |
| 241 | ++ * are also available at https://curl.se/docs/copyright.html. |
| 242 | ++ * |
| 243 | ++ * You may opt to use, copy, modify, merge, publish, distribute and/or sell |
| 244 | ++ * copies of the Software, and permit persons to whom the Software is |
| 245 | ++ * furnished to do so, under the terms of the COPYING file. |
| 246 | ++ * |
| 247 | ++ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| 248 | ++ * KIND, either express or implied. |
| 249 | ++ * |
| 250 | ++ * SPDX-License-Identifier: curl |
| 251 | ++ * |
| 252 | ++ ***************************************************************************/ |
| 253 | ++#include "first.h" |
| 254 | ++ |
| 255 | ++#include "testtrace.h" |
| 256 | ++ |
| 257 | ++static size_t sink2504(char *ptr, size_t size, size_t nmemb, void *ud) |
| 258 | ++{ |
| 259 | ++ (void)ptr; |
| 260 | ++ (void)ud; |
| 261 | ++ return size * nmemb; |
| 262 | ++} |
| 263 | ++ |
| 264 | ++static void dump_cookies2504(CURL *h, const char *tag) |
| 265 | ++{ |
| 266 | ++ struct curl_slist *cookies = NULL; |
| 267 | ++ struct curl_slist *nc; |
| 268 | ++ CURLcode rc = curl_easy_getinfo(h, CURLINFO_COOKIELIST, &cookies); |
| 269 | ++ |
| 270 | ++ curl_mprintf("== %s ==\n", tag); |
| 271 | ++ if(rc) { |
| 272 | ++ curl_mprintf("getinfo error: %d\n", (int)rc); |
| 273 | ++ return; |
| 274 | ++ } |
| 275 | ++ for(nc = cookies; nc; nc = nc->next) |
| 276 | ++ puts(nc->data); |
| 277 | ++ curl_slist_free_all(cookies); |
| 278 | ++} |
| 279 | ++ |
| 280 | ++static CURLcode test_lib2504(const char *URL) |
| 281 | ++{ |
| 282 | ++ CURL *curl; |
| 283 | ++ CURLcode result = CURLE_OUT_OF_MEMORY; |
| 284 | ++ struct curl_slist *hdrs = NULL; |
| 285 | ++ |
| 286 | ++ if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { |
| 287 | ++ curl_mfprintf(stderr, "curl_global_init() failed\n"); |
| 288 | ++ return TEST_ERR_MAJOR_BAD; |
| 289 | ++ } |
| 290 | ++ |
| 291 | ++ curl = curl_easy_init(); |
| 292 | ++ if(!curl) { |
| 293 | ++ curl_mfprintf(stderr, "curl_easy_init() failed\n"); |
| 294 | ++ curl_global_cleanup(); |
| 295 | ++ return TEST_ERR_MAJOR_BAD; |
| 296 | ++ } |
| 297 | ++ |
| 298 | ++ hdrs = curl_slist_append(hdrs, "Host: victim.internal"); |
| 299 | ++ if(hdrs) { |
| 300 | ++ test_setopt(curl, CURLOPT_WRITEFUNCTION, sink2504); |
| 301 | ++ test_setopt(curl, CURLOPT_COOKIEFILE, ""); |
| 302 | ++ test_setopt(curl, CURLOPT_HTTPHEADER, hdrs); |
| 303 | ++ test_setopt(curl, CURLOPT_URL, URL); |
| 304 | ++ |
| 305 | ++ result = curl_easy_perform(curl); |
| 306 | ++ curl_mprintf("req1=%d\n", (int)result); |
| 307 | ++ dump_cookies2504(curl, "after request 1"); |
| 308 | ++ |
| 309 | ++ test_setopt(curl, CURLOPT_HTTPHEADER, NULL); |
| 310 | ++ test_setopt(curl, CURLOPT_URL, URL); |
| 311 | ++ |
| 312 | ++ result = curl_easy_perform(curl); |
| 313 | ++ curl_mprintf("req2=%d\n", (int)result); |
| 314 | ++ dump_cookies2504(curl, "after request 2"); |
| 315 | ++ } |
| 316 | ++test_cleanup: |
| 317 | ++ curl_slist_free_all(hdrs); |
| 318 | ++ curl_easy_cleanup(curl); |
| 319 | ++ curl_global_cleanup(); |
| 320 | ++ |
| 321 | ++ return result; |
| 322 | ++} |
| 323 | +-- |
| 324 | +2.45.4 |
| 325 | + |
0 commit comments