service-name.d show-error.d silent.d socks4a.d socks4.d socks5.d \
socks5-gssapi-nec.d socks5-gssapi-service.d socks5-hostname.d \
speed-limit.d speed-time.d ssl-allow-beast.d ssl.d ssl-no-revoke.d \
- ssl-reqd.d sslv2.d sslv3.d stderr.d tcp-fastopen.d tcp-nodelay.d \
+ ssl-reqd.d sslv2.d sslv3.d stderr.d suppress-connect-headers.d \
+ tcp-fastopen.d tcp-nodelay.d \
telnet-option.d tftp-blksize.d tftp-no-options.d time-cond.d \
tls-max.d \
tlsauthtype.d tlspassword.d tlsuser.d tlsv1.0.d tlsv1.1.d tlsv1.2.d \
HTTP-like operations. The tunnel approach is made with the HTTP proxy CONNECT
request and requires that the proxy allows direct connect to the remote port
number curl wants to tunnel through to.
+
+To suppress proxy CONNECT response headers when curl is set to output headers
+use --suppress-connect-headers.
--- /dev/null
+Long: suppress-connect-headers
+Help: Suppress proxy CONNECT response headers
+See-also: dump-header include proxytunnel
+---
+When --proxytunnel is used and a CONNECT request is made don't output proxy
+CONNECT response headers. This option is meant to be used with --dump-header or
+--include which are used to show protocol headers in the output. It has no
+effect on debug options such as --verbose or --trace, or any statistics.
Callback for wildcard matching. See \fICURLOPT_FNMATCH_FUNCTION(3)\fP
.IP CURLOPT_FNMATCH_DATA
Data pointer to pass to the wildcard matching callback. See \fICURLOPT_FNMATCH_DATA(3)\fP
+.IP CURLOPT_SUPPRESS_CONNECT_HEADERS
+Suppress proxy CONNECT response headers from user callbacks. See \fICURLOPT_SUPPRESS_CONNECT_HEADERS(3)\fP
.SH ERROR OPTIONS
.IP CURLOPT_ERRORBUFFER
Error message buffer. See \fICURLOPT_ERRORBUFFER(3)\fP
.SH DESCRIPTION
Pass a pointer to a long to receive the total size of all the headers
received. Measured in number of bytes.
+
+The total includes the size of any received headers suppressed by
+\fICURLOPT_SUPPRESS_CONNECT_HEADERS(3)\fP.
.SH PROTOCOLS
All
.SH EXAMPLE
When using this, it only makes sense to use \fICURLOPT_PROXYTYPE(3)\fP set to
a HTTP proxy.
+
+To suppress proxy CONNECT response headers from user callbacks use
+\fICURLOPT_SUPPRESS_CONNECT_HEADERS(3)\fP.
.SH DEFAULT
0
.SH PROTOCOLS
--- /dev/null
+.\" **************************************************************************
+.\" * _ _ ____ _
+.\" * Project ___| | | | _ \| |
+.\" * / __| | | | |_) | |
+.\" * | (__| |_| | _ <| |___
+.\" * \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2017, 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
+.\" * are also available at https://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.
+.\" *
+.\" **************************************************************************
+.\"
+.TH CURLOPT_SUPPRESS_CONNECT_HEADERS 3 "13 February 2017" "libcurl 7.54.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_SUPPRESS_CONNECT_HEADERS \- Suppress proxy CONNECT response headers from user callbacks
+.SH SYNOPSIS
+.nf
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SUPPRESS_CONNECT_HEADERS, long onoff);
+.fi
+.SH DESCRIPTION
+When \fICURLOPT_HTTPPROXYTUNNEL(3)\fP is used and a CONNECT request is made,
+suppress proxy CONNECT response headers from the user callback functions
+\fICURLOPT_HEADERFUNCTION(3)\fP and \fICURLOPT_WRITEFUNCTION(3)\fP.
+
+Proxy CONNECT response headers can complicate header processing since it's
+essentially a separate set of headers. You can enable this option to suppress
+those headers.
+
+For example let's assume an HTTPS URL is to be retrieved via CONNECT. On
+success there would normally be two sets of headers, and each header line sent
+to the header function and/or the write function. The data given to the
+callbacks would look like this:
+
+.nf
+HTTP/1.1 200 Connection established
+{headers}...
+
+HTTP/1.1 200 OK
+Content-Type: application/json
+{headers}...
+
+{body}...
+.fi
+
+However by enabling this option the CONNECT response headers are suppressed, so
+the data given to the callbacks would look like this:
+
+.nf
+HTTP/1.1 200 OK
+Content-Type: application/json
+{headers}...
+
+{body}...
+.fi
+
+.SH DEFAULT
+0
+.SH PROTOCOLS
+All
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+if(curl) {
+ curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
+
+ curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
+ curl_easy_setopt(curl, CURLOPT_PROXY, "http://foo:3128");
+ curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L);
+ curl_easy_setopt(curl, CURLOPT_SUPPRESS_CONNECT_HEADERS, 1L);
+
+ curl_easy_perform(curl);
+
+ /* always cleanup */
+ curl_easy_cleanup(curl);
+}
+.fi
+.SH AVAILABILITY
+Added in 7.54.0
+.SH RETURN VALUE
+CURLE_OK or an error such as CURLE_UNKNOWN_OPTION.
+.SH "SEE ALSO"
+.BR CURLOPT_HEADER "(3), " CURLOPT_PROXY "(3), "
+.BR CURLOPT_HTTPPROXYTUNNEL "(3), "
CURLOPT_STREAM_DEPENDS.3 \
CURLOPT_STREAM_DEPENDS_E.3 \
CURLOPT_STREAM_WEIGHT.3 \
+ CURLOPT_SUPPRESS_CONNECT_HEADERS.3 \
CURLOPT_TCP_FASTOPEN.3 \
CURLOPT_TCP_KEEPALIVE.3 \
CURLOPT_TCP_KEEPIDLE.3 \
CURLOPT_STREAM_DEPENDS 7.46.0
CURLOPT_STREAM_DEPENDS_E 7.46.0
CURLOPT_STREAM_WEIGHT 7.46.0
+CURLOPT_SUPPRESS_CONNECT_HEADERS 7.54.0
CURLOPT_TCP_KEEPALIVE 7.25.0
CURLOPT_TCP_KEEPIDLE 7.25.0
CURLOPT_TCP_KEEPINTVL 7.25.0
/* Path to an abstract Unix domain socket */
CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264),
+ /* Suppress proxy CONNECT response headers from user callbacks */
+ CINIT(SUPPRESS_CONNECT_HEADERS, LONG, 265),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
perline = 0;
while(nread < BUFSIZE && keepon && !error) {
- int writetype;
-
if(Curl_pgrsUpdate(conn))
return CURLE_ABORTED_BY_CALLBACK;
Curl_debug(data, CURLINFO_HEADER_IN,
line_start, (size_t)perline, conn);
- /* send the header to the callback */
- writetype = CLIENTWRITE_HEADER;
- if(data->set.include_header)
- writetype |= CLIENTWRITE_BODY;
+ if(!data->set.suppress_connect_headers) {
+ /* send the header to the callback */
+ int writetype = CLIENTWRITE_HEADER;
+ if(data->set.include_header)
+ writetype |= CLIENTWRITE_BODY;
- result = Curl_client_write(conn, writetype, line_start, perline);
+ result = Curl_client_write(conn, writetype, line_start, perline);
+ if(result)
+ return result;
+ }
data->info.header_size += (long)perline;
data->req.headerbytecount += (long)perline;
- if(result)
- return result;
-
/* Newlines are CRLF, so the CR is ignored as the line isn't
really terminated until the LF comes. Treat a following CR
as end-of-headers as well.*/
case CURLOPT_CONNECT_TO:
data->set.connect_to = va_arg(param, struct curl_slist *);
break;
+ case CURLOPT_SUPPRESS_CONNECT_HEADERS:
+ data->set.suppress_connect_headers = (0 != va_arg(param, long))?TRUE:FALSE;
+ break;
default:
/* unknown tag and its companion, just ignore: */
result = CURLE_UNKNOWN_OPTION;
bool pipewait; /* wait for pipe/multiplex status before starting a
new connection */
long expect_100_timeout; /* in milliseconds */
+ bool suppress_connect_headers; /* suppress proxy CONNECT response headers
+ from user callbacks */
struct Curl_easy *stream_depends_on;
bool stream_depends_e; /* set or don't set the Exclusive bit */
d c 10263
d CURLOPT_ABSTRACT_UNIX_SOCKET...
d c 10264
+ d CURLOPT_SUPPRESS_CONNECT_HEADERS...
+ d c 00265
*
/if not defined(CURL_NO_OLDIES)
d CURLOPT_FILE c 10001
bool falsestart;
bool path_as_is;
double expect100timeout;
+ bool suppress_connect_headers; /* suppress proxy CONNECT response headers
+ from user callbacks */
struct GlobalConfig *global;
struct OperationConfig *prev;
struct OperationConfig *next; /* Always last in the struct */
{"$U", "connect-to", TRUE},
{"$W", "abstract-unix-socket", TRUE},
{"$X", "tls-max", TRUE},
+ {"$Y", "suppress-connect-headers", FALSE},
{"0", "http1.0", FALSE},
{"01", "http1.1", FALSE},
{"02", "http2", FALSE},
if(err)
return err;
break;
+ case 'Y': /* --suppress-connect-headers */
+ config->suppress_connect_headers = toggle;
+ break;
}
break;
case '#': /* --progress-bar */
" --ssl-allow-beast Allow security flaw to improve interop (SSL)",
" --ssl-no-revoke Disable cert revocation checks (WinSSL)",
" --stderr FILE Where to redirect stderr (use \"-\" for stdout)",
+ " --suppress-connect-headers Suppress proxy CONNECT response headers",
" --tcp-nodelay Use the TCP_NODELAY option",
" --tcp-fastopen Use TCP Fast Open",
" -t, --telnet-option OPT=VAL Set telnet option",
/* new in libcurl 7.19.4 */
my_setopt_str(curl, CURLOPT_NOPROXY, config->noproxy);
+
+ my_setopt(curl, CURLOPT_SUPPRESS_CONNECT_HEADERS,
+ config->suppress_connect_headers?1L:0L);
}
-#endif
+#endif /* !CURL_DISABLE_PROXY */
my_setopt(curl, CURLOPT_FAILONERROR, config->failonerror?1L:0L);
my_setopt(curl, CURLOPT_UPLOAD, uploadfile?1L:0L);
test1260 \
\
test1280 test1281 test1282 test1283 test1284 test1285 test1286 test1287 \
+test1288 \
\
test1300 test1301 test1302 test1303 test1304 test1305 test1306 test1307 \
test1308 test1309 test1310 test1311 test1312 test1313 test1314 test1315 \
--- /dev/null
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+HTTP CONNECT
+HTTP proxy
+proxytunnel
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<connect>
+HTTP/1.1 200 Mighty fine indeed\r
+Server: test tunnel 2000\r
+\r
+</connect>
+
+<data nocheck="yes">
+HTTP/1.1 200 OK\r
+Date: Thu, 09 Nov 2010 14:49:00 GMT\r
+Server: test-server/fake\r
+Content-Type: text/html\r
+Funny-head: yesyes\r
+Content-Length: 9\r
+Connection: keep-alive\r
+\r
+contents
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+http-proxy
+</server>
+<name>
+Suppress proxy CONNECT response headers
+</name>
+<command>
+--proxytunnel --suppress-connect-headers --dump-header - --include --write-out "\nCONNECT CODE: %{http_connect}\nRECEIVED HEADER BYTE TOTAL: %{size_header}\n" --proxy %HOSTIP:%PROXYPORT http://%HOSTIP.1288:%HTTPPORT/we/want/that/page/1288
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<proxy>
+CONNECT %HOSTIP.1288:%HTTPPORT HTTP/1.1\r
+Host: %HOSTIP.1288:%HTTPPORT\r
+Proxy-Connection: Keep-Alive\r
+\r
+</proxy>
+<protocol>
+GET /we/want/that/page/1288 HTTP/1.1\r
+Host: %HOSTIP.1288:%HTTPPORT\r
+Accept: */*\r
+\r
+</protocol>
+
+# This test is structured to test all the expectations of
+# --suppress-connect-headers, which are:
+# Must suppress in --include and --dump-header
+# Must not suppress in --verbose and --trace
+# Must not suppress in statistics (eg received header byte total)
+<stdout>
+HTTP/1.1 200 OK\r
+HTTP/1.1 200 OK\r
+Date: Thu, 09 Nov 2010 14:49:00 GMT\r
+Date: Thu, 09 Nov 2010 14:49:00 GMT\r
+Server: test-server/fake\r
+Server: test-server/fake\r
+Content-Type: text/html\r
+Content-Type: text/html\r
+Funny-head: yesyes\r
+Funny-head: yesyes\r
+Content-Length: 9\r
+Content-Length: 9\r
+Connection: keep-alive\r
+Connection: keep-alive\r
+\r
+\r
+contents
+
+CONNECT CODE: 200
+RECEIVED HEADER BYTE TOTAL: 231
+</stdout>
+</verify>
+</testcase>