1
0
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:
Daniel Stenberg 2008-09-05 16:13:20 +00:00
parent 4c9768565e
commit 18110b519c
10 changed files with 161 additions and 22 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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,

View File

@ -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! */

View File

@ -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) {

View File

@ -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 */

View File

@ -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();

View File

@ -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
View 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>