mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
- Test cases 1051, 1052 and 1055 were added by Daniel Fandrich on July 30 and
proved how PUT and POST with a redirect could lead to a "hang" due to the data stream not being rewound properly when it had to in order to get sent properly (again) to the subsequent URL. This is now fixed and these test cases are no longer disabled.
This commit is contained in:
parent
931fc45f05
commit
3a499099af
10
CHANGES
10
CHANGES
@ -6,6 +6,13 @@
|
|||||||
|
|
||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
|
Daniel Stenberg (4 Aug 2008)
|
||||||
|
- Test cases 1051, 1052 and 1055 were added by Daniel Fandrich on July 30 and
|
||||||
|
proved how PUT and POST with a redirect could lead to a "hang" due to the
|
||||||
|
data stream not being rewound properly when it had to in order to get sent
|
||||||
|
properly (again) to the subsequent URL. This is now fixed and these test
|
||||||
|
cases are no longer disabled.
|
||||||
|
|
||||||
Yang Tse (4 Aug 2008)
|
Yang Tse (4 Aug 2008)
|
||||||
- Autoconf 2.62 has changed the behaviour of the AC_AIX macro which we use.
|
- Autoconf 2.62 has changed the behaviour of the AC_AIX macro which we use.
|
||||||
Prior versions of autoconf defined _ALL_SOURCE if _AIX was defined. 2.62
|
Prior versions of autoconf defined _ALL_SOURCE if _AIX was defined. 2.62
|
||||||
@ -14,9 +21,8 @@ Yang Tse (4 Aug 2008)
|
|||||||
and an uniform one across autoconf versions AC_AIX is replaced with our
|
and an uniform one across autoconf versions AC_AIX is replaced with our
|
||||||
own internal macro CURL_CHECK_AIX_ALL_SOURCE.
|
own internal macro CURL_CHECK_AIX_ALL_SOURCE.
|
||||||
|
|
||||||
|
|
||||||
Daniel Stenberg (4 Aug 2008)
|
Daniel Stenberg (4 Aug 2008)
|
||||||
- Test case 1041 (added by Daniel Fandrich April 14th) proved a bug where PUT
|
- Test case 1041 (added by Daniel Fandrich July 14th) proved a bug where PUT
|
||||||
with -C - sent garbage in the Content-Range: header. I fixed this problem by
|
with -C - sent garbage in the Content-Range: header. I fixed this problem by
|
||||||
making sure libcurl always sets the size of the _entire_ upload if an app
|
making sure libcurl always sets the size of the _entire_ upload if an app
|
||||||
attemps to do resumed uploads since libcurl simply cannot know the size of
|
attemps to do resumed uploads since libcurl simply cannot know the size of
|
||||||
|
@ -45,7 +45,8 @@ This release includes the following bugfixes:
|
|||||||
o a user name in a proxy URL without a password was parsed incorrectly
|
o a user name in a proxy URL without a password was parsed incorrectly
|
||||||
o library will now be built with _REENTRANT symbol defined only if needed
|
o library will now be built with _REENTRANT symbol defined only if needed
|
||||||
o no longer link with gdi32 on Windows cross-compiled targets
|
o no longer link with gdi32 on Windows cross-compiled targets
|
||||||
o PUT with -C - sent bad Content-Range: header
|
o HTTP PUT with -C - sent bad Content-Range: header
|
||||||
|
o HTTP PUT or POST with redirect could lead to hang
|
||||||
|
|
||||||
This release includes the following known bugs:
|
This release includes the following known bugs:
|
||||||
|
|
||||||
|
@ -29,7 +29,4 @@ To be addressed before 7.19.0 (planned release: August 2008)
|
|||||||
tests on the system might allow determination of the problem origin.
|
tests on the system might allow determination of the problem origin.
|
||||||
Solaris AutoBuilds suceeded on August 2 and 3.
|
Solaris AutoBuilds suceeded on August 2 and 3.
|
||||||
|
|
||||||
151 - PUT with -L hangs after receiving a redirect (test case 1051, but the
|
|
||||||
test harness has a problem with this, too)
|
|
||||||
|
|
||||||
152 -
|
152 -
|
||||||
|
21
lib/http.c
21
lib/http.c
@ -309,7 +309,7 @@ static bool pickoneauth(struct auth *pick)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* perhapsrewind()
|
* Curl_http_perhapsrewind()
|
||||||
*
|
*
|
||||||
* If we are doing POST or PUT {
|
* If we are doing POST or PUT {
|
||||||
* If we have more data to send {
|
* If we have more data to send {
|
||||||
@ -331,18 +331,29 @@ static bool pickoneauth(struct auth *pick)
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
static CURLcode perhapsrewind(struct connectdata *conn)
|
CURLcode Curl_http_perhapsrewind(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
struct SessionHandle *data = conn->data;
|
struct SessionHandle *data = conn->data;
|
||||||
struct HTTP *http = data->state.proto.http;
|
struct HTTP *http = data->state.proto.http;
|
||||||
curl_off_t bytessent;
|
curl_off_t bytessent;
|
||||||
curl_off_t expectsend = -1; /* default is unknown */
|
curl_off_t expectsend = -1; /* default is unknown */
|
||||||
|
|
||||||
if(!http)
|
if(!http || !(conn->protocol & PROT_HTTP))
|
||||||
/* If this is still NULL, we have not reach very far and we can
|
/* If this is still NULL, we have not reach very far and we can
|
||||||
safely skip this rewinding stuff */
|
safely skip this rewinding stuff, or this is attempted to get used
|
||||||
|
when HTTP isn't activated */
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
|
infof(data, "now in %s\n", __func__);
|
||||||
|
|
||||||
|
switch(data->set.httpreq) {
|
||||||
|
case HTTPREQ_GET:
|
||||||
|
case HTTPREQ_HEAD:
|
||||||
|
return CURLE_OK;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
bytessent = http->writebytecount;
|
bytessent = http->writebytecount;
|
||||||
|
|
||||||
if(conn->bits.authneg)
|
if(conn->bits.authneg)
|
||||||
@ -453,7 +464,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
|||||||
if((data->set.httpreq != HTTPREQ_GET) &&
|
if((data->set.httpreq != HTTPREQ_GET) &&
|
||||||
(data->set.httpreq != HTTPREQ_HEAD) &&
|
(data->set.httpreq != HTTPREQ_HEAD) &&
|
||||||
!conn->bits.rewindaftersend) {
|
!conn->bits.rewindaftersend) {
|
||||||
code = perhapsrewind(conn);
|
code = Curl_http_perhapsrewind(conn);
|
||||||
if(code)
|
if(code)
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -57,6 +57,7 @@ void Curl_http_auth_stage(struct SessionHandle *data, int stage);
|
|||||||
CURLcode Curl_http_input_auth(struct connectdata *conn,
|
CURLcode Curl_http_input_auth(struct connectdata *conn,
|
||||||
int httpcode, const char *header);
|
int httpcode, const char *header);
|
||||||
CURLcode Curl_http_auth_act(struct connectdata *conn);
|
CURLcode Curl_http_auth_act(struct connectdata *conn);
|
||||||
|
CURLcode Curl_http_perhapsrewind(struct connectdata *conn);
|
||||||
|
|
||||||
int Curl_http_should_fail(struct connectdata *conn);
|
int Curl_http_should_fail(struct connectdata *conn);
|
||||||
|
|
||||||
|
@ -1116,6 +1116,12 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
data->req.newurl = strdup(data->req.location); /* clone */
|
data->req.newurl = strdup(data->req.location); /* clone */
|
||||||
if(!data->req.newurl)
|
if(!data->req.newurl)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
/* some cases of POST and PUT etc needs to rewind the data
|
||||||
|
stream at this point */
|
||||||
|
result = Curl_http_perhapsrewind(conn);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1570,6 +1576,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
|||||||
/* we've waited long enough, continue anyway */
|
/* we've waited long enough, continue anyway */
|
||||||
k->exp100 = EXP100_SEND_DATA;
|
k->exp100 = EXP100_SEND_DATA;
|
||||||
k->keepon |= KEEP_WRITE;
|
k->keepon |= KEEP_WRITE;
|
||||||
|
infof(data, "Done waiting for 100-continue\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,4 @@
|
|||||||
# test cases are run by runtests.pl. Just add the plain test case numbers, one
|
# test cases are run by runtests.pl. Just add the plain test case numbers, one
|
||||||
# per line.
|
# per line.
|
||||||
# Lines starting with '#' letters are treated as comments.
|
# Lines starting with '#' letters are treated as comments.
|
||||||
1051
|
|
||||||
1052
|
|
||||||
1055
|
|
||||||
|
@ -29,12 +29,12 @@ Content-Length: 51
|
|||||||
If this is received, the location following worked
|
If this is received, the location following worked
|
||||||
</data2>
|
</data2>
|
||||||
<datacheck>
|
<datacheck>
|
||||||
HTTP/1.1 301 Redirect
|
HTTP/1.1 301 Redirect swsclose
|
||||||
Date: Thu, 29 Jul 2008 14:49:00 GMT
|
Date: Thu, 29 Jul 2008 14:49:00 GMT
|
||||||
Server: test-server/fake
|
Server: test-server/fake
|
||||||
Location: data/10510002.txt?coolsite=yes
|
Location: data/10510002.txt?coolsite=yes
|
||||||
Content-Length: 0
|
Content-Length: 0
|
||||||
Connection: Keep-Alive
|
Connection: close
|
||||||
|
|
||||||
HTTP/1.1 100 Continue
|
HTTP/1.1 100 Continue
|
||||||
|
|
||||||
@ -76,6 +76,12 @@ the
|
|||||||
<strip>
|
<strip>
|
||||||
^User-Agent:.*
|
^User-Agent:.*
|
||||||
</strip>
|
</strip>
|
||||||
|
|
||||||
|
# The primary reason libcurl sends the data part twice in this test is that
|
||||||
|
# the test HTTP server is blocking until it has read the entire request,
|
||||||
|
# including the full request-body before it responds. So in this test the
|
||||||
|
# server says 301 and 100 _after_ the entire PUT body has been sent.
|
||||||
|
|
||||||
<protocol>
|
<protocol>
|
||||||
PUT /want/1051 HTTP/1.1
|
PUT /want/1051 HTTP/1.1
|
||||||
Host: %HOSTIP:%HTTPPORT
|
Host: %HOSTIP:%HTTPPORT
|
||||||
@ -83,6 +89,15 @@ Accept: */*
|
|||||||
Content-Length: 78
|
Content-Length: 78
|
||||||
Expect: 100-continue
|
Expect: 100-continue
|
||||||
|
|
||||||
|
Weird
|
||||||
|
file
|
||||||
|
to
|
||||||
|
upload
|
||||||
|
for
|
||||||
|
testing
|
||||||
|
the
|
||||||
|
PUT
|
||||||
|
feature
|
||||||
PUT /want/data/10510002.txt?coolsite=yes HTTP/1.1
|
PUT /want/data/10510002.txt?coolsite=yes HTTP/1.1
|
||||||
Host: %HOSTIP:%HTTPPORT
|
Host: %HOSTIP:%HTTPPORT
|
||||||
Accept: */*
|
Accept: */*
|
||||||
|
@ -27,12 +27,12 @@ Content-Length: 51
|
|||||||
If this is received, the location following worked
|
If this is received, the location following worked
|
||||||
</data2>
|
</data2>
|
||||||
<datacheck>
|
<datacheck>
|
||||||
HTTP/1.0 301 Redirect
|
HTTP/1.0 301 Redirect swsclose
|
||||||
Date: Thu, 29 Jul 2008 14:49:00 GMT
|
Date: Thu, 29 Jul 2008 14:49:00 GMT
|
||||||
Server: test-server/fake
|
Server: test-server/fake
|
||||||
Location: data/10520002.txt?coolsite=yes
|
Location: data/10520002.txt?coolsite=yes
|
||||||
Content-Length: 0
|
Content-Length: 0
|
||||||
Connection: Keep-Alive
|
Connection: close
|
||||||
|
|
||||||
HTTP/1.0 200 Followed here fine swsclose
|
HTTP/1.0 200 Followed here fine swsclose
|
||||||
Date: Thu, 29 Jul 2008 14:49:00 GMT
|
Date: Thu, 29 Jul 2008 14:49:00 GMT
|
||||||
@ -72,13 +72,27 @@ the
|
|||||||
<strip>
|
<strip>
|
||||||
^User-Agent:.*
|
^User-Agent:.*
|
||||||
</strip>
|
</strip>
|
||||||
|
|
||||||
|
# The primary reason libcurl sends the data part twice in this test is that
|
||||||
|
# the test HTTP server is blocking until it has read the entire request,
|
||||||
|
# including the full request-body before it responds. So in this test the
|
||||||
|
# server says 301 and 200 _after_ the entire PUT body has been sent.
|
||||||
<protocol>
|
<protocol>
|
||||||
PUT /want/1052 HTTP/1.1
|
PUT /want/1052 HTTP/1.0
|
||||||
Host: %HOSTIP:%HTTPPORT
|
Host: %HOSTIP:%HTTPPORT
|
||||||
Accept: */*
|
Accept: */*
|
||||||
Content-Length: 78
|
Content-Length: 78
|
||||||
|
|
||||||
PUT /want/data/10520002.txt?coolsite=yes HTTP/1.1
|
Weird
|
||||||
|
file
|
||||||
|
to
|
||||||
|
upload
|
||||||
|
for
|
||||||
|
testing
|
||||||
|
the
|
||||||
|
PUT
|
||||||
|
feature
|
||||||
|
PUT /want/data/10520002.txt?coolsite=yes HTTP/1.0
|
||||||
Host: %HOSTIP:%HTTPPORT
|
Host: %HOSTIP:%HTTPPORT
|
||||||
Accept: */*
|
Accept: */*
|
||||||
Content-Length: 78
|
Content-Length: 78
|
||||||
|
@ -65,7 +65,18 @@ the
|
|||||||
PUT /1055 HTTP/1.1
|
PUT /1055 HTTP/1.1
|
||||||
Host: %HOSTIP:%HTTPPORT
|
Host: %HOSTIP:%HTTPPORT
|
||||||
Accept: */*
|
Accept: */*
|
||||||
|
Content-Length: 78
|
||||||
|
Expect: 100-continue
|
||||||
|
|
||||||
|
Weird
|
||||||
|
file
|
||||||
|
to
|
||||||
|
upload
|
||||||
|
for
|
||||||
|
testing
|
||||||
|
the
|
||||||
|
PUT
|
||||||
|
feature
|
||||||
USER anonymous
|
USER anonymous
|
||||||
PASS ftp@example.com
|
PASS ftp@example.com
|
||||||
PWD
|
PWD
|
||||||
|
Loading…
Reference in New Issue
Block a user