@@ -1877,7 +1877,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
1877
1877
struct Curl_easy * data = conn -> data ;
1878
1878
CURLcode result = CURLE_OK ;
1879
1879
struct HTTP * http ;
1880
- const char * ppath = data -> state .path ;
1880
+ const char * path = data -> state .up .path ;
1881
+ const char * query = data -> state .up .query ;
1881
1882
bool paste_ftp_userpwd = FALSE;
1882
1883
char ftp_typecode [sizeof ("/;type=?" )] = "" ;
1883
1884
const char * host = conn -> host .name ;
@@ -1995,7 +1996,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
1995
1996
}
1996
1997
1997
1998
/* setup the authentication headers */
1998
- result = Curl_http_output_auth (conn , request , ppath , FALSE);
1999
+ result = Curl_http_output_auth (conn , request , path , FALSE);
1999
2000
if (result )
2000
2001
return result ;
2001
2002
@@ -2223,47 +2224,59 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
2223
2224
/* The path sent to the proxy is in fact the entire URL. But if the remote
2224
2225
host is a IDN-name, we must make sure that the request we produce only
2225
2226
uses the encoded host name! */
2227
+
2228
+ /* and no fragment part */
2229
+ CURLUcode uc ;
2230
+ char * url ;
2231
+ CURLU * h = curl_url_dup (data -> state .uh );
2232
+ if (!h )
2233
+ return CURLE_OUT_OF_MEMORY ;
2234
+
2226
2235
if (conn -> host .dispname != conn -> host .name ) {
2227
- char * url = data -> change .url ;
2228
- ptr = strstr (url , conn -> host .dispname );
2229
- if (ptr ) {
2230
- /* This is where the display name starts in the URL, now replace this
2231
- part with the encoded name. TODO: This method of replacing the host
2232
- name is rather crude as I believe there's a slight risk that the
2233
- user has entered a user name or password that contain the host name
2234
- string. */
2235
- size_t currlen = strlen (conn -> host .dispname );
2236
- size_t newlen = strlen (conn -> host .name );
2237
- size_t urllen = strlen (url );
2238
-
2239
- char * newurl ;
2240
-
2241
- newurl = malloc (urllen + newlen - currlen + 1 );
2242
- if (newurl ) {
2243
- /* copy the part before the host name */
2244
- memcpy (newurl , url , ptr - url );
2245
- /* append the new host name instead of the old */
2246
- memcpy (newurl + (ptr - url ), conn -> host .name , newlen );
2247
- /* append the piece after the host name */
2248
- memcpy (newurl + newlen + (ptr - url ),
2249
- ptr + currlen , /* copy the trailing zero byte too */
2250
- urllen - (ptr - url ) - currlen + 1 );
2251
- if (data -> change .url_alloc ) {
2252
- Curl_safefree (data -> change .url );
2253
- data -> change .url_alloc = FALSE;
2254
- }
2255
- data -> change .url = newurl ;
2256
- data -> change .url_alloc = TRUE;
2257
- }
2258
- else
2259
- return CURLE_OUT_OF_MEMORY ;
2236
+ uc = curl_url_set (h , CURLUPART_HOST , conn -> host .name , 0 );
2237
+ if (uc ) {
2238
+ curl_url_cleanup (h );
2239
+ return CURLE_OUT_OF_MEMORY ;
2260
2240
}
2261
2241
}
2262
- ppath = data -> change .url ;
2263
- if (checkprefix ("ftp://" , ppath )) {
2242
+ uc = curl_url_set (h , CURLUPART_FRAGMENT , NULL , 0 );
2243
+ if (uc ) {
2244
+ curl_url_cleanup (h );
2245
+ return CURLE_OUT_OF_MEMORY ;
2246
+ }
2247
+
2248
+ if (strcasecompare ("http" , data -> state .up .scheme )) {
2249
+ /* when getting HTTP, we don't want the userinfo the URL */
2250
+ uc = curl_url_set (h , CURLUPART_USER , NULL , 0 );
2251
+ if (uc ) {
2252
+ curl_url_cleanup (h );
2253
+ return CURLE_OUT_OF_MEMORY ;
2254
+ }
2255
+ uc = curl_url_set (h , CURLUPART_PASSWORD , NULL , 0 );
2256
+ if (uc ) {
2257
+ curl_url_cleanup (h );
2258
+ return CURLE_OUT_OF_MEMORY ;
2259
+ }
2260
+ }
2261
+ /* now extract the new version of the URL */
2262
+ uc = curl_url_get (h , CURLUPART_URL , & url , 0 );
2263
+ if (uc ) {
2264
+ curl_url_cleanup (h );
2265
+ return CURLE_OUT_OF_MEMORY ;
2266
+ }
2267
+
2268
+ if (data -> change .url_alloc )
2269
+ free (data -> change .url );
2270
+
2271
+ data -> change .url = url ;
2272
+ data -> change .url_alloc = TRUE;
2273
+
2274
+ curl_url_cleanup (h );
2275
+
2276
+ if (strcasecompare ("ftp" , data -> state .up .scheme )) {
2264
2277
if (data -> set .proxy_transfer_mode ) {
2265
2278
/* when doing ftp, append ;type=<a|i> if not present */
2266
- char * type = strstr (ppath , ";type=" );
2279
+ char * type = strstr (path , ";type=" );
2267
2280
if (type && type [6 ] && type [7 ] == 0 ) {
2268
2281
switch (Curl_raw_toupper (type [6 ])) {
2269
2282
case 'A' :
@@ -2278,7 +2291,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
2278
2291
char * p = ftp_typecode ;
2279
2292
/* avoid sending invalid URLs like ftp://example.com;type=i if the
2280
2293
* user specified ftp://example.com without the slash */
2281
- if (!* data -> state .path && ppath [strlen (ppath ) - 1 ] != '/' ) {
2294
+ if (!* data -> state .up . path && path [strlen (path ) - 1 ] != '/' ) {
2282
2295
* p ++ = '/' ;
2283
2296
}
2284
2297
snprintf (p , sizeof (ftp_typecode ) - 1 , ";type=%c" ,
@@ -2431,18 +2444,32 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
2431
2444
if (result )
2432
2445
return result ;
2433
2446
2434
- if (data -> set .str [STRING_TARGET ])
2435
- ppath = data -> set .str [STRING_TARGET ];
2447
+ if (data -> set .str [STRING_TARGET ]) {
2448
+ path = data -> set .str [STRING_TARGET ];
2449
+ query = NULL ;
2450
+ }
2436
2451
2437
2452
/* url */
2438
- if (paste_ftp_userpwd )
2453
+ if (conn -> bits .httpproxy && !conn -> bits .tunnel_proxy ) {
2454
+ char * url = data -> change .url ;
2455
+ result = Curl_add_buffer (& req_buffer , url , strlen (url ));
2456
+ if (result )
2457
+ return result ;
2458
+ }
2459
+ else if (paste_ftp_userpwd )
2439
2460
result = Curl_add_bufferf (& req_buffer , "ftp://%s:%s@%s" ,
2440
2461
conn -> user , conn -> passwd ,
2441
- ppath + sizeof ("ftp://" ) - 1 );
2442
- else
2443
- result = Curl_add_buffer (& req_buffer , ppath , strlen (ppath ));
2444
- if (result )
2445
- return result ;
2462
+ path + sizeof ("ftp://" ) - 1 );
2463
+ else {
2464
+ result = Curl_add_buffer (& req_buffer , path , strlen (path ));
2465
+ if (result )
2466
+ return result ;
2467
+ if (query ) {
2468
+ result = Curl_add_bufferf (& req_buffer , "?%s" , query );
2469
+ if (result )
2470
+ return result ;
2471
+ }
2472
+ }
2446
2473
2447
2474
result =
2448
2475
Curl_add_bufferf (& req_buffer ,
@@ -2515,7 +2542,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
2515
2542
co = Curl_cookie_getlist (data -> cookies ,
2516
2543
conn -> allocptr .cookiehost ?
2517
2544
conn -> allocptr .cookiehost :host ,
2518
- data -> state .path ,
2545
+ data -> state .up . path ,
2519
2546
(conn -> handler -> protocol & CURLPROTO_HTTPS )?
2520
2547
TRUE:FALSE);
2521
2548
Curl_share_unlock (data , CURL_LOCK_DATA_COOKIE );
@@ -3836,7 +3863,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
3836
3863
here, or else use real peer host name. */
3837
3864
conn -> allocptr .cookiehost ?
3838
3865
conn -> allocptr .cookiehost :conn -> host .name ,
3839
- data -> state .path );
3866
+ data -> state .up . path );
3840
3867
Curl_share_unlock (data , CURL_LOCK_DATA_COOKIE );
3841
3868
}
3842
3869
#endif
0 commit comments