diff --git a/CHANGES b/CHANGES index 852d16da4..8480c71cb 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,10 @@ Changelog +Michal Marek (16 Jun 2009) +- When doing non-anonymous ftp via http proxies and the password is not + provided in the url, add it there (squid needs this). + Daniel Stenberg (15 Jun 2009) - Eric Wong's patch: diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 6c0c53984..73dbcae61 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -28,6 +28,7 @@ This release includes the following bugfixes: o libcurl-NSS client cert handling segfaults o curl uploading from stdin/pipes now works in non-blocking way so that it continues the downloading even when the read stalls + o ftp credentials are added to the url if needed for http proxies This release includes the following known bugs: diff --git a/lib/http.c b/lib/http.c index 8457b51f4..f69c5aaaf 100644 --- a/lib/http.c +++ b/lib/http.c @@ -2060,6 +2060,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) CURLcode result=CURLE_OK; struct HTTP *http; const char *ppath = data->state.path; + bool paste_ftp_userpwd = FALSE; char ftp_typecode[sizeof(";type=?")] = ""; const char *host = conn->host.name; const char *te = ""; /* transfer-encoding */ @@ -2288,24 +2289,26 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) } } ppath = data->change.url; - if (data->set.proxy_transfer_mode) { - /* when doing ftp, append ;type= if not present */ - if(checkprefix("ftp://", ppath) || checkprefix("ftps://", ppath)) { - char *p = strstr(ppath, ";type="); - if(p && p[6] && p[7] == 0) { - switch (Curl_raw_toupper(p[6])) { - case 'A': - case 'D': - case 'I': - break; - default: - p = NULL; + if(checkprefix("ftp://", ppath)) { + if (data->set.proxy_transfer_mode) { + /* when doing ftp, append ;type= if not present */ + char *p = strstr(ppath, ";type="); + if(p && p[6] && p[7] == 0) { + switch (Curl_raw_toupper(p[6])) { + case 'A': + case 'D': + case 'I': + break; + default: + p = NULL; + } } - } - if(!p) - snprintf(ftp_typecode, sizeof(ftp_typecode), ";type=%c", - data->set.prefer_ascii ? 'a' : 'i'); + if(!p) + snprintf(ftp_typecode, sizeof(ftp_typecode), ";type=%c", + data->set.prefer_ascii ? 'a' : 'i'); } + if (conn->bits.user_passwd && !conn->bits.userpwd_in_url) + paste_ftp_userpwd = TRUE; } } #endif /* CURL_DISABLE_PROXY */ @@ -2464,10 +2467,23 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) return CURLE_OUT_OF_MEMORY; /* add the main request stuff */ - result = - add_bufferf(req_buffer, - "%s " /* GET/HEAD/POST/PUT */ - "%s%s HTTP/%s\r\n" /* path + HTTP version */ + /* GET/HEAD/POST/PUT */ + result = add_bufferf(req_buffer, "%s ", request); + if (result) + return result; + + /* url */ + if (paste_ftp_userpwd) + result = add_bufferf(req_buffer, "ftp://%s:%s@%s", + conn->user, conn->passwd, ppath + sizeof("ftp://") - 1); + else + result = add_buffer(req_buffer, ppath, strlen(ppath)); + if (result) + return result; + + result = add_bufferf(req_buffer, + "%s" /* ftp typecode (;type=x) */ + " HTTP/%s\r\n" /* HTTP version */ "%s" /* proxyuserpwd */ "%s" /* userpwd */ "%s" /* range */ @@ -2479,8 +2495,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) "%s" /* Proxy-Connection */ "%s",/* transfer-encoding */ - request, - ppath, ftp_typecode, httpstring, conn->allocptr.proxyuserpwd? diff --git a/lib/url.c b/lib/url.c index cd79866c7..11e336c0f 100644 --- a/lib/url.c +++ b/lib/url.c @@ -3831,6 +3831,7 @@ static CURLcode parse_url_userpass(struct SessionHandle *data, * set user/passwd, but doing that first adds more cases here :-( */ + conn->bits.userpwd_in_url = 1; if(data->set.use_netrc != CURL_NETRC_REQUIRED) { /* We could use the one in the URL */ diff --git a/lib/urldata.h b/lib/urldata.h index f41b6583e..a1d9be739 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -625,6 +625,7 @@ struct ConnectBits { EPRT doesn't work we disable it for the forthcoming requests */ bool netrc; /* name+password provided by netrc */ + bool userpwd_in_url; /* name+password found in url */ bool done; /* set to FALSE when Curl_do() is called and set to TRUE when Curl_done() is called, to prevent Curl_done() to diff --git a/tests/data/test299 b/tests/data/test299 new file mode 100644 index 000000000..a557a14c7 --- /dev/null +++ b/tests/data/test299 @@ -0,0 +1,53 @@ + + + +FTP +HTTP +CURLOPT_USERPWD +HTTP proxy + + + +# Server-side + + +HTTP/1.0 200 OK swsclose +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake + +blablabla + + + + +# Client-side + + +http + + +ftp + + +FTP over HTTP proxy with user:pass not in url + + +-x http://%HOSTIP:%HTTPPORT -u michal:aybabtu ftp://host.com/we/want/299 + + + +# Verify data after the test has been "shot" + + +^User-Agent:.* + + +GET ftp://michal:aybabtu@host.com/we/want/299 HTTP/1.1 +Authorization: Basic bWljaGFsOmF5YmFidHU= +Host: host.com:21 +Accept: */* +Proxy-Connection: Keep-Alive + + + +