зеркало из https://github.com/mozilla/pjs.git
fix for bug 48202 - HTTP 307 redirect behavior violates RFC2616 [should preserve request method]. r-dougt,sr-darin.
This commit is contained in:
Родитель
aa98771054
Коммит
3f83cc0661
|
@ -732,6 +732,54 @@ nsHttpChannel::ProcessNormal()
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHttpChannel::GetCallback(const nsIID &aIID, void **aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_ASSERTION(aResult, "Invalid argument in GetCallback!");
|
||||
rv = mCallbacks->GetInterface(aIID, aResult);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (mLoadGroup) {
|
||||
nsCOMPtr<nsIInterfaceRequestor> cbs;
|
||||
rv = mLoadGroup->GetNotificationCallbacks(getter_AddRefs(cbs));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = cbs->GetInterface(aIID, aResult);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHttpChannel::PromptTempRedirect()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIStringBundleService> bundleService =
|
||||
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIStringBundle> stringBundle;
|
||||
rv = bundleService->CreateBundle(NECKO_MSGS_URL, getter_AddRefs(stringBundle));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsXPIDLString messageString;
|
||||
rv = stringBundle->GetStringFromName(NS_LITERAL_STRING("RepostFormData").get(), getter_Copies(messageString));
|
||||
//GetStringFromName can return NS_OK and NULL messageString.
|
||||
if (NS_SUCCEEDED(rv) && messageString) {
|
||||
PRBool repost = PR_FALSE;
|
||||
nsCOMPtr<nsIPrompt> prompt;
|
||||
rv = GetCallback(NS_GET_IID(nsIPrompt), getter_AddRefs(prompt));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (prompt) {
|
||||
prompt->Confirm(nsnull, messageString, &repost);
|
||||
if (!repost)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsHttpChannel <byte-range>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1556,6 +1604,32 @@ nsHttpChannel::ProcessRedirection(PRUint32 redirectType)
|
|||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
|
||||
if (httpChannel) {
|
||||
if (redirectType == 307 && mUploadStream) {
|
||||
//307 is Temporary Redirect response. Redirect the postdata to the new URI.
|
||||
rv = PromptTempRedirect();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(httpChannel, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (mUploadStreamHasHeaders)
|
||||
uploadChannel->SetUploadStream(mUploadStream, NS_LITERAL_CSTRING(""), -1);
|
||||
else {
|
||||
const char *ctype;
|
||||
ctype = mRequestHead.PeekHeader(nsHttp::Content_Type);
|
||||
const char *clength;
|
||||
clength = mRequestHead.PeekHeader(nsHttp::Content_Length);
|
||||
uploadChannel->SetUploadStream(mUploadStream, nsDependentCString(ctype), atoi(clength));
|
||||
}
|
||||
|
||||
httpChannel->SetRequestMethod(nsDependentCString(mRequestHead.Method()));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIHttpChannelInternal> httpInternal = do_QueryInterface(newChannel);
|
||||
NS_ENSURE_TRUE(httpInternal, NS_ERROR_UNEXPECTED);
|
||||
|
||||
|
@ -1929,21 +2003,9 @@ nsHttpChannel::PromptForUserPass(const char *host,
|
|||
LOG(("nsHttpChannel::PromptForUserPass [this=%x realm=%s]\n", this, realm));
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIAuthPrompt> authPrompt(do_GetInterface(mCallbacks, &rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
// Ok, perhaps the loadgroup's notification callbacks provide an auth prompt...
|
||||
if (mLoadGroup) {
|
||||
nsCOMPtr<nsIInterfaceRequestor> cbs;
|
||||
rv = mLoadGroup->GetNotificationCallbacks(getter_AddRefs(cbs));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
authPrompt = do_GetInterface(cbs, &rv);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
// Unable to prompt -- return
|
||||
NS_WARNING("notification callbacks should provide nsIAuthPrompt");
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIAuthPrompt> authPrompt;
|
||||
rv = GetCallback(NS_GET_IID(nsIAuthPrompt), getter_AddRefs(authPrompt));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// construct the domain string
|
||||
// we always add the port to domain since it is used
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "nsIOutputStream.h"
|
||||
#include "nsIAsyncInputStream.h"
|
||||
#include "nsIInputStreamPump.h"
|
||||
#include "nsIPrompt.h"
|
||||
|
||||
class nsHttpResponseHead;
|
||||
class nsHttpAuthCache;
|
||||
|
@ -117,6 +118,8 @@ private:
|
|||
nsresult ProcessNotModified();
|
||||
nsresult ProcessRedirection(PRUint32 httpStatus);
|
||||
nsresult ProcessAuthentication(PRUint32 httpStatus);
|
||||
nsresult GetCallback(const nsIID &aIID, void **aResult);
|
||||
nsresult PromptTempRedirect();
|
||||
|
||||
// cache specific methods
|
||||
nsresult OpenCacheEntry(PRBool offline, PRBool *delayed);
|
||||
|
|
|
@ -48,6 +48,7 @@ EnterUserPasswordForProxy=Enter username and password for proxy at %1$S
|
|||
EnterUserPasswordFor=Enter username and password for %1$S
|
||||
EnterPasswordFor=Enter password for %1$S on %2$S
|
||||
UnsupportedFTPServer=The FTP server %1$S is currently unsupported.
|
||||
RepostFormData=This web page is being redirected to a new location. Would you like to resend the form data you have typed to the new location?
|
||||
|
||||
# Directory listing strings
|
||||
DirTitle=Index of %1$S
|
||||
|
|
Загрузка…
Ссылка в новой задаче