fixes bug 100022 "make sure redirects are followed correctly when loading a PAC URL" r=biesi a=bsmedberg

This commit is contained in:
darin%meer.net 2005-06-30 20:21:34 +00:00
Родитель d45c1846f8
Коммит 7d5c38dd25
5 изменённых файлов: 55 добавлений и 25 удалений

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

@ -235,9 +235,12 @@ nsIncrementalDownload::ProcessTimeout()
}
// Fetch next chunk
nsCOMPtr<nsIInterfaceRequestor> callbacks = do_QueryInterface(mObserver);
nsCOMPtr<nsIChannel> channel;
nsresult rv = NS_NewChannel(getter_AddRefs(channel), mFinalURI);
nsresult rv = NS_NewChannel(getter_AddRefs(channel), mFinalURI, nsnull,
nsnull, callbacks, mLoadFlags);
if (NS_FAILED(rv))
return rv;

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

@ -154,7 +154,6 @@ PendingPACQuery::OnLookupComplete(nsICancelable *request,
nsPACMan::nsPACMan()
: mLoadEvent(nsnull)
, mShutdown(PR_FALSE)
, mStartingToLoad(PR_FALSE)
{
PR_INIT_CLIST(&mPendingQ);
}
@ -181,7 +180,7 @@ nsPACMan::GetProxyForURI(nsIURI *uri, nsACString &result)
{
NS_ENSURE_STATE(!mShutdown);
if (mStartingToLoad) {
if (IsPACURI(uri)) {
result.Truncate();
return NS_OK;
}
@ -210,8 +209,11 @@ nsPACMan::AsyncGetProxyForURI(nsIURI *uri, nsPACManCallback *callback)
PR_APPEND_LINK(query, &mPendingQ);
// If we're waiting for the PAC file to load, then delay starting the query.
// See OnStreamComplete.
if (IsLoading())
// See OnStreamComplete. However, if this is the PAC URI then query right
// away since we know the result will be DIRECT. We could shortcut some code
// in this case by issuing the callback directly from here, but that would
// require extra code, so we just go through the usual async code path.
if (IsLoading() && !IsPACURI(uri))
return NS_OK;
nsresult rv = query->Start();
@ -241,7 +243,7 @@ nsPACMan::LoadEvent_Destroy(PLEvent *ev)
}
nsresult
nsPACMan::LoadPACFromURI(const nsACString &uriSpec)
nsPACMan::LoadPACFromURI(nsIURI *pacURI)
{
NS_ENSURE_STATE(!mShutdown);
@ -274,7 +276,7 @@ nsPACMan::LoadPACFromURI(const nsACString &uriSpec)
CancelExistingLoad();
mLoader = loader;
mPACSpec = uriSpec;
mPACURI = pacURI;
mPAC = nsnull;
return NS_OK;
}
@ -293,12 +295,8 @@ nsPACMan::StartLoading()
if (ios) {
nsCOMPtr<nsIChannel> channel;
// Calling NewChannel will result in GetProxyForURI being called, and we
// want to make sure that it does not return NS_ERROR_IN_PROGRESS. So,
// we set this flag to cause it to indicate a DIRECT fetch for this URI.
mStartingToLoad = PR_TRUE;
ios->NewChannel(mPACSpec, nsnull, nsnull, getter_AddRefs(channel));
mStartingToLoad = PR_FALSE;
// NOTE: This results in GetProxyForURI being called
ios->NewChannelFromURI(mPACURI, getter_AddRefs(channel));
if (channel) {
channel->SetLoadFlags(nsIRequest::LOAD_BYPASS_CACHE);
@ -347,7 +345,8 @@ nsPACMan::ProcessPendingQ(nsresult status)
}
}
NS_IMPL_ISUPPORTS2(nsPACMan, nsIStreamLoaderObserver, nsIInterfaceRequestor)
NS_IMPL_ISUPPORTS3(nsPACMan, nsIStreamLoaderObserver, nsIInterfaceRequestor,
nsIChannelEventSink)
NS_IMETHODIMP
nsPACMan::OnStreamComplete(nsIStreamLoader *loader,
@ -412,5 +411,19 @@ nsPACMan::GetInterface(const nsIID &iid, void **result)
return CallCreateInstance(NS_DEFAULTAUTHPROMPT_CONTRACTID,
nsnull, iid, result);
// In case loading the PAC file results in a redirect.
if (iid.Equals(NS_GET_IID(nsIChannelEventSink))) {
NS_ADDREF_THIS();
*result = NS_STATIC_CAST(nsIChannelEventSink *, this);
return NS_OK;
}
return NS_ERROR_NO_INTERFACE;
}
NS_IMETHODIMP
nsPACMan::OnChannelRedirect(nsIChannel *oldChannel, nsIChannel *newChannel,
PRUint32 flags)
{
return newChannel->GetURI(getter_AddRefs(mPACURI));
}

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

@ -41,7 +41,9 @@
#include "nsIStreamLoader.h"
#include "nsIInterfaceRequestor.h"
#include "nsIChannelEventSink.h"
#include "nsIProxyAutoConfig.h"
#include "nsIURI.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "prclist.h"
@ -69,7 +71,9 @@ public:
* This class provides an abstraction layer above the PAC thread. The methods
* defined on this class are intended to be called on the main thread only.
*/
class nsPACMan : public nsIStreamLoaderObserver, public nsIInterfaceRequestor
class nsPACMan : public nsIStreamLoaderObserver
, public nsIInterfaceRequestor
, public nsIChannelEventSink
{
public:
NS_DECL_ISUPPORTS
@ -114,10 +118,10 @@ public:
* the PAC file, any asynchronous PAC queries will be queued up to be
* processed once the PAC file finishes loading.
*
* @param uriSpec
* The URI spec of the PAC file to load.
* @param pacURI
* The nsIURI of the PAC file to load.
*/
nsresult LoadPACFromURI(const nsACString &uriSpec);
nsresult LoadPACFromURI(nsIURI *pacURI);
/**
* Returns true if we are currently loading the PAC file.
@ -127,6 +131,7 @@ public:
private:
NS_DECL_NSISTREAMLOADEROBSERVER
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSICHANNELEVENTSINK
~nsPACMan();
@ -147,6 +152,14 @@ private:
*/
nsresult StartLoading();
/**
* Returns true if the given URI matches the URI of our PAC file.
*/
PRBool IsPACURI(nsIURI *uri) {
PRBool result;
return mPACURI && NS_SUCCEEDED(mPACURI->Equals(uri, &result)) && result;
}
/**
* Event fu for calling StartLoading asynchronously.
*/
@ -155,12 +168,11 @@ private:
private:
nsCOMPtr<nsIProxyAutoConfig> mPAC;
nsCString mPACSpec;
nsCOMPtr<nsIURI> mPACURI;
PRCList mPendingQ;
nsCOMPtr<nsIStreamLoader> mLoader;
PLEvent *mLoadEvent;
PRPackedBool mShutdown;
PRPackedBool mStartingToLoad;
PRBool mShutdown;
};
#endif // nsPACMan_h__

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

@ -901,11 +901,14 @@ nsProtocolProxyService::ConfigureFromPAC(const nsACString &spec)
return NS_ERROR_OUT_OF_MEMORY;
}
mPACURI = spec;
mFailedProxies.Clear();
LOG(("LoadPACFromURI(\"%s\")\n", mPACURI.get()));
return mPACMan->LoadPACFromURI(mPACURI);
nsCOMPtr<nsIURI> pacURI;
nsresult rv = NS_NewURI(getter_AddRefs(pacURI), spec);
if (NS_FAILED(rv))
return rv;
return mPACMan->LoadPACFromURI(pacURI);
}
NS_IMETHODIMP

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

@ -370,7 +370,6 @@ protected:
PRInt32 mSOCKSProxyVersion;
PRBool mSOCKSProxyRemoteDNS;
nsCString mPACURI;
nsRefPtr<nsPACMan> mPACMan; // non-null if we are using PAC
PRTime mSessionStart;