fix for bug 48202 - HTTP 307 redirect behavior violates RFC2616 [should preserve request method]. r-dougt,sr-darin.

This commit is contained in:
suresh%netscape.com 2003-03-25 01:19:21 +00:00
Родитель 2e6bf27bc3
Коммит ab88bb861d
3 изменённых файлов: 81 добавлений и 15 удалений

Просмотреть файл

@ -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