diff --git a/lib/http.c b/lib/http.c
index a1e58e886c..f976987111 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -1278,12 +1278,24 @@ CURLcode Curl_http_follow(struct Curl_easy *data, const char *newurl,
curlx_free(scheme);
}
if(clear) {
+ CURLcode result = Curl_reset_userpwd(data);
+ if(result) {
+ curlx_free(follow_url);
+ return result;
+ }
curlx_safefree(data->state.aptr.user);
curlx_safefree(data->state.aptr.passwd);
}
}
}
DEBUGASSERT(follow_url);
+ {
+ CURLcode result = Curl_reset_proxypwd(data);
+ if(result) {
+ curlx_free(follow_url);
+ return result;
+ }
+ }
if(type == FOLLOW_FAKE) {
/* we are only figuring out the new URL if we would have followed locations
diff --git a/lib/transfer.c b/lib/transfer.c
index dd4e16b7f5..a2fce9331b 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -438,6 +438,40 @@ void Curl_init_CONNECT(struct Curl_easy *data)
data->state.upload = (data->state.httpreq == HTTPREQ_PUT);
}
+/*
+ * Restore the user credentials to those set in options.
+ */
+CURLcode Curl_reset_userpwd(struct Curl_easy *data)
+{
+ CURLcode result;
+ if(data->set.str[STRING_USERNAME] || data->set.str[STRING_PASSWORD])
+ data->state.creds_from = CREDS_OPTION;
+ result = Curl_setstropt(&data->state.aptr.user,
+ data->set.str[STRING_USERNAME]);
+ if(!result)
+ result = Curl_setstropt(&data->state.aptr.passwd,
+ data->set.str[STRING_PASSWORD]);
+ return result;
+}
+
+/*
+ * Restore the proxy credentials to those set in options.
+ */
+CURLcode Curl_reset_proxypwd(struct Curl_easy *data)
+{
+#ifndef CURL_DISABLE_PROXY
+ CURLcode result = Curl_setstropt(&data->state.aptr.proxyuser,
+ data->set.str[STRING_PROXYUSERNAME]);
+ if(!result)
+ result = Curl_setstropt(&data->state.aptr.proxypasswd,
+ data->set.str[STRING_PROXYPASSWORD]);
+ return result;
+#else
+ (void)data;
+ return CURLE_OK;
+#endif
+}
+
/*
* Curl_pretransfer() is called immediately before a transfer starts, and only
* once for one transfer no matter if it has redirects or do multi-pass
@@ -586,23 +620,10 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
return CURLE_OUT_OF_MEMORY;
}
- if(data->set.str[STRING_USERNAME] ||
- data->set.str[STRING_PASSWORD])
- data->state.creds_from = CREDS_OPTION;
if(!result)
- result = Curl_setstropt(&data->state.aptr.user,
- data->set.str[STRING_USERNAME]);
+ result = Curl_reset_userpwd(data);
if(!result)
- result = Curl_setstropt(&data->state.aptr.passwd,
- data->set.str[STRING_PASSWORD]);
-#ifndef CURL_DISABLE_PROXY
- if(!result)
- result = Curl_setstropt(&data->state.aptr.proxyuser,
- data->set.str[STRING_PROXYUSERNAME]);
- if(!result)
- result = Curl_setstropt(&data->state.aptr.proxypasswd,
- data->set.str[STRING_PROXYPASSWORD]);
-#endif
+ result = Curl_reset_proxypwd(data);
data->req.headerbytecount = 0;
Curl_headers_cleanup(data);
diff --git a/lib/transfer.h b/lib/transfer.h
index 41ec0357f6..b29e70b9ec 100644
--- a/lib/transfer.h
+++ b/lib/transfer.h
@@ -31,6 +31,8 @@ char *Curl_checkheaders(const struct Curl_easy *data,
void Curl_init_CONNECT(struct Curl_easy *data);
+CURLcode Curl_reset_userpwd(struct Curl_easy *data);
+CURLcode Curl_reset_proxypwd(struct Curl_easy *data);
CURLcode Curl_pretransfer(struct Curl_easy *data);
CURLcode Curl_sendrecv(struct Curl_easy *data);
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 44ff75668f..3003dce03b 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -244,7 +244,7 @@ test1970 test1971 test1972 test1973 test1974 test1975 test1976 test1977 \
test1978 test1979 test1980 test1981 test1982 test1983 test1984 \
\
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
-test2008 \
+test2008 test2009 test2010 test2011 \
\
test2023 \
test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \
diff --git a/tests/data/test2009 b/tests/data/test2009
new file mode 100644
index 0000000000..d2fd79e0d6
--- /dev/null
+++ b/tests/data/test2009
@@ -0,0 +1,70 @@
+
+
+
+
+HTTP
+HTTP proxy
+http_proxy
+
+
+# Server-side
+
+
+HTTP/1.1 407 Denied
+
+
+
+HTTP/1.1 301 redirect
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 4
+Content-Type: text/html
+Location: https://another.example/%TESTNUMBER0002
+
+boo
+
+
+
+# Client-side
+
+
+proxy
+
+
+http
+https
+
+
+proxy credentials via env variables, redirect from http to https
+
+
+
+http_proxy=http://user:secret@%HOSTIP:%HTTPPORT
+https_proxy=https://%HOSTIP:%HTTPSPORT/
+
+
+http://somewhere.example/ --follow --proxy-insecure
+
+
+
+# Verify data after the test has been "shot"
+
+
+GET http://somewhere.example/ HTTP/1.1
+Host: somewhere.example
+Proxy-Authorization: Basic %b64[user:secret]b64%
+User-Agent: curl/%VERSION
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+CONNECT another.example:443 HTTP/1.1
+Host: another.example:443
+User-Agent: curl/%VERSION
+Proxy-Connection: Keep-Alive
+
+
+
+7
+
+
+
diff --git a/tests/data/test2010 b/tests/data/test2010
new file mode 100644
index 0000000000..443ae9d2f9
--- /dev/null
+++ b/tests/data/test2010
@@ -0,0 +1,71 @@
+
+
+
+
+HTTP
+HTTP proxy
+http_proxy
+
+
+# Server-side
+
+
+HTTP/1.1 407 Denied
+
+
+
+HTTP/1.1 301 redirect
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 4
+Content-Type: text/html
+Location: https://another.example/%TESTNUMBER0002
+
+boo
+
+
+
+# Client-side
+
+
+proxy
+
+
+http
+https
+
+
+proxy credentials via options for two proxies, redirect from http to https
+
+
+
+http_proxy=http://%HOSTIP:%HTTPPORT
+https_proxy=https://%HOSTIP:%HTTPSPORT/
+
+
+--proxy-user batman:robin http://somewhere.example/ --follow --proxy-insecure
+
+
+
+# Verify data after the test has been "shot"
+
+
+GET http://somewhere.example/ HTTP/1.1
+Host: somewhere.example
+Proxy-Authorization: Basic %b64[batman:robin]b64%
+User-Agent: curl/%VERSION
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+CONNECT another.example:443 HTTP/1.1
+Host: another.example:443
+Proxy-Authorization: Basic %b64[batman:robin]b64%
+User-Agent: curl/%VERSION
+Proxy-Connection: Keep-Alive
+
+
+
+7
+
+
+
diff --git a/tests/data/test2011 b/tests/data/test2011
new file mode 100644
index 0000000000..dd4e534248
--- /dev/null
+++ b/tests/data/test2011
@@ -0,0 +1,70 @@
+
+
+
+
+HTTP
+HTTP proxy
+http_proxy
+
+
+# Server-side
+
+
+HTTP/1.1 407 Denied
+
+
+
+HTTP/1.1 301 redirect
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 4
+Content-Type: text/html
+Location: https://another.example/%TESTNUMBER0002
+
+boo
+
+
+
+# Client-side
+
+
+proxy
+
+
+http
+https
+
+
+proxy creds via env, cross-scheme redirect, --location-trusted
+
+
+
+http_proxy=http://user:secret@%HOSTIP:%HTTPPORT
+https_proxy=https://%HOSTIP:%HTTPSPORT/
+
+
+http://somewhere.example/ --location-trusted --proxy-insecure
+
+
+
+# Verify data after the test has been "shot"
+
+
+GET http://somewhere.example/ HTTP/1.1
+Host: somewhere.example
+Proxy-Authorization: Basic %b64[user:secret]b64%
+User-Agent: curl/%VERSION
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+CONNECT another.example:443 HTTP/1.1
+Host: another.example:443
+User-Agent: curl/%VERSION
+Proxy-Connection: Keep-Alive
+
+
+
+7
+
+
+