CURLOPT_HEADEROPT: added

Modified the logic so that CURLOPT_HEADEROPT now controls if PROXYHEADER
is actually used or not.
This commit is contained in:
Daniel Stenberg 2014-02-04 23:37:29 +01:00
parent ac887eedbc
commit ef6be35bae
9 changed files with 59 additions and 28 deletions

View File

@ -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
@ -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.

View File

@ -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

View File

@ -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)
@ -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;

View File

@ -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))
@ -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) {

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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);

View File

@ -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);