mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
- Martin Drasar provided the CURLOPT_POSTREDIR patch. It renames
CURLOPT_POST301 (but adds a define for backwards compatibility for you who don't define CURL_NO_OLDIES). This option allows you to now also change the libcurl behavior for a HTTP response 302 after a POST to not use GET in the subsequent request (when CURLOPT_FOLLOWLOCATION is enabled). I edited the patch somewhat before commit. The curl tool got a matching --post302 option. Test case 1076 was added to verify this.
This commit is contained in:
parent
4c9768565e
commit
18110b519c
8
CHANGES
8
CHANGES
@ -7,6 +7,14 @@
|
||||
Changelog
|
||||
|
||||
Daniel Stenberg (5 Sep 2008)
|
||||
- Martin Drasar provided the CURLOPT_POSTREDIR patch. It renames
|
||||
CURLOPT_POST301 (but adds a define for backwards compatibility for you who
|
||||
don't define CURL_NO_OLDIES). This option allows you to now also change the
|
||||
libcurl behavior for a HTTP response 302 after a POST to not use GET in the
|
||||
subsequent request (when CURLOPT_FOLLOWLOCATION is enabled). I edited the
|
||||
patch somewhat before commit. The curl tool got a matching --post302
|
||||
option. Test case 1076 was added to verify this.
|
||||
|
||||
- Introducing CURLOPT_CERTINFO and the corresponding CURLINFO_CERTINFO. By
|
||||
enabling this feature with CURLOPT_CERTINFO for a request using SSL (HTTPS
|
||||
or FTPS), libcurl will gather lots of server certificate info and that info
|
||||
|
@ -1,7 +1,7 @@
|
||||
Curl and libcurl 7.19.1
|
||||
|
||||
Public curl releases: 107
|
||||
Command line options: 127
|
||||
Command line options: 128
|
||||
curl_easy_setopt() options: 154
|
||||
Public functions in libcurl: 58
|
||||
Known libcurl bindings: 36
|
||||
@ -11,6 +11,7 @@ This release includes the following changes:
|
||||
|
||||
o pkg-config can now show supported_protocols and supported_features
|
||||
o Added CURLOPT_CERTINFO and CURLINFO_CERTINFO
|
||||
o Added CURLOPT_POSTREDIR
|
||||
|
||||
This release includes the following bugfixes:
|
||||
|
||||
@ -30,6 +31,6 @@ This release would not have looked like this without help, code, reports and
|
||||
advice from friends like these:
|
||||
|
||||
Keith Mok, Yang Tse, Daniel Fandrich, Guenter Knauf, Dmitriy Sergeyev,
|
||||
Linus Nielsen Feltzing
|
||||
Linus Nielsen Feltzing, Martin Drasar
|
||||
|
||||
Thanks! (and sorry if I forgot to mention someone)
|
||||
|
@ -870,6 +870,13 @@ in web browsers, so curl does the conversion by default to maintain
|
||||
consistency. However, a server may requires a POST to remain a POST after such
|
||||
a redirection. This option is meaningful only when using \fI-L/--location\fP
|
||||
(Added in 7.17.1)
|
||||
.IP "--post302"
|
||||
Tells curl to respect RFC 2616/10.3.2 and not convert POST requests into GET
|
||||
requests when following a 302 redirection. The non-RFC behaviour is ubiquitous
|
||||
in web browsers, so curl does the conversion by default to maintain
|
||||
consistency. However, a server may requires a POST to remain a POST after such
|
||||
a redirection. This option is meaningful only when using \fI-L/--location\fP
|
||||
(Added in 7.19.1)
|
||||
.IP "--proxy-anyauth"
|
||||
Tells curl to pick a suitable authentication method when communicating with
|
||||
the given proxy. This might cause an extra request/response round-trip. (Added
|
||||
|
@ -1103,8 +1103,9 @@ typedef enum {
|
||||
CINIT(NEW_FILE_PERMS, LONG, 159),
|
||||
CINIT(NEW_DIRECTORY_PERMS, LONG, 160),
|
||||
|
||||
/* Obey RFC 2616/10.3.2 and keep POSTs as POSTs after a 301 */
|
||||
CINIT(POST301, LONG, 161),
|
||||
/* Set the behaviour of POST when redirecting. Values must be set to one
|
||||
of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */
|
||||
CINIT(POSTREDIR, LONG, 161),
|
||||
|
||||
/* used by scp/sftp to verify the host's public key */
|
||||
CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162),
|
||||
@ -1147,6 +1148,11 @@ typedef enum {
|
||||
the obsolete stuff removed! */
|
||||
|
||||
/* Backwards compatibility with older names */
|
||||
/* These are scheduled to disappear by 2011 */
|
||||
|
||||
/* This was added in version 7.19.1 */
|
||||
#define CURLOPT_POST301 CURLOPT_POSTREDIR
|
||||
|
||||
/* These are scheduled to disappear by 2009 */
|
||||
|
||||
/* The following were added in 7.17.0 */
|
||||
@ -1211,6 +1217,14 @@ enum {
|
||||
CURL_SSLVERSION_LAST /* never use, keep last */
|
||||
};
|
||||
|
||||
/* symbols to use with CURLOPT_POSTREDIR.
|
||||
CURL_REDIR_POST_301 and CURL_REDIR_POST_302 can be bitwise ORed so that
|
||||
CURL_REDIR_POST_301 | CURL_REDIR_POST_302 == CURL_REDIR_POST_ALL */
|
||||
|
||||
#define CURL_REDIR_GET_ALL 0
|
||||
#define CURL_REDIR_POST_301 1
|
||||
#define CURL_REDIR_POST_302 2
|
||||
#define CURL_REDIR_POST_ALL (CURL_REDIR_POST_301|CURL_REDIR_POST_302)
|
||||
|
||||
typedef enum {
|
||||
CURL_TIMECOND_NONE,
|
||||
|
@ -2286,7 +2286,7 @@ CURLcode Curl_follow(struct SessionHandle *data,
|
||||
* libcurl gets the page that most user agents would get, libcurl has to
|
||||
* force GET.
|
||||
*
|
||||
* This behaviour can be overridden with CURLOPT_POST301.
|
||||
* This behaviour can be overridden with CURLOPT_POSTREDIR.
|
||||
*/
|
||||
if( (data->set.httpreq == HTTPREQ_POST
|
||||
|| data->set.httpreq == HTTPREQ_POST_FORM)
|
||||
@ -2313,7 +2313,18 @@ CURLcode Curl_follow(struct SessionHandle *data,
|
||||
status. When interoperability with such clients is a concern, the
|
||||
302 status code may be used instead, since most user agents react
|
||||
to a 302 response as described here for 303.
|
||||
|
||||
This behaviour can be overriden with CURLOPT_POSTREDIR
|
||||
*/
|
||||
if( (data->set.httpreq == HTTPREQ_POST
|
||||
|| data->set.httpreq == HTTPREQ_POST_FORM)
|
||||
&& !data->set.post302) {
|
||||
infof(data,
|
||||
"Violate RFC 2616/10.3.3 and switch from POST to GET\n");
|
||||
data->set.httpreq = HTTPREQ_GET;
|
||||
}
|
||||
break;
|
||||
|
||||
case 303: /* See Other */
|
||||
/* Disable both types of POSTs, since doing a second POST when
|
||||
* following isn't what anyone would want! */
|
||||
|
21
lib/url.c
21
lib/url.c
@ -1028,12 +1028,21 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
||||
data->set.maxredirs = va_arg(param, long);
|
||||
break;
|
||||
|
||||
case CURLOPT_POST301:
|
||||
case CURLOPT_POSTREDIR:
|
||||
{
|
||||
/*
|
||||
* Obey RFC 2616/10.3.2 and resubmit a POST as a POST after a 301.
|
||||
* Set the behaviour of POST when redirecting
|
||||
* CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
|
||||
* CURL_REDIR_POST_301 - POST is kept as POST after 301
|
||||
* CURL_REDIR_POST_302 - POST is kept as POST after 302
|
||||
* CURL_REDIR_POST_ALL - POST is kept as POST after 301 and 302
|
||||
* other - POST is kept as POST after 301 and 302
|
||||
*/
|
||||
data->set.post301 = (bool)(0 != va_arg(param, long));
|
||||
break;
|
||||
long postRedir = va_arg(param, long);
|
||||
data->set.post301 = (postRedir & CURL_REDIR_POST_301)?1:0;
|
||||
data->set.post302 = (postRedir & CURL_REDIR_POST_302)?1:0;
|
||||
}
|
||||
break;
|
||||
|
||||
case CURLOPT_POST:
|
||||
/* Does this option serve a purpose anymore? Yes it does, when
|
||||
@ -2200,13 +2209,13 @@ CURLcode Curl_disconnect(struct connectdata *conn)
|
||||
if (has_host_ntlm) {
|
||||
data->state.authhost.done = FALSE;
|
||||
data->state.authhost.picked =
|
||||
data->state.authhost.want;
|
||||
data->state.authhost.want;
|
||||
}
|
||||
|
||||
if (has_proxy_ntlm) {
|
||||
data->state.authproxy.done = FALSE;
|
||||
data->state.authproxy.picked =
|
||||
data->state.authproxy.want;
|
||||
data->state.authproxy.want;
|
||||
}
|
||||
|
||||
if (has_host_ntlm || has_proxy_ntlm) {
|
||||
|
@ -1358,6 +1358,7 @@ struct UserDefined {
|
||||
for infinity */
|
||||
bool post301; /* Obey RFC 2616/10.3.2 and keep POSTs as POSTs after a
|
||||
301 */
|
||||
bool post302; /* keep POSTs as POSTs after a 302 */
|
||||
bool free_referer; /* set TRUE if 'referer' points to a string we
|
||||
allocated */
|
||||
void *postfields; /* if POST, set the fields' values here */
|
||||
|
29
src/main.c
29
src/main.c
@ -557,6 +557,7 @@ struct Configurable {
|
||||
char *libcurl; /* output libcurl code to this file name */
|
||||
bool raw;
|
||||
bool post301;
|
||||
bool post302;
|
||||
bool nokeepalive; /* for keepalive needs */
|
||||
long alivetime;
|
||||
|
||||
@ -780,6 +781,7 @@ static void help(void)
|
||||
" -o/--output <file> Write output to <file> instead of stdout",
|
||||
" --pass <pass> Pass phrase for the private key (SSL/SSH)",
|
||||
" --post301 Do not switch to GET after following a 301 redirect (H)",
|
||||
" --post302 Do not switch to GET after following a 302 redirect (H)",
|
||||
" -#/--progress-bar Display transfer progress as a progress bar",
|
||||
" -x/--proxy <host[:port]> Use HTTP proxy on given port",
|
||||
" --proxy-anyauth Pick \"any\" proxy authentication method (H)",
|
||||
@ -1669,6 +1671,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
{"$1", "keepalive", FALSE}, /* listed as --no-keepalive in the help */
|
||||
{"$2", "socks5-hostname", TRUE},
|
||||
{"$3", "keepalive-time", TRUE},
|
||||
{"$4", "post302", FALSE},
|
||||
|
||||
{"0", "http1.0", FALSE},
|
||||
{"1", "tlsv1", FALSE},
|
||||
@ -2177,6 +2180,9 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
|
||||
if(str2num(&config->alivetime, nextarg))
|
||||
return PARAM_BAD_NUMERIC;
|
||||
break;
|
||||
case '4': /* --post302 */
|
||||
config->post302 = toggle;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '#': /* --progress-bar */
|
||||
@ -2946,19 +2952,19 @@ static const char *unslashquote(const char *line, char *param)
|
||||
/* default is to output the letter after the backslash */
|
||||
switch(out = *line) {
|
||||
case '\0':
|
||||
continue; /* this'll break out of the loop */
|
||||
continue; /* this'll break out of the loop */
|
||||
case 't':
|
||||
out='\t';
|
||||
break;
|
||||
out='\t';
|
||||
break;
|
||||
case 'n':
|
||||
out='\n';
|
||||
break;
|
||||
out='\n';
|
||||
break;
|
||||
case 'r':
|
||||
out='\r';
|
||||
break;
|
||||
out='\r';
|
||||
break;
|
||||
case 'v':
|
||||
out='\v';
|
||||
break;
|
||||
out='\v';
|
||||
break;
|
||||
}
|
||||
*param++=out;
|
||||
line++;
|
||||
@ -4777,12 +4783,15 @@ operate(struct Configurable *config, int argc, argv_item_t argv[])
|
||||
}
|
||||
|
||||
/* curl 7.17.1 */
|
||||
my_setopt(curl, CURLOPT_POST301, config->post301);
|
||||
if (!config->nokeepalive) {
|
||||
my_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockoptcallback);
|
||||
my_setopt(curl, CURLOPT_SOCKOPTDATA, config);
|
||||
}
|
||||
|
||||
/* curl 7.19.1 (the 301 version existed in 7.18.2) */
|
||||
my_setopt(curl, CURLOPT_POSTREDIR, config->post301 |
|
||||
(config->post302 ? CURL_REDIR_POST_302 : FALSE));
|
||||
|
||||
retry_numretries = config->req_retry;
|
||||
|
||||
retrystart = cutil_tvnow();
|
||||
|
@ -57,7 +57,7 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
|
||||
test1048 test1049 test1050 test1051 test1052 test1053 test1054 test1055 \
|
||||
test1056 test1057 test1058 test1059 test1060 test1061 test1062 test1063 \
|
||||
test1064 test1065 test1066 test1067 test1068 test1069 test1070 test1071 \
|
||||
test1072 test1073 test1074 test1075
|
||||
test1072 test1073 test1074 test1075 test1076
|
||||
|
||||
filecheck:
|
||||
@mkdir test-place; \
|
||||
|
79
tests/data/test1076
Normal file
79
tests/data/test1076
Normal file
@ -0,0 +1,79 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
HTTP
|
||||
HTTP POST
|
||||
followlocation
|
||||
</keywords>
|
||||
</info>
|
||||
#
|
||||
# Server-side
|
||||
<reply>
|
||||
<data>
|
||||
HTTP/1.1 302 OK swsclose
|
||||
Location: moo.html&testcase=/10760002
|
||||
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||
Connection: close
|
||||
|
||||
</data>
|
||||
<data2>
|
||||
HTTP/1.1 200 OK swsclose
|
||||
Location: this should be ignored
|
||||
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||
Connection: close
|
||||
|
||||
body
|
||||
</data2>
|
||||
<datacheck>
|
||||
HTTP/1.1 302 OK swsclose
|
||||
Location: moo.html&testcase=/10760002
|
||||
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||
Connection: close
|
||||
|
||||
HTTP/1.1 200 OK swsclose
|
||||
Location: this should be ignored
|
||||
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||
Connection: close
|
||||
|
||||
body
|
||||
</datacheck>
|
||||
</reply>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
http
|
||||
</server>
|
||||
<name>
|
||||
HTTP POST with 302 redirect and --post302
|
||||
</name>
|
||||
<command>
|
||||
http://%HOSTIP:%HTTPPORT/blah/1076 -L -d "moo" --post302
|
||||
</command>
|
||||
</client>
|
||||
|
||||
#
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<strip>
|
||||
^User-Agent:.*
|
||||
</strip>
|
||||
<protocol nonewline="yes">
|
||||
POST /blah/1076 HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
Accept: */*
|
||||
Content-Length: 3
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
mooPOST /blah/moo.html&testcase=/10760002 HTTP/1.1
|
||||
User-Agent: curl/7.10 (i686-pc-linux-gnu) libcurl/7.10 OpenSSL/0.9.6c ipv6 zlib/1.1.3
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
Accept: */*
|
||||
Content-Length: 3
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
moo
|
||||
</protocol>
|
||||
</verify>
|
||||
</testcase>
|
Loading…
Reference in New Issue
Block a user