← Commit list

9596c4a258

Daniel Stenberg
Daniel Stenberg
2025-10-20
SUCCESS Duration: 149s

Subject

http: return error for a second Location: header

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/http.c+28 -20
@@ -3265,9 +3265,7 @@ static CURLcode http_header_l(struct Curl_easy *data,
data->info.filetime = k->timeofdoc;
return CURLE_OK;
}
- if((k->httpcode >= 300 && k->httpcode < 400) &&
- HD_IS(hd, hdlen, "Location:") &&
- !data->req.location) {
+ if(HD_IS(hd, hdlen, "Location:")) {
/* this is the URL that the server advises us to use instead */
char *location = Curl_copy_header_value(hd);
if(!location)
@@ -3276,23 +3274,33 @@ static CURLcode http_header_l(struct Curl_easy *data,
/* ignore empty data */
free(location);
else {
- data->req.location = location;
-
- if(data->set.http_follow_mode) {
- CURLcode result;
- DEBUGASSERT(!data->req.newurl);
- data->req.newurl = strdup(data->req.location); /* clone */
- if(!data->req.newurl)
- return CURLE_OUT_OF_MEMORY;
-
- /* some cases of POST and PUT etc needs to rewind the data
- stream at this point */
- result = http_perhapsrewind(data, conn);
- if(result)
- return result;
-
- /* mark the next request as a followed location: */
- data->state.this_is_a_follow = TRUE;
+ if(data->req.location &&
+ strcmp(data->req.location, location)) {
+ failf(data, "Multiple Location headers");
+ free(location);
+ return CURLE_WEIRD_SERVER_REPLY;
+ }
+ else {
+ free(data->req.location);
+ data->req.location = location;
+
+ if((k->httpcode >= 300 && k->httpcode < 400) &&
+ data->set.http_follow_mode) {
+ CURLcode result;
+ DEBUGASSERT(!data->req.newurl);
+ data->req.newurl = strdup(data->req.location); /* clone */
+ if(!data->req.newurl)
+ return CURLE_OUT_OF_MEMORY;
+
+ /* some cases of POST and PUT etc needs to rewind the data
+ stream at this point */
+ result = http_perhapsrewind(data, conn);
+ if(result)
+ return result;
+
+ /* mark the next request as a followed location: */
+ data->state.this_is_a_follow = TRUE;
+ }
}
}
}
tests/data/Makefile.am+1 -1
@@ -110,7 +110,7 @@ test736 test737 test738 test739 test740 test741 test742 test743 test744 \
test745 test746 test747 test748 test749 test750 test751 test752 test753 \
test754 test755 test756 test757 test758 test759 test760 test761 test762 \
test763 test764 test765 test766 test767 test768 test769 test770 test771 \
-\
+test772 test773 \
test780 test781 test782 test783 test784 test785 test786 test787 test788 \
test789 test790 test791 test792 test793 test794 test796 test797 \
\
tests/data/test580+11 -0
@@ -20,6 +20,14 @@ Connection: close
Location: and there's a second one too! / moo.html
</data>
+<datacheck>
+HTTP/1.1 302 eat this!
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Location: this-is-the-first.html
+Content-Length: 0
+Connection: close
+</datacheck>
</reply>
# Client-side
@@ -51,5 +59,8 @@ Host: %HOSTIP:%HTTPPORT
Accept: */*
</protocol>
+<errorcode>
+8
+</errorcode>
</verify>
</testcase>
tests/data/test772+52 -0
@@ -0,0 +1,52 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+Location
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data crlf="yes" nocheck="yes">
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Content-Length: 0
+Connection: close
+Location: this
+Location: that
+
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<name>
+HTTP with two Location: headers triggers error
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol crlf="yes">
+GET /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+<errorcode>
+8
+</errorcode>
+</verify>
+</testcase>
tests/data/test773+49 -0
@@ -0,0 +1,49 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+Location
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data crlf="yes" nocheck="yes">
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Content-Length: 0
+Connection: close
+Location: this
+Location: this
+
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+<name>
+HTTP with two identical Location: headers triggers no error
+</name>
+<command>
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol crlf="yes">
+GET /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+</verify>
+</testcase>