Skip to content

Commit

Permalink
CURLOPT_HEADEROPT: added
Browse files Browse the repository at this point in the history
Modified the logic so that CURLOPT_HEADEROPT now controls if PROXYHEADER
is actually used or not.
  • Loading branch information
bagder committed Apr 4, 2014
1 parent ac887ee commit ef6be35
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 28 deletions.
60 changes: 36 additions & 24 deletions docs/libcurl/curl_easy_setopt.3
Expand Up @@ -1515,17 +1515,20 @@ set the User-Agent: header in the http request sent to the remote server. This
can be used to fool servers or scripts. You can also set any custom header
with \fICURLOPT_HTTPHEADER\fP.
.IP CURLOPT_HTTPHEADER
Pass a pointer to a linked list of HTTP headers to pass to the server in your
HTTP request. The linked list should be a fully valid list of \fBstruct
curl_slist\fP structs properly filled in. Use \fIcurl_slist_append(3)\fP to
create the list and \fIcurl_slist_free_all(3)\fP to clean up an entire
list. If you add a header that is otherwise generated and used by libcurl
internally, your added one will be used instead. If you add a header with no
content as in 'Accept:' (no data on the right side of the colon), the
internally used header will get disabled. Thus, using this option you can add
new headers, replace internal headers and remove internal headers. To add a
header with no content (nothing to the right side of the colon), use the
form 'MyHeader;' (note the ending semicolon).
Pass a pointer to a linked list of HTTP headers to pass to the server and/or
proxy in your HTTP request. The same list is used for both host and proxy
requests!

The linked list should be a fully valid list of \fBstruct curl_slist\fP
structs properly filled in. Use \fIcurl_slist_append(3)\fP to create the list
and \fIcurl_slist_free_all(3)\fP to clean up an entire list. If you add a
header that is otherwise generated and used by libcurl internally, your added
one will be used instead. If you add a header with no content as in 'Accept:'
(no data on the right side of the colon), the internally used header will get
disabled. With this option you can add new headers, replace internal headers
and remove internal headers. To add a header with no content (nothing to the
right side of the colon), use the form 'MyHeader;' (note the ending
semicolon).

The headers included in the linked list must not be CRLF-terminated, because
curl adds CRLF after each header item. Failure to comply with this will result
Expand All @@ -1542,26 +1545,35 @@ Pass a NULL to this to reset back to no custom headers.
The most commonly replaced headers have "shortcuts" in the options
\fICURLOPT_COOKIE\fP, \fICURLOPT_USERAGENT\fP and \fICURLOPT_REFERER\fP.

Starting in 7.36.0, libcurl offers an alternative option that sets or replaces
headers only for requests that are sent to a proxy:
\fICURLOPT_PROXYHEADER\fP. If \fICURLOPT_PROXYHEADER\fP is not used at all by
an application, the \fICURLOPT_HTTPHEADER headers\fP will be used for proxy
requests as well!
There's an alternative option that sets or replaces headers only for requests
that are sent with CONNECT to a proxy: \fICURLOPT_PROXYHEADER\fP. Use
\fICURLOPT_HEADEROPT\fP to control the behavior.
.IP CURLOPT_HEADEROPT
Pass a long that is a bitmask of options of how to deal with headers. The
available options are:

CURLHEADER_UNIFIED - keep working as before. This means CURLOPT_HTTPHEADER
headers will be used in requests both to servers and in CONNECT requests. With
this option enabled, \fICURLOPT_PROXYHEADER\fP will not have any effect.

CURLHEADER_SEPARATE - makes \fICURLOPT_HTTPHEADER\fP headers only get sent to
a host and not to a proxy if CONNECT is being used. It has to be set to make
\fICURLOPT_PROXYHEADER\fP get used.

This behavior is set per request and an application can alter it between
different invokes if desired.

(Added in 7.36.0)
.IP CURLOPT_PROXYHEADER
Pass a pointer to a linked list of HTTP headers to pass in your HTTP request
sent to a proxy. The rules for this list is identical to the
\fICURLOPT_HTTPHEADER\fP option's.

The headers set with this option is only ever used in requests sent to a
proxy.

As a special quirk to stay backwards compatible with the libcurl versions
released before this option existed, all headers set with
\fICURLOPT_HTTPHEADER\fP will also be used for proxies unless you set one or
more headers (or even just NULL) with \fICURLOPT_PROXYHEADER\fP.
The headers set with this option is only ever used in requests sent to a proxy
- when there's also a request sent to a host.

The first line in a request (containing the method, usually a GET or POST) is
not a header and cannot be replaced using this option. Only the lines
NOT a header and cannot be replaced using this option. Only the lines
following the request-line are headers. Adding this method line in this list
of headers will only cause your request to send an invalid header.

