From c0e139a60db68034e04362694290f7cf422eb924 Mon Sep 17 00:00:00 2001 From: Jay Satiro Date: Thu, 16 Apr 2020 14:15:34 -0400 Subject: 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 --- lib/transfer.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'lib') 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; -- cgit v1.2.3