aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/libcurl/curl_easy_setopt.37
-rw-r--r--docs/libcurl/symbols-in-versions1
-rw-r--r--include/curl/curl.h9
-rw-r--r--lib/transfer.c11
-rw-r--r--lib/url.c6
-rw-r--r--lib/urldata.h6
6 files changed, 23 insertions, 17 deletions
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index d0e054b62..a90ee65e6 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -1180,12 +1180,13 @@ Setting the limit to 0 will make libcurl refuse any redirect. Set it to -1 for
an infinite number of redirects (which is the default)
.IP CURLOPT_POSTREDIR
Pass a bitmask to control how libcurl acts on redirects after POSTs that get a
-301 or 302 response back. A parameter with bit 0 set (value
+301, 302 or 303 response back. A parameter with bit 0 set (value
\fBCURL_REDIR_POST_301\fP) tells the library to respect RFC 2616/10.3.2 and
not convert POST requests into GET requests when following a 301
redirection. Setting bit 1 (value CURL_REDIR_POST_302) makes libcurl maintain
-the request method after a 302 redirect. CURL_REDIR_POST_ALL is a convenience
-define that sets both bits.
+the request method after a 302 redirect. Setting bit 2 (value
+\fBCURL_REDIR_POST_303) makes libcurl maintain the request method after a 302
+redirect. CURL_REDIR_POST_ALL is a convenience define that sets both bits.
The non-RFC behaviour is ubiquitous in web browsers, so the library does the
conversion by default to maintain consistency. However, a server may require a
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
index 62d8a242b..41705fd29 100644
--- a/docs/libcurl/symbols-in-versions
+++ b/docs/libcurl/symbols-in-versions
@@ -649,6 +649,7 @@ CURL_READFUNC_PAUSE 7.18.0
CURL_REDIR_GET_ALL 7.19.1
CURL_REDIR_POST_301 7.19.1
CURL_REDIR_POST_302 7.19.1
+CURL_REDIR_POST_303 7.25.1
CURL_REDIR_POST_ALL 7.19.1
CURL_RTSPREQ_ANNOUNCE 7.20.0
CURL_RTSPREQ_DESCRIBE 7.20.0
diff --git a/include/curl/curl.h b/include/curl/curl.h
index f2501cd2b..f3166d952 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -1624,13 +1624,16 @@ enum CURL_TLSAUTH {
};
/* 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 */
+ CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303
+ can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302
+ | CURL_REDIR_POST_303 == 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)
+#define CURL_REDIR_POST_303 4
+#define CURL_REDIR_POST_ALL \
+ (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303)
typedef enum {
CURL_TIMECOND_NONE,
diff --git a/lib/transfer.c b/lib/transfer.c
index d872719fa..20b3d048e 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -1864,7 +1864,7 @@ CURLcode Curl_follow(struct SessionHandle *data,
*/
if((data->set.httpreq == HTTPREQ_POST
|| data->set.httpreq == HTTPREQ_POST_FORM)
- && !data->set.post301) {
+ && !(data->set.keep_post & CURL_REDIR_POST_301)) {
infof(data,
"Violate RFC 2616/10.3.2 and switch from POST to GET\n");
data->set.httpreq = HTTPREQ_GET;
@@ -1892,7 +1892,7 @@ CURLcode Curl_follow(struct SessionHandle *data,
*/
if((data->set.httpreq == HTTPREQ_POST
|| data->set.httpreq == HTTPREQ_POST_FORM)
- && !data->set.post302) {
+ && !(data->set.keep_post & CURL_REDIR_POST_302)) {
infof(data,
"Violate RFC 2616/10.3.3 and switch from POST to GET\n");
data->set.httpreq = HTTPREQ_GET;
@@ -1900,9 +1900,10 @@ CURLcode Curl_follow(struct SessionHandle *data,
break;
case 303: /* See Other */
- /* Disable both types of POSTs, since doing a second POST when
- * following isn't what anyone would want! */
- if(data->set.httpreq != HTTPREQ_GET) {
+ /* Disable both types of POSTs, unless the user explicitely
+ asks for POST after POST */
+ if(data->set.httpreq != HTTPREQ_GET
+ && !(data->set.keep_post & CURL_REDIR_POST_303)) {
data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
infof(data, "Disables POST, goes with %s\n",
data->set.opt_no_body?"HEAD":"GET");
diff --git a/lib/url.c b/lib/url.c
index 01e217cd9..9ae977e11 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -1111,12 +1111,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* 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
+ * CURL_REDIR_POST_303 - POST is kept as POST after 303
+ * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
* other - POST is kept as POST after 301 and 302
*/
long postRedir = va_arg(param, long);
- data->set.post301 = (postRedir & CURL_REDIR_POST_301)?TRUE:FALSE;
- data->set.post302 = (postRedir & CURL_REDIR_POST_302)?TRUE:FALSE;
+ data->set.keep_post = postRedir & CURL_REDIR_POST_ALL;
}
break;
diff --git a/lib/urldata.h b/lib/urldata.h
index b27fc6bf7..3474431cb 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1368,9 +1368,9 @@ struct UserDefined {
long followlocation; /* as in HTTP Location: */
long maxredirs; /* maximum no. of http(s) redirects to follow, set to -1
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 */
+
+ int keep_post; /* keep POSTs as POSTs after a 30x request; each
+ bit represents a request, from 301 to 303 */
bool free_referer; /* set TRUE if 'referer' points to a string we
allocated */
void *postfields; /* if POST, set the fields' values here */