← Commit list

c1a1a2968e

Stefan Eissing
Stefan Eissing
2026-09-24
SUCCESS Duration: 396s

Subject

cf-h1-proxy: stricter status line parsing

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/cf-h1-proxy.c+33 -14
@@ -303,6 +303,30 @@ out:
return result;
}
+static CURLcode on_resp_status(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ struct h1_tunnel_state *ts,
+ const char *header)
+{
+ struct SingleRequest *k = &data->req;
+
+ (void)ts;
+ if(!strncmp(header, "HTTP/1.", 7) &&
+ ((header[7] == '0') || (header[7] == '1')) &&
+ (header[8] == ' ') &&
+ ISDIGIT(header[9]) && ISDIGIT(header[10]) && ISDIGIT(header[11]) &&
+ !ISDIGIT(header[12])) {
+ /* store the HTTP code from the proxy */
+ data->info.httpproxycode = k->httpcode = ((header[9] - '0') * 100) +
+ ((header[10] - '0') * 10) + (header[11] - '0');
+ CURL_TRC_CF(data, cf, "CONNECT%s HTTP status %d",
+ h1_proxy_is_udp(cf) ? "-UDP" : "", k->httpcode);
+ return CURLE_OK;
+ }
+ failf(data, "Invalid response header");
+ return CURLE_WEIRD_SERVER_REPLY;
+}
+
static CURLcode on_resp_header(struct Curl_cfilter *cf,
struct Curl_easy *data,
struct h1_tunnel_state *ts,
@@ -391,17 +415,6 @@ static CURLcode on_resp_header(struct Curl_cfilter *cf,
is_udp ? "-UDP" : "");
ts->close_connection = TRUE;
}
- else if(!strncmp(header, "HTTP/1.", 7) &&
- ((header[7] == '0') || (header[7] == '1')) &&
- (header[8] == ' ') &&
- ISDIGIT(header[9]) && ISDIGIT(header[10]) && ISDIGIT(header[11]) &&
- !ISDIGIT(header[12])) {
- /* store the HTTP code from the proxy */
- data->info.httpproxycode = k->httpcode = ((header[9] - '0') * 100) +
- ((header[10] - '0') * 10) + (header[11] - '0');
- CURL_TRC_CF(data, cf, "CONNECT%s HTTP status %d",
- is_udp ? "-UDP" : "", k->httpcode);
- }
return result;
}
@@ -442,8 +455,11 @@ static CURLcode single_header(struct Curl_cfilter *cf,
if(ISNEWLINE(linep[0])) {
/* end of response-headers from the proxy */
-
- if((407 == k->httpcode) && !data->state.authproblem) {
+ if(ts->headerlines == 1) {
+ ts->keepon = KEEPON_DONE;
+ result = CURLE_WEIRD_SERVER_REPLY;
+ }
+ else if((407 == k->httpcode) && !data->state.authproblem) {
/* If we get a 407 response code with content length
when we have no auth problem, we must ignore the
whole response-body */
@@ -472,7 +488,10 @@ static CURLcode single_header(struct Curl_cfilter *cf,
return result;
}
- result = on_resp_header(cf, data, ts, linep);
+ if(ts->headerlines == 1)
+ result = on_resp_status(cf, data, ts, linep);
+ else
+ result = on_resp_header(cf, data, ts, linep);
if(result)
return result;
tests/data/Makefile.am+1 -0
@@ -1748,6 +1748,7 @@ TESTCASES = \
test1800 \
test1801 \
test1802 \
+ test1827 \
test1847 \
test1848 \
test1849 \
tests/data/test1827+51 -0
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="US-ASCII"?>
+<testcase>
+<info>
+<keywords>
+HTTPS
+HTTP GET
+HTTP CONNECT
+HTTP proxy
+</keywords>
+</info>
+# Server-side
+<reply>
+<connect nocheck="yes">
+HTTP/1.1 407 Needs proxy authentication
+HTTP/1.1 200 is not the answer: nonono
+Server: test-server/fake swsclose yesyes
+Proxy-Authenticate: Basic "oh please"
+
+</connect>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+<features>
+proxy
+</features>
+<name>
+HTTP CONNECT with faked status line header
+</name>
+<command>
+http://test.anything.really.com:%TESTNUMBER --proxy %HOSTIP:%HTTPPORT --proxytunnel
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<errorcode>
+7
+</errorcode>
+<protocol crlf="headers">
+CONNECT test.anything.really.com:%TESTNUMBER HTTP/1.1
+Host: test.anything.really.com:%TESTNUMBER
+User-Agent: curl/%VERSION
+Proxy-Connection: Keep-Alive
+
+</protocol>
+</verify>
+</testcase>
tests/data/test750+2 -2
@@ -49,10 +49,10 @@ Proxy-Connection: Keep-Alive
</protocol>
<errorcode>
-43
+8
</errorcode>
<stderr mode="text">
-curl: (43) Invalid response header
+curl: (8) Invalid response header
</stderr>
</verify>
</testcase>