diff --git a/dom/fetch/FetchDriver.cpp b/dom/fetch/FetchDriver.cpp index 74851c80d6e4..a44db5a774e0 100644 --- a/dom/fetch/FetchDriver.cpp +++ b/dom/fetch/FetchDriver.cpp @@ -1432,20 +1432,13 @@ FetchDriver::AsyncOnChannelRedirect(nsIChannel* aOldChannel, nsCOMPtr oldHttpChannel = do_QueryInterface(aOldChannel); nsCOMPtr newHttpChannel = do_QueryInterface(aNewChannel); if (newHttpChannel) { - uint32_t responseCode = 0; - bool rewriteToGET = false; - if (oldHttpChannel && - NS_SUCCEEDED(oldHttpChannel->GetResponseStatus(&responseCode))) { - nsAutoCString method; - mRequest->GetMethod(method); + nsAutoCString method; + mRequest->GetMethod(method); - // Fetch 4.4.11 - rewriteToGET = - ((responseCode == 301 || responseCode == 302) && - method.LowerCaseEqualsASCII("post")) || - (responseCode == 303 && !method.LowerCaseEqualsASCII("get") && - !method.LowerCaseEqualsASCII("head")); - } + // Fetch 4.4.11 + bool rewriteToGET = false; + Unused << oldHttpChannel->ShouldStripRequestBodyHeader(method, + &rewriteToGET); SetRequestHeaders(newHttpChannel, rewriteToGET); } diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp index 8ab9ccc8da26..4ac9e63ee21e 100644 --- a/dom/xhr/XMLHttpRequestMainThread.cpp +++ b/dom/xhr/XMLHttpRequestMainThread.cpp @@ -3324,16 +3324,9 @@ nsresult XMLHttpRequestMainThread::OnRedirectVerifyCallback(nsresult result) { if (NS_SUCCEEDED(result)) { bool rewriteToGET = false; nsCOMPtr oldHttpChannel = GetCurrentHttpChannel(); - if (uint32_t responseCode = 0; - oldHttpChannel && - NS_SUCCEEDED(oldHttpChannel->GetResponseStatus(&responseCode))) { - // Fetch 4.4.11 - rewriteToGET = - ((responseCode == 301 || responseCode == 302) && - mRequestMethod.LowerCaseEqualsASCII("post")) || - (responseCode == 303 && !mRequestMethod.LowerCaseEqualsASCII("get") && - !mRequestMethod.LowerCaseEqualsASCII("head")); - } + // Fetch 4.4.11 + Unused << oldHttpChannel->ShouldStripRequestBodyHeader(mRequestMethod, + &rewriteToGET); mChannel = mNewRedirectChannel; diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index e241b869f7ca..90962040ee9d 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -3352,6 +3352,27 @@ bool HttpBaseChannel::ShouldRewriteRedirectToGET( return false; } +NS_IMETHODIMP +HttpBaseChannel::ShouldStripRequestBodyHeader(const nsACString& aMethod, + bool* aResult) { + *aResult = false; + uint32_t httpStatus = 0; + if (NS_FAILED(GetResponseStatus(&httpStatus))) { + return NS_OK; + } + + nsAutoCString method(aMethod); + nsHttpRequestHead::ParsedMethodType parsedMethod; + nsHttpRequestHead::ParseMethod(method, parsedMethod); + // Fetch 4.4.11, which is slightly different than the perserved method + // algrorithm: strip request-body-header for GET->GET redirection for 303. + *aResult = + ShouldRewriteRedirectToGET(httpStatus, parsedMethod) && + !(httpStatus == 303 && parsedMethod == nsHttpRequestHead::kMethod_Get); + + return NS_OK; +} + HttpBaseChannel::ReplacementChannelConfig HttpBaseChannel::CloneReplacementChannelConfig(bool aPreserveMethod, uint32_t aRedirectFlags, diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h index b9841e67db0e..35bfae136ca0 100644 --- a/netwerk/protocol/http/HttpBaseChannel.h +++ b/netwerk/protocol/http/HttpBaseChannel.h @@ -198,6 +198,8 @@ class HttpBaseChannel : public nsHashPropertyBag, NS_IMETHOD VisitRequestHeaders(nsIHttpHeaderVisitor* visitor) override; NS_IMETHOD VisitNonDefaultRequestHeaders( nsIHttpHeaderVisitor* visitor) override; + NS_IMETHOD ShouldStripRequestBodyHeader(const nsACString& aMethod, + bool* aResult) override; NS_IMETHOD GetResponseHeader(const nsACString& header, nsACString& value) override; NS_IMETHOD SetResponseHeader(const nsACString& header, diff --git a/netwerk/protocol/http/NullHttpChannel.cpp b/netwerk/protocol/http/NullHttpChannel.cpp index 401ca7a6752a..9355ddccedb9 100644 --- a/netwerk/protocol/http/NullHttpChannel.cpp +++ b/netwerk/protocol/http/NullHttpChannel.cpp @@ -231,6 +231,12 @@ NullHttpChannel::VisitOriginalResponseHeaders(nsIHttpHeaderVisitor* aVisitor) { return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP +NullHttpChannel::ShouldStripRequestBodyHeader(const nsACString& aMethod, + bool* aResult) { + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP NullHttpChannel::IsNoStoreResponse(bool* _retval) { return NS_ERROR_NOT_IMPLEMENTED; diff --git a/netwerk/protocol/http/nsIHttpChannel.idl b/netwerk/protocol/http/nsIHttpChannel.idl index ed8e897fac03..04b3b96995cf 100644 --- a/netwerk/protocol/http/nsIHttpChannel.idl +++ b/netwerk/protocol/http/nsIHttpChannel.idl @@ -183,6 +183,12 @@ interface nsIHttpChannel : nsIIdentChannel [must_use] void visitNonDefaultRequestHeaders(in nsIHttpHeaderVisitor aVisitor); + /** + * Call this method to see if we need to strip the request body headers + * for the new http channel. This should be called during redirection. + */ + [must_use] bool ShouldStripRequestBodyHeader(in ACString aMethod); + /** * This attribute no longer has any effect, it remains for backwards compat * diff --git a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp index 8c991063d2da..0e0c995d09be 100644 --- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp +++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp @@ -827,6 +827,14 @@ nsViewSourceChannel::VisitNonDefaultRequestHeaders( : mHttpChannel->VisitNonDefaultRequestHeaders(aVisitor); } +NS_IMETHODIMP +nsViewSourceChannel::ShouldStripRequestBodyHeader(const nsACString& aMethod, + bool* aResult) { + return !mHttpChannel + ? NS_ERROR_NULL_POINTER + : mHttpChannel->ShouldStripRequestBodyHeader(aMethod, aResult); +} + NS_IMETHODIMP nsViewSourceChannel::GetAllowPipelining(bool* aAllowPipelining) { return !mHttpChannel ? NS_ERROR_NULL_POINTER