Expand Down
1 change: 1 addition & 0 deletions docs/libcurl/symbols-in-versions
Expand Up @@ -370,6 +370,7 @@ CURLOPT_GSSAPI_DELEGATION 7.22.0
CURLOPT_HEADER 7.1
CURLOPT_HEADERDATA 7.10
CURLOPT_HEADERFUNCTION 7.7.2
CURLOPT_HEADEROPT 7.36.0
CURLOPT_HTTP200ALIASES 7.10.3
CURLOPT_HTTPAUTH 7.10.6
CURLOPT_HTTPGET 7.8.1
Expand Down
7 changes: 7 additions & 0 deletions include/curl/curl.h
Expand Up @@ -754,6 +754,10 @@ typedef enum {
CURLFTPMETHOD_LAST /* not an option, never use */
} curl_ftpmethod;

/* bitmask defines for CURLOPT_HEADEROPT */
#define CURLHEADER_UNIFIED 0
#define CURLHEADER_SEPARATE (1<<0)

/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
#define CURLPROTO_HTTP (1<<0)
#define CURLPROTO_HTTPS (1<<1)
Expand Down Expand Up @@ -1586,6 +1590,9 @@ typedef enum {
struct curl_slist kind */
CINIT(PROXYHEADER, OBJECTPOINT, 228),

/* Pass in a bitmask of "header options" */
CINIT(HEADEROPT, LONG, 229),

CURLOPT_LASTENTRY /* the last unused */
} CURLoption;

Expand Down
4 changes: 2 additions & 2 deletions lib/http.c
Expand Up @@ -200,7 +200,7 @@ char *Curl_checkProxyheaders(const struct connectdata *conn,
size_t thislen = strlen(thisheader);
struct SessionHandle *data = conn->data;

for(head = (conn->bits.proxy && data->set.proxyheaders)?
for(head = (conn->bits.proxy && data->set.sep_headers)?
data->set.proxyheaders:data->set.headers;
head; head=head->next) {
if(Curl_raw_nequal(head->data, thisheader, thislen))
Expand Down Expand Up @@ -1550,7 +1550,7 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
{
char *ptr;
struct curl_slist *headers=
(is_proxy && conn->data->set.proxyheaders)?
(is_proxy && conn->data->set.sep_headers)?
conn->data->set.proxyheaders:conn->data->set.headers;

while(headers) {
Expand Down
8 changes: 8 additions & 0 deletions lib/url.c
Expand Up @@ -1081,6 +1081,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
data->set.proxyheaders = va_arg(param, struct curl_slist *);
break;

case CURLOPT_HEADEROPT:
/*
* Set header option.
*/
arg = va_arg(param, long);
data->set.sep_headers = (arg & CURLHEADER_SEPARATE)? TRUE: FALSE;
break;

case CURLOPT_HTTP200ALIASES:
/*
* Set a list of aliases for HTTP 200 in response header
Expand Down
1 change: 1 addition & 0 deletions lib/urldata.h
Expand Up @@ -1467,6 +1467,7 @@ struct UserDefined {
struct curl_slist *headers; /* linked list of extra headers */
struct curl_slist *proxyheaders; /* linked list of extra CONNECT headers */
struct curl_httppost *httppost; /* linked list of POST data */
bool sep_headers; /* handle host and proxy headers separately */
bool cookiesession; /* new cookie session? */
bool crlf; /* convert crlf on ftp upload(?) */
struct curl_slist *quote; /* after connection is established */
Expand Down
2 changes: 1 addition & 1 deletion tests/data/test1525
Expand Up @@ -46,7 +46,7 @@ http-proxy
lib1525
</tool>
<name>
CURLOPT_PROXYHEADER: same headers for host and proxy
CURLOPT_PROXYHEADER is ignored CURLHEADER_UNIFIED
</name>
<command>
http://the.old.moo.1525:%HTTPPORT/1525 %HOSTIP:%PROXYPORT
Expand Down
3 changes: 2 additions & 1 deletion tests/libtest/lib1525.c
Expand Up @@ -71,7 +71,8 @@ int test(char *URL)
test_setopt(curl, CURLOPT_URL, URL);
test_setopt(curl, CURLOPT_PROXY, libtest_arg2);
test_setopt(curl, CURLOPT_HTTPHEADER, hhl);
test_setopt(curl, CURLOPT_PROXYHEADER, NULL);
test_setopt(curl, CURLOPT_PROXYHEADER, hhl);
test_setopt(curl, CURLOPT_HEADEROPT, CURLHEADER_UNIFIED);
test_setopt(curl, CURLOPT_POST, 0L);
test_setopt(curl, CURLOPT_UPLOAD, 1L);
test_setopt(curl, CURLOPT_VERBOSE, 1L);
Expand Down
1 change: 1 addition & 0 deletions tests/libtest/lib1526.c
Expand Up @@ -72,6 +72,7 @@ int test(char *URL)
test_setopt(curl, CURLOPT_PROXY, libtest_arg2);
test_setopt(curl, CURLOPT_HTTPHEADER, hhl);
test_setopt(curl, CURLOPT_PROXYHEADER, phl);
test_setopt(curl, CURLOPT_HEADEROPT, CURLHEADER_SEPARATE);
test_setopt(curl, CURLOPT_POST, 0L);
test_setopt(curl, CURLOPT_UPLOAD, 1L);
test_setopt(curl, CURLOPT_VERBOSE, 1L);
Expand Down

0 comments on commit ef6be35

Please sign in to comment.