aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2008-09-05 16:13:20 +0000
committerDaniel Stenberg <daniel@haxx.se>2008-09-05 16:13:20 +0000
commit18110b519c56a464bca4258332279c580f07a52f (patch)
tree0818c63153e939254958ebeacce23ac713bd9bba /lib
parent4c9768565ec3a9baf26ac8a547bca6e42cc64fa5 (diff)
- 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.
Diffstat (limited to 'lib')
-rw-r--r--lib/transfer.c13
-rw-r--r--lib/url.c21
-rw-r--r--lib/urldata.h1
3 files changed, 28 insertions, 7 deletions
diff --git a/lib/transfer.c b/lib/transfer.c
index 2fd6d4cf3..ddacb442a 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -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! */
diff --git a/lib/url.c b/lib/url.c
index d6dec0d0a..a51ba4394 100644
--- a/lib/url.c
+++ b/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) {
diff --git a/lib/urldata.h b/lib/urldata.h
index f1a001aa0..a8a7555aa 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -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 */