mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
CURLOPT_PROXYHEADER: set headers for proxy-only
Includes docs and new test cases: 1525, 1526 and 1527 Co-written-by: Vijay Panghal
This commit is contained in:
parent
42937f87e6
commit
ac887eedbc
@ -1541,6 +1541,33 @@ 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!
|
||||
.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 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
|
||||
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.
|
||||
|
||||
Pass a NULL to this to reset back to no custom headers.
|
||||
|
||||
This option was added in libcurl 7.36.0.
|
||||
.IP CURLOPT_HTTP200ALIASES
|
||||
Pass a pointer to a linked list of aliases to be treated as valid HTTP 200
|
||||
responses. Some servers respond with a custom header response line. For
|
||||
|
@ -439,6 +439,7 @@ CURLOPT_PROGRESSFUNCTION 7.1 7.32.0
|
||||
CURLOPT_PROTOCOLS 7.19.4
|
||||
CURLOPT_PROXY 7.1
|
||||
CURLOPT_PROXYAUTH 7.10.7
|
||||
CURLOPT_PROXYHEADER 7.36.0
|
||||
CURLOPT_PROXYPASSWORD 7.19.1
|
||||
CURLOPT_PROXYPORT 7.1
|
||||
CURLOPT_PROXYTYPE 7.10
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -903,7 +903,8 @@ typedef enum {
|
||||
/* Set cookie in request: */
|
||||
CINIT(COOKIE, OBJECTPOINT, 22),
|
||||
|
||||
/* This points to a linked list of headers, struct curl_slist kind */
|
||||
/* This points to a linked list of headers, struct curl_slist kind. This
|
||||
list is also used for RTSP (in spite of its name) */
|
||||
CINIT(HTTPHEADER, OBJECTPOINT, 23),
|
||||
|
||||
/* This points to a linked list of post entries, struct curl_httppost */
|
||||
@ -1581,6 +1582,10 @@ typedef enum {
|
||||
* Expect: 100-continue header before sending the data anyway. */
|
||||
CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227),
|
||||
|
||||
/* This points to a linked list of headers used for proxy requests only,
|
||||
struct curl_slist kind */
|
||||
CINIT(PROXYHEADER, OBJECTPOINT, 228),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
|
80
lib/http.c
80
lib/http.c
@ -169,10 +169,12 @@ CURLcode Curl_http_setup_conn(struct connectdata *conn)
|
||||
*
|
||||
* Returns a pointer to the first matching header or NULL if none matched.
|
||||
*/
|
||||
char *Curl_checkheaders(struct SessionHandle *data, const char *thisheader)
|
||||
char *Curl_checkheaders(const struct connectdata *conn,
|
||||
const char *thisheader)
|
||||
{
|
||||
struct curl_slist *head;
|
||||
size_t thislen = strlen(thisheader);
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
for(head = data->set.headers;head; head=head->next) {
|
||||
if(Curl_raw_nequal(head->data, thisheader, thislen))
|
||||
@ -181,6 +183,32 @@ char *Curl_checkheaders(struct SessionHandle *data, const char *thisheader)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* checkProxyHeaders() checks the linked list of custom proxy headers
|
||||
* if proxy headers are not available, then it will lookup into http header
|
||||
* link list
|
||||
*
|
||||
* It takes a connectdata struct as input instead of the SessionHandle simply
|
||||
* to know if this is a proxy request or not, as it then might check a
|
||||
* different header list.
|
||||
*
|
||||
*/
|
||||
char *Curl_checkProxyheaders(const struct connectdata *conn,
|
||||
const char *thisheader)
|
||||
{
|
||||
struct curl_slist *head;
|
||||
size_t thislen = strlen(thisheader);
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
for(head = (conn->bits.proxy && data->set.proxyheaders)?
|
||||
data->set.proxyheaders:data->set.headers;
|
||||
head; head=head->next) {
|
||||
if(Curl_raw_nequal(head->data, thisheader, thislen))
|
||||
return head->data;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Strip off leading and trailing whitespace from the value in the
|
||||
* given HTTP header line and return a strdupped copy. Returns NULL in
|
||||
@ -584,9 +612,9 @@ output_auth_headers(struct connectdata *conn,
|
||||
if(authstatus->picked == CURLAUTH_BASIC) {
|
||||
/* Basic */
|
||||
if((proxy && conn->bits.proxy_user_passwd &&
|
||||
!Curl_checkheaders(data, "Proxy-authorization:")) ||
|
||||
!Curl_checkProxyheaders(conn, "Proxy-authorization:")) ||
|
||||
(!proxy && conn->bits.user_passwd &&
|
||||
!Curl_checkheaders(data, "Authorization:"))) {
|
||||
!Curl_checkheaders(conn, "Authorization:"))) {
|
||||
auth="Basic";
|
||||
result = http_output_basic(conn, proxy);
|
||||
if(result)
|
||||
@ -1501,7 +1529,7 @@ static CURLcode expect100(struct SessionHandle *data,
|
||||
/* if not doing HTTP 1.0 or disabled explicitly, we add a Expect:
|
||||
100-continue to the headers which actually speeds up post operations
|
||||
(as there is one packet coming back from the web server) */
|
||||
ptr = Curl_checkheaders(data, "Expect:");
|
||||
ptr = Curl_checkheaders(conn, "Expect:");
|
||||
if(ptr) {
|
||||
data->state.expect100header =
|
||||
Curl_compareheader(ptr, "Expect:", "100-continue");
|
||||
@ -1517,10 +1545,13 @@ static CURLcode expect100(struct SessionHandle *data,
|
||||
}
|
||||
|
||||
CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
bool is_proxy,
|
||||
Curl_send_buffer *req_buffer)
|
||||
{
|
||||
char *ptr;
|
||||
struct curl_slist *headers=conn->data->set.headers;
|
||||
struct curl_slist *headers=
|
||||
(is_proxy && conn->data->set.proxyheaders)?
|
||||
conn->data->set.proxyheaders:conn->data->set.headers;
|
||||
|
||||
while(headers) {
|
||||
ptr = strchr(headers->data, ':');
|
||||
@ -1736,7 +1767,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
it might have been used in the proxy connect, but if we have got a header
|
||||
with the user-agent string specified, we erase the previously made string
|
||||
here. */
|
||||
if(Curl_checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
|
||||
if(Curl_checkheaders(conn, "User-Agent:") && conn->allocptr.uagent) {
|
||||
free(conn->allocptr.uagent);
|
||||
conn->allocptr.uagent=NULL;
|
||||
}
|
||||
@ -1757,7 +1788,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
conn->bits.authneg = FALSE;
|
||||
|
||||
Curl_safefree(conn->allocptr.ref);
|
||||
if(data->change.referer && !Curl_checkheaders(data, "Referer:")) {
|
||||
if(data->change.referer && !Curl_checkheaders(conn, "Referer:")) {
|
||||
conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
|
||||
if(!conn->allocptr.ref)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@ -1765,10 +1796,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
else
|
||||
conn->allocptr.ref = NULL;
|
||||
|
||||
if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(data, "Cookie:"))
|
||||
if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie:"))
|
||||
addcookies = data->set.str[STRING_COOKIE];
|
||||
|
||||
if(!Curl_checkheaders(data, "Accept-Encoding:") &&
|
||||
if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
|
||||
data->set.str[STRING_ENCODING]) {
|
||||
Curl_safefree(conn->allocptr.accept_encoding);
|
||||
conn->allocptr.accept_encoding =
|
||||
@ -1780,13 +1811,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
#ifdef HAVE_LIBZ
|
||||
/* we only consider transfer-encoding magic if libz support is built-in */
|
||||
|
||||
if(!Curl_checkheaders(data, "TE:") && data->set.http_transfer_encoding) {
|
||||
if(!Curl_checkheaders(conn, "TE:") &&
|
||||
data->set.http_transfer_encoding) {
|
||||
/* When we are to insert a TE: header in the request, we must also insert
|
||||
TE in a Connection: header, so we need to merge the custom provided
|
||||
Connection: header and prevent the original to get sent. Note that if
|
||||
the user has inserted his/hers own TE: header we don't do this magic
|
||||
but then assume that the user will handle it all! */
|
||||
char *cptr = Curl_checkheaders(data, "Connection:");
|
||||
char *cptr = Curl_checkheaders(conn, "Connection:");
|
||||
#define TE_HEADER "TE: gzip\r\n"
|
||||
|
||||
Curl_safefree(conn->allocptr.te);
|
||||
@ -1804,7 +1836,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
/* In HTTP2 forbids Transfer-Encoding: chunked */
|
||||
ptr = NULL;
|
||||
else {
|
||||
ptr = Curl_checkheaders(data, "Transfer-Encoding:");
|
||||
ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
|
||||
if(ptr) {
|
||||
/* Some kind of TE is requested, check if 'chunked' is chosen */
|
||||
data->req.upload_chunky =
|
||||
@ -1838,7 +1870,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
|
||||
Curl_safefree(conn->allocptr.host);
|
||||
|
||||
ptr = Curl_checkheaders(data, "Host:");
|
||||
ptr = Curl_checkheaders(conn, "Host:");
|
||||
if(ptr && (!data->state.this_is_a_follow ||
|
||||
Curl_raw_equal(data->state.first_host, conn->host.name))) {
|
||||
#if !defined(CURL_DISABLE_COOKIES)
|
||||
@ -1983,13 +2015,13 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
/* we must build the whole post sequence first, so that we have a size of
|
||||
the whole transfer before we start to send it */
|
||||
result = Curl_getformdata(data, &http->sendit, data->set.httppost,
|
||||
Curl_checkheaders(data, "Content-Type:"),
|
||||
Curl_checkheaders(conn, "Content-Type:"),
|
||||
&http->postsize);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
http->p_accept = Curl_checkheaders(data, "Accept:")?NULL:"Accept: */*\r\n";
|
||||
http->p_accept = Curl_checkheaders(conn, "Accept:")?NULL:"Accept: */*\r\n";
|
||||
|
||||
if(( (HTTPREQ_POST == httpreq) ||
|
||||
(HTTPREQ_POST_FORM == httpreq) ||
|
||||
@ -2069,7 +2101,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
* ones if any such are specified.
|
||||
*/
|
||||
if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
|
||||
!Curl_checkheaders(data, "Range:")) {
|
||||
!Curl_checkheaders(conn, "Range:")) {
|
||||
/* if a line like this was already allocated, free the previous one */
|
||||
if(conn->allocptr.rangeline)
|
||||
free(conn->allocptr.rangeline);
|
||||
@ -2077,7 +2109,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
data->state.range);
|
||||
}
|
||||
else if((httpreq != HTTPREQ_GET) &&
|
||||
!Curl_checkheaders(data, "Content-Range:")) {
|
||||
!Curl_checkheaders(conn, "Content-Range:")) {
|
||||
|
||||
/* if a line like this was already allocated, free the previous one */
|
||||
if(conn->allocptr.rangeline)
|
||||
@ -2179,7 +2211,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
conn->allocptr.ref:"" /* Referer: <data> */,
|
||||
(conn->bits.httpproxy &&
|
||||
!conn->bits.tunnel_proxy &&
|
||||
!Curl_checkheaders(data, "Proxy-Connection:"))?
|
||||
!Curl_checkProxyheaders(conn, "Proxy-Connection:"))?
|
||||
"Proxy-Connection: Keep-Alive\r\n":"",
|
||||
te
|
||||
);
|
||||
@ -2264,7 +2296,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
}
|
||||
|
||||
result = Curl_add_custom_headers(conn, req_buffer);
|
||||
result = Curl_add_custom_headers(conn, FALSE, req_buffer);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -2314,7 +2346,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
http->sending = HTTPSEND_BODY;
|
||||
|
||||
if(!data->req.upload_chunky &&
|
||||
!Curl_checkheaders(data, "Content-Length:")) {
|
||||
!Curl_checkheaders(conn, "Content-Length:")) {
|
||||
/* only add Content-Length if not uploading chunked */
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T
|
||||
@ -2386,7 +2418,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
postsize = data->set.infilesize;
|
||||
|
||||
if((postsize != -1) && !data->req.upload_chunky &&
|
||||
!Curl_checkheaders(data, "Content-Length:")) {
|
||||
!Curl_checkheaders(conn, "Content-Length:")) {
|
||||
/* only add Content-Length if not uploading chunked */
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T
|
||||
@ -2438,7 +2470,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
we don't upload data chunked, as RFC2616 forbids us to set both
|
||||
kinds of headers (Transfer-Encoding: chunked and Content-Length) */
|
||||
if((postsize != -1) && !data->req.upload_chunky &&
|
||||
!Curl_checkheaders(data, "Content-Length:")) {
|
||||
!Curl_checkheaders(conn, "Content-Length:")) {
|
||||
/* we allow replacing this header if not during auth negotiation,
|
||||
although it isn't very wise to actually set your own */
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
@ -2448,7 +2480,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
}
|
||||
|
||||
if(!Curl_checkheaders(data, "Content-Type:")) {
|
||||
if(!Curl_checkheaders(conn, "Content-Type:")) {
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"Content-Type: application/"
|
||||
"x-www-form-urlencoded\r\n");
|
||||
@ -2460,7 +2492,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
the somewhat bigger ones we allow the app to disable it. Just make
|
||||
sure that the expect100header is always set to the preferred value
|
||||
here. */
|
||||
ptr = Curl_checkheaders(data, "Expect:");
|
||||
ptr = Curl_checkheaders(conn, "Expect:");
|
||||
if(ptr) {
|
||||
data->state.expect100header =
|
||||
Curl_compareheader(ptr, "Expect:", "100-continue");
|
||||
|
@ -39,9 +39,13 @@ extern const struct Curl_handler Curl_handler_https;
|
||||
bool Curl_compareheader(const char *headerline, /* line to check */
|
||||
const char *header, /* header keyword _with_ colon */
|
||||
const char *content); /* content string to find */
|
||||
char *Curl_checkheaders(struct SessionHandle *data, const char *thisheader);
|
||||
|
||||
char *Curl_checkheaders(const struct connectdata *conn,
|
||||
const char *thisheader);
|
||||
char *Curl_copy_header_value(const char *header);
|
||||
|
||||
char *Curl_checkProxyheaders(const struct connectdata *conn,
|
||||
const char *thisheader);
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/*
|
||||
* The add_buffer series of functions are used to build one large memory chunk
|
||||
@ -67,6 +71,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
|
||||
CURLcode Curl_add_timecondition(struct SessionHandle *data,
|
||||
Curl_send_buffer *buf);
|
||||
CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
bool is_connect,
|
||||
Curl_send_buffer *req_buffer);
|
||||
|
||||
/* protocol-specific functions set up to be called by the main engine */
|
||||
|
@ -165,7 +165,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(!Curl_checkheaders(data, "Host:")) {
|
||||
if(!Curl_checkProxyheaders(conn, "Host:")) {
|
||||
host = aprintf("Host: %s\r\n", hostheader);
|
||||
if(!host) {
|
||||
free(hostheader);
|
||||
@ -173,10 +173,10 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
if(!Curl_checkheaders(data, "Proxy-Connection:"))
|
||||
if(!Curl_checkProxyheaders(conn, "Proxy-Connection:"))
|
||||
proxyconn = "Proxy-Connection: Keep-Alive\r\n";
|
||||
|
||||
if(!Curl_checkheaders(data, "User-Agent:") &&
|
||||
if(!Curl_checkProxyheaders(conn, "User-Agent:") &&
|
||||
data->set.str[STRING_USERAGENT])
|
||||
useragent = conn->allocptr.uagent;
|
||||
|
||||
@ -200,7 +200,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
free(hostheader);
|
||||
|
||||
if(CURLE_OK == result)
|
||||
result = Curl_add_custom_headers(conn, req_buffer);
|
||||
result = Curl_add_custom_headers(conn, TRUE, req_buffer);
|
||||
|
||||
if(CURLE_OK == result)
|
||||
/* CRLF terminate the request */
|
||||
|
26
lib/rtsp.c
26
lib/rtsp.c
@ -341,7 +341,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
/* Transport Header for SETUP requests */
|
||||
p_transport = Curl_checkheaders(data, "Transport:");
|
||||
p_transport = Curl_checkheaders(conn, "Transport:");
|
||||
if(rtspreq == RTSPREQ_SETUP && !p_transport) {
|
||||
/* New Transport: setting? */
|
||||
if(data->set.str[STRING_RTSP_TRANSPORT]) {
|
||||
@ -365,11 +365,11 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
/* Accept Headers for DESCRIBE requests */
|
||||
if(rtspreq == RTSPREQ_DESCRIBE) {
|
||||
/* Accept Header */
|
||||
p_accept = Curl_checkheaders(data, "Accept:")?
|
||||
p_accept = Curl_checkheaders(conn, "Accept:")?
|
||||
NULL:"Accept: application/sdp\r\n";
|
||||
|
||||
/* Accept-Encoding header */
|
||||
if(!Curl_checkheaders(data, "Accept-Encoding:") &&
|
||||
if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
|
||||
data->set.str[STRING_ENCODING]) {
|
||||
Curl_safefree(conn->allocptr.accept_encoding);
|
||||
conn->allocptr.accept_encoding =
|
||||
@ -386,18 +386,18 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
it might have been used in the proxy connect, but if we have got a header
|
||||
with the user-agent string specified, we erase the previously made string
|
||||
here. */
|
||||
if(Curl_checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
|
||||
if(Curl_checkheaders(conn, "User-Agent:") && conn->allocptr.uagent) {
|
||||
Curl_safefree(conn->allocptr.uagent);
|
||||
conn->allocptr.uagent = NULL;
|
||||
}
|
||||
else if(!Curl_checkheaders(data, "User-Agent:") &&
|
||||
else if(!Curl_checkheaders(conn, "User-Agent:") &&
|
||||
data->set.str[STRING_USERAGENT]) {
|
||||
p_uagent = conn->allocptr.uagent;
|
||||
}
|
||||
|
||||
/* Referrer */
|
||||
Curl_safefree(conn->allocptr.ref);
|
||||
if(data->change.referer && !Curl_checkheaders(data, "Referer:"))
|
||||
if(data->change.referer && !Curl_checkheaders(conn, "Referer:"))
|
||||
conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
|
||||
else
|
||||
conn->allocptr.ref = NULL;
|
||||
@ -414,7 +414,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
(rtspreq & (RTSPREQ_PLAY | RTSPREQ_PAUSE | RTSPREQ_RECORD))) {
|
||||
|
||||
/* Check to see if there is a range set in the custom headers */
|
||||
if(!Curl_checkheaders(data, "Range:") && data->state.range) {
|
||||
if(!Curl_checkheaders(conn, "Range:") && data->state.range) {
|
||||
Curl_safefree(conn->allocptr.rangeline);
|
||||
conn->allocptr.rangeline = aprintf("Range: %s\r\n", data->state.range);
|
||||
p_range = conn->allocptr.rangeline;
|
||||
@ -424,11 +424,11 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
/*
|
||||
* Sanity check the custom headers
|
||||
*/
|
||||
if(Curl_checkheaders(data, "CSeq:")) {
|
||||
if(Curl_checkheaders(conn, "CSeq:")) {
|
||||
failf(data, "CSeq cannot be set as a custom header.");
|
||||
return CURLE_RTSP_CSEQ_ERROR;
|
||||
}
|
||||
if(Curl_checkheaders(data, "Session:")) {
|
||||
if(Curl_checkheaders(conn, "Session:")) {
|
||||
failf(data, "Session ID cannot be set as a custom header.");
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
@ -484,7 +484,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
}
|
||||
|
||||
result = Curl_add_custom_headers(conn, req_buffer);
|
||||
result = Curl_add_custom_headers(conn, FALSE, req_buffer);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -507,7 +507,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
if(putsize > 0 || postsize > 0) {
|
||||
/* As stated in the http comments, it is probably not wise to
|
||||
* actually set a custom Content-Length in the headers */
|
||||
if(!Curl_checkheaders(data, "Content-Length:")) {
|
||||
if(!Curl_checkheaders(conn, "Content-Length:")) {
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
|
||||
(data->set.upload ? putsize : postsize));
|
||||
@ -517,7 +517,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
|
||||
if(rtspreq == RTSPREQ_SET_PARAMETER ||
|
||||
rtspreq == RTSPREQ_GET_PARAMETER) {
|
||||
if(!Curl_checkheaders(data, "Content-Type:")) {
|
||||
if(!Curl_checkheaders(conn, "Content-Type:")) {
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"Content-Type: text/parameters\r\n");
|
||||
if(result)
|
||||
@ -526,7 +526,7 @@ static CURLcode rtsp_do(struct connectdata *conn, bool *done)
|
||||
}
|
||||
|
||||
if(rtspreq == RTSPREQ_ANNOUNCE) {
|
||||
if(!Curl_checkheaders(data, "Content-Type:")) {
|
||||
if(!Curl_checkheaders(conn, "Content-Type:")) {
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"Content-Type: application/sdp\r\n");
|
||||
if(result)
|
||||
|
14
lib/url.c
14
lib/url.c
@ -1067,6 +1067,20 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
data->set.headers = va_arg(param, struct curl_slist *);
|
||||
break;
|
||||
|
||||
case CURLOPT_PROXYHEADER:
|
||||
/*
|
||||
* Set a list with proxy headers to use (or replace internals with)
|
||||
*
|
||||
* Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a
|
||||
* long time we remain doing it this way until CURLOPT_PROXYHEADER is
|
||||
* used. As soon as this option has been used, if set to anything but
|
||||
* NULL, custom headers for proxies are only picked from this list.
|
||||
*
|
||||
* Set this option to NULL to restore the previous behavior.
|
||||
*/
|
||||
data->set.proxyheaders = va_arg(param, struct curl_slist *);
|
||||
break;
|
||||
|
||||
case CURLOPT_HTTP200ALIASES:
|
||||
/*
|
||||
* Set a list of aliases for HTTP 200 in response header
|
||||
|
@ -1465,6 +1465,7 @@ struct UserDefined {
|
||||
download */
|
||||
curl_off_t set_resume_from; /* continue [ftp] transfer from here */
|
||||
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 cookiesession; /* new cookie session? */
|
||||
bool crlf; /* convert crlf on ftp upload(?) */
|
||||
|
@ -127,6 +127,8 @@ test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
|
||||
test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \
|
||||
test1516 \
|
||||
\
|
||||
test1525 test1526 test1527 \
|
||||
\
|
||||
test1900 test1901 test1902 test1903 \
|
||||
\
|
||||
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
|
||||
|
76
tests/data/test1525
Normal file
76
tests/data/test1525
Normal file
@ -0,0 +1,76 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
HTTP
|
||||
HTTP GET
|
||||
HTTP CONNECT
|
||||
HTTP proxy
|
||||
proxytunnel
|
||||
CURLOPT_PROXYHEADER
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
# Server-side
|
||||
<reply>
|
||||
<connect>
|
||||
HTTP/1.1 200 OK
|
||||
Content-Length: 17
|
||||
|
||||
</connect>
|
||||
<data>
|
||||
HTTP/1.1 200 OK swsclose
|
||||
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||
Server: test-server/fake
|
||||
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||
ETag: "21025-dc7-39462498"
|
||||
</data>
|
||||
<datacheck>
|
||||
HTTP/1.1 200 OK
|
||||
Content-Length: 17
|
||||
|
||||
HTTP/1.1 200 OK swsclose
|
||||
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||
Server: test-server/fake
|
||||
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||
ETag: "21025-dc7-39462498"
|
||||
</datacheck>
|
||||
|
||||
</reply>
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
http
|
||||
http-proxy
|
||||
</server>
|
||||
<tool>
|
||||
lib1525
|
||||
</tool>
|
||||
<name>
|
||||
CURLOPT_PROXYHEADER: same headers for host and proxy
|
||||
</name>
|
||||
<command>
|
||||
http://the.old.moo.1525:%HTTPPORT/1525 %HOSTIP:%PROXYPORT
|
||||
</command>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<proxy>
|
||||
CONNECT the.old.moo.1525:%HTTPPORT HTTP/1.1
|
||||
Host: the.old.moo.1525:%HTTPPORT
|
||||
Proxy-Connection: Keep-Alive
|
||||
User-Agent: Http Agent
|
||||
|
||||
</proxy>
|
||||
<protocol>
|
||||
PUT /1525 HTTP/1.1
|
||||
Host: the.old.moo.1525:%HTTPPORT
|
||||
Accept: */*
|
||||
User-Agent: Http Agent
|
||||
Content-Length: 13
|
||||
Expect: 100-continue
|
||||
|
||||
Hello Cloud!
|
||||
</protocol>
|
||||
</verify>
|
||||
</testcase>
|
76
tests/data/test1526
Normal file
76
tests/data/test1526
Normal file
@ -0,0 +1,76 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
HTTP
|
||||
HTTP GET
|
||||
HTTP CONNECT
|
||||
HTTP proxy
|
||||
proxytunnel
|
||||
CURLOPT_PROXYHEADER
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
# Server-side
|
||||
<reply>
|
||||
<connect>
|
||||
HTTP/1.1 200 OK
|
||||
Server: present
|
||||
|
||||
</connect>
|
||||
<data>
|
||||
HTTP/1.1 200 OK swsclose
|
||||
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||
Server: test-server/fake
|
||||
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||
ETag: "21025-dc7-39462498"
|
||||
</data>
|
||||
<datacheck>
|
||||
HTTP/1.1 200 OK
|
||||
Server: present
|
||||
|
||||
HTTP/1.1 200 OK swsclose
|
||||
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||
Server: test-server/fake
|
||||
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||
ETag: "21025-dc7-39462498"
|
||||
</datacheck>
|
||||
</reply>
|
||||
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
http
|
||||
http-proxy
|
||||
</server>
|
||||
<tool>
|
||||
lib1526
|
||||
</tool>
|
||||
<name>
|
||||
CURLOPT_PROXYHEADER: separate host/proxy headers
|
||||
</name>
|
||||
<command>
|
||||
http://the.old.moo.1526:%HTTPPORT/1526 %HOSTIP:%PROXYPORT
|
||||
</command>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<proxy>
|
||||
CONNECT the.old.moo.1526:%HTTPPORT HTTP/1.1
|
||||
Host: the.old.moo.1526:%HTTPPORT
|
||||
Proxy-Connection: Keep-Alive
|
||||
User-Agent: Proxy Agent
|
||||
|
||||
</proxy>
|
||||
<protocol>
|
||||
PUT /1526 HTTP/1.1
|
||||
Host: the.old.moo.1526:%HTTPPORT
|
||||
Accept: */*
|
||||
User-Agent: Http Agent
|
||||
Content-Length: 13
|
||||
Expect: 100-continue
|
||||
|
||||
Hello Cloud!
|
||||
</protocol>
|
||||
</verify>
|
||||
</testcase>
|
76
tests/data/test1527
Normal file
76
tests/data/test1527
Normal file
@ -0,0 +1,76 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
HTTP
|
||||
HTTP GET
|
||||
HTTP CONNECT
|
||||
HTTP proxy
|
||||
proxytunnel
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
# Server-side
|
||||
<reply>
|
||||
<connect>
|
||||
HTTP/1.1 200 OK
|
||||
We-are: good
|
||||
|
||||
</connect>
|
||||
<data>
|
||||
HTTP/1.1 200 OK swsclose
|
||||
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||
Server: test-server/fake
|
||||
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||
ETag: "21025-dc7-39462498"
|
||||
</data>
|
||||
<datacheck>
|
||||
HTTP/1.1 200 OK
|
||||
We-are: good
|
||||
|
||||
HTTP/1.1 200 OK swsclose
|
||||
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||
Server: test-server/fake
|
||||
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||
ETag: "21025-dc7-39462498"
|
||||
</datacheck>
|
||||
|
||||
</reply>
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
http
|
||||
http-proxy
|
||||
</server>
|
||||
<tool>
|
||||
lib1527
|
||||
</tool>
|
||||
<name>
|
||||
Check same headers are generated without CURLOPT_PROXYHEADER
|
||||
</name>
|
||||
<command>
|
||||
http://the.old.moo.1527:%HTTPPORT/1527 %HOSTIP:%PROXYPORT
|
||||
</command>
|
||||
</client>
|
||||
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<proxy>
|
||||
CONNECT the.old.moo.1527:%HTTPPORT HTTP/1.1
|
||||
Host: the.old.moo.1527:%HTTPPORT
|
||||
Proxy-Connection: Keep-Alive
|
||||
User-Agent: Http Agent
|
||||
Expect: 100-continue
|
||||
|
||||
</proxy>
|
||||
<protocol>
|
||||
PUT /1527 HTTP/1.1
|
||||
Host: the.old.moo.1527:%HTTPPORT
|
||||
Accept: */*
|
||||
User-Agent: Http Agent
|
||||
Expect: 100-continue
|
||||
Content-Length: 13
|
||||
|
||||
Hello Cloud!
|
||||
</protocol>
|
||||
</verify>
|
||||
</testcase>
|
@ -22,6 +22,8 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \
|
||||
lib583 lib585 lib586 lib587 lib590 lib591 lib597 lib598 lib599 \
|
||||
lib1500 lib1501 lib1502 lib1503 lib1504 lib1505 lib1506 lib1507 lib1508 \
|
||||
lib1509 lib1510 lib1511 lib1512 lib1513 lib1514 lib1515 \
|
||||
lib1509 lib1510 lib1511 lib1512 lib1513 lib1514 lib1515 \
|
||||
lib1525 lib1526 lib1527 \
|
||||
lib1900 \
|
||||
lib2033
|
||||
|
||||
@ -353,7 +355,19 @@ lib1514_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1514
|
||||
|
||||
lib1515_SOURCES = lib1515.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
|
||||
lib1515_LDADD = $(TESTUTIL_LIBS)
|
||||
lib1515_CPPFLAGS = $(AM_CPPFLAGS)
|
||||
lib1515_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1515
|
||||
|
||||
lib1525_SOURCES = lib1525.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
|
||||
lib1525_LDADD = $(TESTUTIL_LIBS)
|
||||
lib1525_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1525
|
||||
|
||||
lib1526_SOURCES = lib1526.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
|
||||
lib1526_LDADD = $(TESTUTIL_LIBS)
|
||||
lib1526_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1526
|
||||
|
||||
lib1527_SOURCES = lib1527.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
|
||||
lib1527_LDADD = $(TESTUTIL_LIBS)
|
||||
lib1527_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1527
|
||||
|
||||
lib1900_SOURCES = lib1900.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
|
||||
lib1900_LDADD = $(TESTUTIL_LIBS)
|
||||
|
96
tests/libtest/lib1525.c
Normal file
96
tests/libtest/lib1525.c
Normal file
@ -0,0 +1,96 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2014, Vijay Panghal, <vpanghal@maginatics.com>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* This unit test PUT http data over proxy. Proxy header will be different
|
||||
* from server http header
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include "memdebug.h"
|
||||
|
||||
static char data [] = "Hello Cloud!\n";
|
||||
|
||||
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
size_t amount = nmemb * size; /* Total bytes curl wants */
|
||||
if (amount < strlen(data)) {
|
||||
return strlen(data);
|
||||
}
|
||||
(void)stream;
|
||||
memcpy(ptr, data, strlen(data));
|
||||
return strlen(data);
|
||||
}
|
||||
|
||||
|
||||
int test(char *URL)
|
||||
{
|
||||
CURL *curl = NULL;
|
||||
CURLcode res = CURLE_FAILED_INIT;
|
||||
/* http and proxy header list*/
|
||||
struct curl_slist *hhl = NULL;
|
||||
|
||||
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||
fprintf(stderr, "curl_global_init() failed\n");
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if((curl = curl_easy_init()) == NULL) {
|
||||
fprintf(stderr, "curl_easy_init() failed\n");
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
hhl = curl_slist_append(hhl, "User-Agent: Http Agent");
|
||||
|
||||
if (!hhl) {
|
||||
goto test_cleanup;
|
||||
}
|
||||
|
||||
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_POST, 0L);
|
||||
test_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
test_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
test_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
test_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
test_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
|
||||
test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
test_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L);
|
||||
test_setopt(curl, CURLOPT_INFILESIZE, strlen(data));
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
test_cleanup:
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
curl_slist_free_all(hhl);
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
99
tests/libtest/lib1526.c
Normal file
99
tests/libtest/lib1526.c
Normal file
@ -0,0 +1,99 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Vijay Panghal, <vpanghal@maginatics.com>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* This unit test PUT http data over proxy. Proxy header will be different
|
||||
* from server http header
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include "memdebug.h"
|
||||
|
||||
static char data [] = "Hello Cloud!\n";
|
||||
|
||||
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
size_t amount = nmemb * size; /* Total bytes curl wants */
|
||||
if (amount < strlen(data)) {
|
||||
return strlen(data);
|
||||
}
|
||||
(void)stream;
|
||||
memcpy(ptr, data, strlen(data));
|
||||
return strlen(data);
|
||||
}
|
||||
|
||||
int test(char *URL)
|
||||
{
|
||||
CURL *curl = NULL;
|
||||
CURLcode res = CURLE_FAILED_INIT;
|
||||
/* http and proxy header list*/
|
||||
struct curl_slist *hhl = NULL, *phl = NULL;
|
||||
|
||||
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||
fprintf(stderr, "curl_global_init() failed\n");
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if((curl = curl_easy_init()) == NULL) {
|
||||
fprintf(stderr, "curl_easy_init() failed\n");
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
hhl = curl_slist_append(hhl, "User-Agent: Http Agent");
|
||||
phl = curl_slist_append(phl, "User-Agent: Proxy Agent");
|
||||
phl = curl_slist_append(phl, "Expect:");
|
||||
|
||||
if (!hhl || !phl) {
|
||||
goto test_cleanup;
|
||||
}
|
||||
|
||||
test_setopt(curl, CURLOPT_URL, URL);
|
||||
test_setopt(curl, CURLOPT_PROXY, libtest_arg2);
|
||||
test_setopt(curl, CURLOPT_HTTPHEADER, hhl);
|
||||
test_setopt(curl, CURLOPT_PROXYHEADER, phl);
|
||||
test_setopt(curl, CURLOPT_POST, 0L);
|
||||
test_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
test_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
test_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
test_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
test_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
|
||||
test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
test_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L);
|
||||
test_setopt(curl, CURLOPT_INFILESIZE, strlen(data));
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
test_cleanup:
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
curl_slist_free_all(hhl);
|
||||
|
||||
curl_slist_free_all(phl);
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
|
95
tests/libtest/lib1527.c
Normal file
95
tests/libtest/lib1527.c
Normal file
@ -0,0 +1,95 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Vijay Panghal, <vpanghal@maginatics.com>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* This unit test PUT http data over proxy. Same http header will be generated
|
||||
* for server and proxy
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include "memdebug.h"
|
||||
|
||||
static char data [] = "Hello Cloud!\n";
|
||||
|
||||
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
size_t amount = nmemb * size; /* Total bytes curl wants */
|
||||
if (amount < strlen(data)) {
|
||||
return strlen(data);
|
||||
}
|
||||
(void)stream;
|
||||
memcpy(ptr, data, strlen(data));
|
||||
return strlen(data);
|
||||
}
|
||||
|
||||
|
||||
int test(char *URL)
|
||||
{
|
||||
CURL *curl = NULL;
|
||||
CURLcode res = CURLE_FAILED_INIT;
|
||||
/* http header list*/
|
||||
struct curl_slist *hhl = NULL;
|
||||
|
||||
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||
fprintf(stderr, "curl_global_init() failed\n");
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if((curl = curl_easy_init()) == NULL) {
|
||||
fprintf(stderr, "curl_easy_init() failed\n");
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
hhl = curl_slist_append(hhl, "User-Agent: Http Agent");
|
||||
hhl = curl_slist_append(hhl, "Expect: 100-continue");
|
||||
|
||||
if (!hhl) {
|
||||
goto test_cleanup;
|
||||
}
|
||||
|
||||
test_setopt(curl, CURLOPT_URL, URL);
|
||||
test_setopt(curl, CURLOPT_PROXY, libtest_arg2);
|
||||
test_setopt(curl, CURLOPT_HTTPHEADER, hhl);
|
||||
test_setopt(curl, CURLOPT_POST, 0L);
|
||||
test_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
test_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
test_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
test_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
test_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
|
||||
test_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
test_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L);
|
||||
test_setopt(curl, CURLOPT_INFILESIZE, strlen(data));
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
test_cleanup:
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
curl_slist_free_all(hhl);
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
Loading…
Reference in New Issue
Block a user