aboutsummaryrefslogtreecommitdiff
path: root/lib/http.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2014-02-20 17:10:00 +0100
committerDaniel Stenberg <daniel@haxx.se>2014-04-04 17:03:43 +0200
commit74851340bd7b4edbdc749e74562fc1ebcef9930f (patch)
tree5648f921a7e79ffea2f7deb32188d3ad2ca8d3a5 /lib/http.c
parentd3d27551e716e4899ef8fea7ac416f1d6c654f96 (diff)
PROXYHEADER: send these headers in "normal" proxy requests too
Updated the docs to clarify and the code accordingly, with test 1528 to verify: When CURLHEADER_SEPARATE is set and libcurl is asked to send a request to a proxy but it isn't CONNECT, then _both_ header lists (CURLOPT_HTTPHEADER and CURLOPT_PROXYHEADER) will be used since the single request is then made for both the proxy and the server.
Diffstat (limited to 'lib/http.c')
-rw-r--r--lib/http.c148
1 files changed, 94 insertions, 54 deletions
diff --git a/lib/http.c b/lib/http.c
index b316fb4c2..1a2799f28 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -1544,80 +1544,120 @@ static CURLcode expect100(struct SessionHandle *data,
return result;
}
+enum proxy_use {
+ HEADER_SERVER, /* direct to server */
+ HEADER_PROXY, /* regular request to proxy */
+ HEADER_CONNECT /* sending CONNECT to a proxy */
+};
+
CURLcode Curl_add_custom_headers(struct connectdata *conn,
- bool is_proxy,
+ bool is_connect,
Curl_send_buffer *req_buffer)
{
char *ptr;
- struct curl_slist *headers=
- (is_proxy && conn->data->set.sep_headers)?
- conn->data->set.proxyheaders:conn->data->set.headers;
-
- while(headers) {
- ptr = strchr(headers->data, ':');
- if(ptr) {
- /* we require a colon for this to be a true header */
+ struct curl_slist *h[2];
+ struct curl_slist *headers;
+ int numlists=1; /* by default */
+ struct SessionHandle *data = conn->data;
+ int i;
- ptr++; /* pass the colon */
- while(*ptr && ISSPACE(*ptr))
- ptr++;
+ enum proxy_use proxy;
- if(*ptr) {
- /* only send this if the contents was non-blank */
+ if(is_connect)
+ proxy = HEADER_CONNECT;
+ else
+ proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy?
+ HEADER_PROXY:HEADER_SERVER;
- if(conn->allocptr.host &&
- /* a Host: header was sent already, don't pass on any custom Host:
- header as that will produce *two* in the same request! */
- checkprefix("Host:", headers->data))
- ;
- else if(conn->data->set.httpreq == HTTPREQ_POST_FORM &&
- /* this header (extended by formdata.c) is sent later */
- checkprefix("Content-Type:", headers->data))
- ;
- else if(conn->bits.authneg &&
- /* while doing auth neg, don't allow the custom length since
- we will force length zero then */
- checkprefix("Content-Length", headers->data))
- ;
- else if(conn->allocptr.te &&
- /* when asking for Transfer-Encoding, don't pass on a custom
- Connection: */
- checkprefix("Connection", headers->data))
- ;
- else {
- CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
- headers->data);
- if(result)
- return result;
- }
- }
+ switch(proxy) {
+ case HEADER_SERVER:
+ h[0] = data->set.headers;
+ break;
+ case HEADER_PROXY:
+ h[0] = data->set.headers;
+ if(data->set.sep_headers) {
+ h[1] = data->set.proxyheaders;
+ numlists++;
}
- else {
- ptr = strchr(headers->data, ';');
+ break;
+ case HEADER_CONNECT:
+ if(data->set.sep_headers)
+ h[0] = data->set.proxyheaders;
+ else
+ h[0] = data->set.headers;
+ break;
+ }
+
+ /* loop through one or two lists */
+ for(i=0; i < numlists; i++) {
+ headers = h[i];
+
+ while(headers) {
+ ptr = strchr(headers->data, ':');
if(ptr) {
+ /* we require a colon for this to be a true header */
- ptr++; /* pass the semicolon */
+ ptr++; /* pass the colon */
while(*ptr && ISSPACE(*ptr))
ptr++;
if(*ptr) {
- /* this may be used for something else in the future */
- }
- else {
- if(*(--ptr) == ';') {
- CURLcode result;
-
- /* send no-value custom header if terminated by semicolon */
- *ptr = ':';
- result = Curl_add_bufferf(req_buffer, "%s\r\n",
- headers->data);
+ /* only send this if the contents was non-blank */
+
+ if(conn->allocptr.host &&
+ /* a Host: header was sent already, don't pass on any custom Host:
+ header as that will produce *two* in the same request! */
+ checkprefix("Host:", headers->data))
+ ;
+ else if(data->set.httpreq == HTTPREQ_POST_FORM &&
+ /* this header (extended by formdata.c) is sent later */
+ checkprefix("Content-Type:", headers->data))
+ ;
+ else if(conn->bits.authneg &&
+ /* while doing auth neg, don't allow the custom length since
+ we will force length zero then */
+ checkprefix("Content-Length", headers->data))
+ ;
+ else if(conn->allocptr.te &&
+ /* when asking for Transfer-Encoding, don't pass on a custom
+ Connection: */
+ checkprefix("Connection", headers->data))
+ ;
+ else {
+ CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
+ headers->data);
if(result)
return result;
}
}
}
+ else {
+ ptr = strchr(headers->data, ';');
+ if(ptr) {
+
+ ptr++; /* pass the semicolon */
+ while(*ptr && ISSPACE(*ptr))
+ ptr++;
+
+ if(*ptr) {
+ /* this may be used for something else in the future */
+ }
+ else {
+ if(*(--ptr) == ';') {
+ CURLcode result;
+
+ /* send no-value custom header if terminated by semicolon */
+ *ptr = ':';
+ result = Curl_add_bufferf(req_buffer, "%s\r\n",
+ headers->data);
+ if(result)
+ return result;
+ }
+ }
+ }
+ }
+ headers = headers->next;
}
- headers = headers->next;
}
return CURLE_OK;
}