Fix two bugs in HTTPS tunnelling:

- If the proxy returns a non-200 result, set the error code accordingly
   so the caller / user gets a somewhat meaningful error message.
 - Consume and discard any HTTP response header following the result line.

PR:		194483
Tested by:	Fabian Keil <fk@fabiankeil.de>
MFC after:	1 week
This commit is contained in:
des 2015-10-16 12:21:44 +00:00
parent 7f5fdd9fd0
commit 7cd58b9488

View File

@ -1376,8 +1376,12 @@ http_connect(struct url *URL, struct url *purl, const char *flags)
{
struct url *curl;
conn_t *conn;
hdr_t h;
http_headerbuf_t headerbuf;
const char *p;
int verbose;
int af, val;
int serrno;
#ifdef INET6
af = AF_UNSPEC;
@ -1398,6 +1402,7 @@ http_connect(struct url *URL, struct url *purl, const char *flags)
if ((conn = fetch_connect(curl->host, curl->port, af, verbose)) == NULL)
/* fetch_connect() has already set an error code */
return (NULL);
init_http_headerbuf(&headerbuf);
if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 && purl) {
http_cmd(conn, "CONNECT %s:%d HTTP/1.1",
URL->host, URL->port);
@ -1405,10 +1410,26 @@ http_connect(struct url *URL, struct url *purl, const char *flags)
URL->host, URL->port);
http_cmd(conn, "");
if (http_get_reply(conn) != HTTP_OK) {
fetch_close(conn);
return (NULL);
http_seterr(conn->err);
goto ouch;
}
http_get_reply(conn);
/* Read and discard the rest of the proxy response */
if (fetch_getln(conn) < 0) {
fetch_syserr();
goto ouch;
}
do {
switch ((h = http_next_header(conn, &headerbuf, &p))) {
case hdr_syserror:
fetch_syserr();
goto ouch;
case hdr_error:
http_seterr(HTTP_PROTOCOL_ERROR);
goto ouch;
default:
/* ignore */ ;
}
} while (h < hdr_end);
}
if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 &&
fetch_ssl(conn, URL, verbose) == -1) {
@ -1416,13 +1437,20 @@ http_connect(struct url *URL, struct url *purl, const char *flags)
/* grrr */
errno = EAUTH;
fetch_syserr();
return (NULL);
goto ouch;
}
val = 1;
setsockopt(conn->sd, IPPROTO_TCP, TCP_NOPUSH, &val, sizeof(val));
clean_http_headerbuf(&headerbuf);
return (conn);
ouch:
serrno = errno;
clean_http_headerbuf(&headerbuf);
fetch_close(conn);
errno = serrno;
return (NULL);
}
static struct url *