Skip to content

Commit ab525c0

Browse files
committed
http: have CURLOPT_FAILONERROR fail after all headers
... so that Retry-After and other meta-content can still be used. Added 1634 to verify. Adjusted test 194 and 281 since --fail now also includes the header-terminating CRLF in the output before it exits. Fixes curl#6408 Closes curl#6409
1 parent 9d7281f commit ab525c0

File tree

5 files changed

+90
-37
lines changed

5 files changed

+90
-37
lines changed

lib/http.c

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696

9797
static int http_getsock_do(struct connectdata *conn,
9898
curl_socket_t *socks);
99-
static int http_should_fail(struct connectdata *conn);
99+
static bool http_should_fail(struct connectdata *conn);
100100

101101
#ifndef CURL_DISABLE_PROXY
102102
static CURLcode add_haproxy_protocol_header(struct connectdata *conn);
@@ -1046,11 +1046,11 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
10461046
*
10471047
* @param conn all information about the current connection
10481048
*
1049-
* @retval 0 communications should continue
1049+
* @retval FALSE communications should continue
10501050
*
1051-
* @retval 1 communications should not continue
1051+
* @retval TRUE communications should not continue
10521052
*/
1053-
static int http_should_fail(struct connectdata *conn)
1053+
static bool http_should_fail(struct connectdata *conn)
10541054
{
10551055
struct Curl_easy *data;
10561056
int httpcode;
@@ -1066,20 +1066,20 @@ static int http_should_fail(struct connectdata *conn)
10661066
** don't fail.
10671067
*/
10681068
if(!data->set.http_fail_on_error)
1069-
return 0;
1069+
return FALSE;
10701070

10711071
/*
10721072
** Any code < 400 is never terminal.
10731073
*/
10741074
if(httpcode < 400)
1075-
return 0;
1075+
return FALSE;
10761076

10771077
/*
10781078
** Any code >= 400 that's not 401 or 407 is always
10791079
** a terminal error
10801080
*/
10811081
if((httpcode != 401) && (httpcode != 407))
1082-
return 1;
1082+
return TRUE;
10831083

10841084
/*
10851085
** All we have left to deal with is 401 and 407
@@ -3309,12 +3309,6 @@ checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
33093309
return checkhttpprefix(data, s, len);
33103310
}
33113311

3312-
static void print_http_error(struct Curl_easy *data)
3313-
{
3314-
struct SingleRequest *k = &data->req;
3315-
failf(data, "The requested URL returned error: %d", k->httpcode);
3316-
}
3317-
33183312
/*
33193313
* Curl_http_header() parses a single response header.
33203314
*/
@@ -3646,16 +3640,6 @@ CURLcode Curl_http_statusline(struct Curl_easy *data,
36463640
pretend this is no error */
36473641
k->ignorebody = TRUE; /* Avoid appending error msg to good data. */
36483642
}
3649-
else if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3650-
((k->httpcode != 401) || !conn->bits.user_passwd)
3651-
#ifndef CURL_DISABLE_PROXY
3652-
&& ((k->httpcode != 407) || !conn->bits.proxy_user_passwd)
3653-
#endif
3654-
) {
3655-
/* serious error, go home! */
3656-
print_http_error(data);
3657-
return CURLE_HTTP_RETURNED_ERROR;
3658-
}
36593643

36603644
if(conn->httpversion == 10) {
36613645
/* Default action for HTTP/1.0 must be to close, unless
@@ -3928,15 +3912,6 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
39283912
conn->proxy_negotiate_state = GSS_AUTHSUCC;
39293913
}
39303914
#endif
3931-
/*
3932-
* When all the headers have been parsed, see if we should give
3933-
* up and return an error.
3934-
*/
3935-
if(http_should_fail(conn)) {
3936-
failf(data, "The requested URL returned error: %d",
3937-
k->httpcode);
3938-
return CURLE_HTTP_RETURNED_ERROR;
3939-
}
39403915

39413916
/* now, only output this if the header AND body are requested:
39423917
*/
@@ -3954,6 +3929,16 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
39543929
data->info.header_size += (long)headerlen;
39553930
data->req.headerbytecount += (long)headerlen;
39563931

3932+
/*
3933+
* When all the headers have been parsed, see if we should give
3934+
* up and return an error.
3935+
*/
3936+
if(http_should_fail(conn)) {
3937+
failf(data, "The requested URL returned error: %d",
3938+
k->httpcode);
3939+
return CURLE_HTTP_RETURNED_ERROR;
3940+
}
3941+
39573942
data->req.deductheadercount =
39583943
(100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
39593944

tests/data/Makefile.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ test1608 test1609 test1610 test1611 test1612 \
196196
\
197197
test1620 test1621 \
198198
\
199-
test1630 test1631 test1632 test1633 \
199+
test1630 test1631 test1632 test1633 test1634 \
200200
\
201201
test1650 test1651 test1652 test1653 test1654 test1655 \
202202
test1660 \

tests/data/test1634

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<testcase>
2+
<info>
3+
<keywords>
4+
HTTP
5+
HTTP GET
6+
</keywords>
7+
</info>
8+
9+
#
10+
# Server-side
11+
<reply>
12+
<data>
13+
HTTP/1.1 429 too many requests swsbounce
14+
Retry-After: 1
15+
Content-Length: 4
16+
17+
moo
18+
</data>
19+
<data1>
20+
HTTP/1.1 200 OK
21+
Content-Length: 4
22+
Connection: close
23+
24+
hey
25+
</data1>
26+
27+
<datacheck>
28+
HTTP/1.1 429 too many requests swsbounce
29+
Retry-After: 1
30+
Content-Length: 4
31+
32+
HTTP/1.1 200 OK
33+
Content-Length: 4
34+
Connection: close
35+
36+
hey
37+
</datacheck>
38+
</reply>
39+
40+
#
41+
# Client-side
42+
<client>
43+
<server>
44+
http
45+
</server>
46+
<name>
47+
--retry with a 429 response and Retry-After: and --fail
48+
</name>
49+
<command>
50+
http://%HOSTIP:%HTTPPORT/1634 --retry 1 --fail
51+
</command>
52+
</client>
53+
54+
#
55+
# Verify data after the test has been "shot"
56+
<verify>
57+
<protocol>
58+
GET /1634 HTTP/1.1
59+
Host: %HOSTIP:%HTTPPORT
60+
User-Agent: curl/%VERSION
61+
Accept: */*
62+
63+
GET /1634 HTTP/1.1
64+
Host: %HOSTIP:%HTTPPORT
65+
User-Agent: curl/%VERSION
66+
Accept: */*
67+
68+
</protocol>
69+
</verify>
70+
</testcase>

tests/data/test194

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Content-Length: 4
3636
Content-Range: bytes */87
3737
Content-Type: image/gif
3838
Connection: close
39+
3940
</datacheck>
4041

4142
</reply>

tests/data/test281

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,8 @@ HTTP/1.1 401 Bad Auth swsclose
1414
Date: Thu, 09 Nov 2010 14:49:00 GMT
1515
WWW-Authenticate: Basic Realm=authenticate
1616
Server: test-server/fake
17-
</data>
18-
<datacheck>
19-
HTTP/1.1 100 Continue
2017

21-
</datacheck>
18+
</data>
2219

2320
</reply>
2421

0 commit comments

Comments
 (0)