aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJay Satiro <raysatiro@yahoo.com>2020-04-16 14:15:34 -0400
committerJay Satiro <raysatiro@yahoo.com>2020-04-22 17:56:17 -0400
commitc0e139a60db68034e04362694290f7cf422eb924 (patch)
treee7c0d414ccf98961d4dc0db1a2512529336c2d58 /lib
parentbffa1165357a5964c44794c253019375c2a80250 (diff)
transfer: Switch PUT to GET/HEAD on 303 redirect
Prior to this change if there was a 303 reply to a PUT request then the subsequent request to respond to that redirect would also be a PUT. It was determined that was most likely incorrect based on the language of the RFCs. Basically 303 means "see other" resource, which implies it is most likely not the same resource, therefore we should not try to PUT to that different resource. Refer to the discussions in #5237 and #5248 for more information. Fixes https://github.com/curl/curl/issues/5237 Closes https://github.com/curl/curl/pull/5248
Diffstat (limited to 'lib')
-rw-r--r--lib/transfer.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/lib/transfer.c b/lib/transfer.c
index d5eb2c327..b9581d7ad 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -1717,12 +1717,19 @@ CURLcode Curl_follow(struct Curl_easy *data,
break;
case 303: /* See Other */
- /* Disable both types of POSTs, unless the user explicitly
- 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",
+ /* 'See Other' location is not the resource but a substitute for the
+ * resource. In this case we switch the method to GET/HEAD, unless the
+ * method is POST and the user specified to keep it as POST.
+ * https://github.com/curl/curl/issues/5237#issuecomment-614641049
+ */
+ if(data->set.httpreq != HTTPREQ_GET &&
+ ((data->set.httpreq != HTTPREQ_POST &&
+ data->set.httpreq != HTTPREQ_POST_FORM &&
+ data->set.httpreq != HTTPREQ_POST_MIME) ||
+ !(data->set.keep_post & CURL_REDIR_POST_303))) {
+ data->set.httpreq = HTTPREQ_GET;
+ data->set.upload = false;
+ infof(data, "Switch to %s\n",
data->set.opt_no_body?"HEAD":"GET");
}
break;