2007-03-22 10:30:00 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
2012-05-21 04:12:37 -07:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#include "nsPACMan.h"
|
|
|
|
#include "nsThreadUtils.h"
|
2012-09-13 14:42:29 -07:00
|
|
|
#include "nsIDNSService.h"
|
|
|
|
#include "nsIDNSListener.h"
|
|
|
|
#include "nsICancelable.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsIAuthPrompt.h"
|
2010-06-16 17:06:17 -07:00
|
|
|
#include "nsIPromptFactory.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsIHttpChannel.h"
|
|
|
|
#include "nsIPrefService.h"
|
|
|
|
#include "nsIPrefBranch.h"
|
|
|
|
#include "nsNetUtil.h"
|
2012-09-13 14:42:29 -07:00
|
|
|
#include "nsAutoPtr.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsCRT.h"
|
|
|
|
#include "prmon.h"
|
2010-08-04 19:15:55 -07:00
|
|
|
#include "nsIAsyncVerifyRedirectCallback.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Check to see if the underlying request was not an error page in the case of
|
|
|
|
// a HTTP request. For other types of channels, just return true.
|
2011-09-28 23:19:26 -07:00
|
|
|
static bool
|
2007-03-22 10:30:00 -07:00
|
|
|
HttpRequestSucceeded(nsIStreamLoader *loader)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIRequest> request;
|
|
|
|
loader->GetRequest(getter_AddRefs(request));
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool result = true; // default to assuming success
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(request);
|
|
|
|
if (httpChannel)
|
|
|
|
httpChannel->GetRequestSucceeded(&result);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
// These objects are stored in nsPACMan::mPendingQ
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
class PendingPACQuery MOZ_FINAL : public PRCList,
|
|
|
|
public nsIDNSListener
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
public:
|
2012-09-13 14:42:29 -07:00
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
NS_DECL_NSIDNSLISTENER
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
PendingPACQuery(nsPACMan *pacMan, nsIURI *uri, nsPACManCallback *callback)
|
|
|
|
: mPACMan(pacMan)
|
|
|
|
, mURI(uri)
|
|
|
|
, mCallback(callback)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-09-13 14:42:29 -07:00
|
|
|
PR_INIT_CLIST(this);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
nsresult Start(uint32_t flags);
|
|
|
|
void Complete(nsresult status, const nsCString &pacString);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
private:
|
2012-09-13 14:42:29 -07:00
|
|
|
nsPACMan *mPACMan; // weak reference
|
|
|
|
nsCOMPtr<nsIURI> mURI;
|
2007-03-22 10:30:00 -07:00
|
|
|
nsRefPtr<nsPACManCallback> mCallback;
|
2012-09-13 14:42:29 -07:00
|
|
|
nsCOMPtr<nsICancelable> mDNSRequest;
|
2007-03-22 10:30:00 -07:00
|
|
|
};
|
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
// This is threadsafe because we implement nsIDNSListener
|
|
|
|
NS_IMPL_THREADSAFE_ISUPPORTS1(PendingPACQuery, nsIDNSListener)
|
2012-09-13 12:22:56 -07:00
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
nsresult
|
|
|
|
PendingPACQuery::Start(uint32_t flags)
|
2012-09-13 12:22:56 -07:00
|
|
|
{
|
2012-09-13 14:42:29 -07:00
|
|
|
if (mDNSRequest)
|
|
|
|
return NS_OK; // already started
|
2012-09-13 12:22:56 -07:00
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID, &rv);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
NS_WARNING("unable to get the DNS service");
|
|
|
|
return rv;
|
2012-09-13 12:22:56 -07:00
|
|
|
}
|
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
nsAutoCString host;
|
|
|
|
rv = mURI->GetAsciiHost(host);
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
2012-09-13 12:22:56 -07:00
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
rv = dns->AsyncResolve(host, flags, this, NS_GetCurrentThread(),
|
|
|
|
getter_AddRefs(mDNSRequest));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
NS_WARNING("DNS AsyncResolve failed");
|
2012-09-13 12:22:56 -07:00
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
return rv;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
// This may be called before or after OnLookupComplete
|
2007-03-22 10:30:00 -07:00
|
|
|
void
|
|
|
|
PendingPACQuery::Complete(nsresult status, const nsCString &pacString)
|
|
|
|
{
|
|
|
|
if (!mCallback)
|
|
|
|
return;
|
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
mCallback->OnQueryComplete(status, pacString);
|
|
|
|
mCallback = nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
if (mDNSRequest) {
|
|
|
|
mDNSRequest->Cancel(NS_ERROR_ABORT);
|
|
|
|
mDNSRequest = nullptr;
|
|
|
|
}
|
2012-09-13 12:22:56 -07:00
|
|
|
}
|
2010-07-18 01:18:55 -07:00
|
|
|
|
2012-09-13 12:22:56 -07:00
|
|
|
NS_IMETHODIMP
|
2012-09-13 14:42:29 -07:00
|
|
|
PendingPACQuery::OnLookupComplete(nsICancelable *request,
|
|
|
|
nsIDNSRecord *record,
|
|
|
|
nsresult status)
|
2012-09-13 12:22:56 -07:00
|
|
|
{
|
2012-09-13 14:42:29 -07:00
|
|
|
// NOTE: we don't care about the results of this DNS query. We issued
|
|
|
|
// this DNS query just to pre-populate our DNS cache.
|
|
|
|
|
|
|
|
mDNSRequest = nullptr; // break reference cycle
|
|
|
|
|
|
|
|
// If we've already completed this query then do nothing.
|
|
|
|
if (!mCallback)
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
// We're no longer pending, so we can remove ourselves.
|
|
|
|
PR_REMOVE_LINK(this);
|
|
|
|
|
|
|
|
nsAutoCString pacString;
|
|
|
|
status = mPACMan->GetProxyForURI(mURI, pacString);
|
|
|
|
Complete(status, pacString);
|
|
|
|
|
|
|
|
NS_RELEASE_THIS();
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
nsPACMan::nsPACMan()
|
2011-10-17 07:59:28 -07:00
|
|
|
: mLoadPending(false)
|
|
|
|
, mShutdown(false)
|
2012-09-13 14:42:29 -07:00
|
|
|
, mScheduledReload(LL_MAXINT)
|
2007-03-22 10:30:00 -07:00
|
|
|
, mLoadFailureCount(0)
|
|
|
|
{
|
2012-09-13 14:42:29 -07:00
|
|
|
PR_INIT_CLIST(&mPendingQ);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
nsPACMan::~nsPACMan()
|
|
|
|
{
|
2012-07-30 07:20:58 -07:00
|
|
|
NS_ASSERTION(mLoader == nullptr, "pac man not shutdown properly");
|
2012-09-13 14:42:29 -07:00
|
|
|
NS_ASSERTION(mPAC == nullptr, "pac man not shutdown properly");
|
|
|
|
NS_ASSERTION(PR_CLIST_IS_EMPTY(&mPendingQ), "pac man not shutdown properly");
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsPACMan::Shutdown()
|
|
|
|
{
|
|
|
|
CancelExistingLoad();
|
2012-09-13 14:42:29 -07:00
|
|
|
ProcessPendingQ(NS_ERROR_ABORT);
|
|
|
|
|
|
|
|
mPAC = nullptr;
|
2011-10-17 07:59:28 -07:00
|
|
|
mShutdown = true;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2012-09-13 14:42:29 -07:00
|
|
|
nsPACMan::GetProxyForURI(nsIURI *uri, nsACString &result)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-09-13 14:42:29 -07:00
|
|
|
NS_ENSURE_STATE(!mShutdown);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
if (IsPACURI(uri)) {
|
2012-09-13 14:42:29 -07:00
|
|
|
result.Truncate();
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
MaybeReloadPAC();
|
|
|
|
|
|
|
|
if (IsLoading())
|
|
|
|
return NS_ERROR_IN_PROGRESS;
|
|
|
|
if (!mPAC)
|
|
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
|
|
|
|
|
|
nsAutoCString spec, host;
|
|
|
|
uri->GetAsciiSpec(spec);
|
|
|
|
uri->GetAsciiHost(host);
|
|
|
|
|
|
|
|
return mPAC->GetProxyForURI(spec, host, result);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2012-09-13 14:42:29 -07:00
|
|
|
nsPACMan::AsyncGetProxyForURI(nsIURI *uri, nsPACManCallback *callback)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2012-09-13 14:42:29 -07:00
|
|
|
NS_ENSURE_STATE(!mShutdown);
|
|
|
|
|
|
|
|
MaybeReloadPAC();
|
|
|
|
|
|
|
|
PendingPACQuery *query = new PendingPACQuery(this, uri, callback);
|
|
|
|
if (!query)
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
NS_ADDREF(query);
|
|
|
|
PR_APPEND_LINK(query, &mPendingQ);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
// If we're waiting for the PAC file to load, then delay starting the query.
|
|
|
|
// 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.
|
|
|
|
int isPACURI = IsPACURI(uri);
|
|
|
|
|
|
|
|
if (IsLoading() && !isPACURI)
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
2012-09-13 14:42:29 -07:00
|
|
|
|
|
|
|
nsresult rv = query->Start(isPACURI ? 0 : nsIDNSService::RESOLVE_SPECULATE);
|
|
|
|
if (rv == NS_ERROR_DNS_LOOKUP_QUEUE_FULL && !isPACURI) {
|
|
|
|
query->OnLookupComplete(NULL, NULL, NS_OK);
|
|
|
|
rv = NS_OK;
|
|
|
|
} else if (NS_FAILED(rv)) {
|
|
|
|
NS_WARNING("failed to start PAC query");
|
|
|
|
PR_REMOVE_LINK(query);
|
|
|
|
NS_RELEASE(query);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
return rv;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsPACMan::LoadPACFromURI(nsIURI *pacURI)
|
|
|
|
{
|
|
|
|
NS_ENSURE_STATE(!mShutdown);
|
|
|
|
NS_ENSURE_ARG(pacURI || mPACURI);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIStreamLoader> loader =
|
|
|
|
do_CreateInstance(NS_STREAMLOADER_CONTRACTID);
|
|
|
|
NS_ENSURE_STATE(loader);
|
|
|
|
|
|
|
|
// Since we might get called from nsProtocolProxyService::Init, we need to
|
|
|
|
// post an event back to the main thread before we try to use the IO service.
|
|
|
|
//
|
|
|
|
// But, we need to flag ourselves as loading, so that we queue up any PAC
|
|
|
|
// queries the enter between now and when we actually load the PAC file.
|
|
|
|
|
|
|
|
if (!mLoadPending) {
|
|
|
|
nsCOMPtr<nsIRunnable> event =
|
2010-04-20 16:21:35 -07:00
|
|
|
NS_NewRunnableMethod(this, &nsPACMan::StartLoading);
|
2007-03-22 10:30:00 -07:00
|
|
|
nsresult rv;
|
|
|
|
if (NS_FAILED(rv = NS_DispatchToCurrentThread(event)))
|
|
|
|
return rv;
|
2011-10-17 07:59:28 -07:00
|
|
|
mLoadPending = true;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
CancelExistingLoad();
|
|
|
|
|
|
|
|
mLoader = loader;
|
|
|
|
if (pacURI) {
|
|
|
|
mPACURI = pacURI;
|
|
|
|
mLoadFailureCount = 0; // reset
|
|
|
|
}
|
2012-09-13 14:42:29 -07:00
|
|
|
mScheduledReload = LL_MAXINT;
|
|
|
|
mPAC = nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsPACMan::StartLoading()
|
|
|
|
{
|
2011-10-17 07:59:28 -07:00
|
|
|
mLoadPending = false;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// CancelExistingLoad was called...
|
|
|
|
if (!mLoader) {
|
2012-09-13 14:42:29 -07:00
|
|
|
ProcessPendingQ(NS_ERROR_ABORT);
|
2007-03-22 10:30:00 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(mLoader->Init(this))) {
|
|
|
|
// Always hit the origin server when loading PAC.
|
|
|
|
nsCOMPtr<nsIIOService> ios = do_GetIOService();
|
|
|
|
if (ios) {
|
|
|
|
nsCOMPtr<nsIChannel> channel;
|
|
|
|
|
|
|
|
// NOTE: This results in GetProxyForURI being called
|
|
|
|
ios->NewChannelFromURI(mPACURI, getter_AddRefs(channel));
|
|
|
|
|
|
|
|
if (channel) {
|
|
|
|
channel->SetLoadFlags(nsIRequest::LOAD_BYPASS_CACHE);
|
|
|
|
channel->SetNotificationCallbacks(this);
|
2012-07-30 07:20:58 -07:00
|
|
|
if (NS_SUCCEEDED(channel->AsyncOpen(mLoader, nullptr)))
|
2007-03-22 10:30:00 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CancelExistingLoad();
|
2012-09-13 14:42:29 -07:00
|
|
|
ProcessPendingQ(NS_ERROR_UNEXPECTED);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
void
|
|
|
|
nsPACMan::MaybeReloadPAC()
|
|
|
|
{
|
|
|
|
if (!mPACURI)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (PR_Now() > mScheduledReload)
|
|
|
|
LoadPACFromURI(nullptr);
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
void
|
|
|
|
nsPACMan::OnLoadFailure()
|
|
|
|
{
|
2012-08-22 08:56:38 -07:00
|
|
|
int32_t minInterval = 5; // 5 seconds
|
|
|
|
int32_t maxInterval = 300; // 5 minutes
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
|
|
|
if (prefs) {
|
|
|
|
prefs->GetIntPref("network.proxy.autoconfig_retry_interval_min",
|
|
|
|
&minInterval);
|
|
|
|
prefs->GetIntPref("network.proxy.autoconfig_retry_interval_max",
|
|
|
|
&maxInterval);
|
|
|
|
}
|
|
|
|
|
2012-08-22 08:56:38 -07:00
|
|
|
int32_t interval = minInterval << mLoadFailureCount++; // seconds
|
2007-03-22 10:30:00 -07:00
|
|
|
if (!interval || interval > maxInterval)
|
|
|
|
interval = maxInterval;
|
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
#ifdef DEBUG
|
|
|
|
printf("PAC load failure: will retry in %d seconds\n", interval);
|
|
|
|
#endif
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
mScheduledReload = PR_Now() + int64_t(interval) * PR_USEC_PER_SEC;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsPACMan::CancelExistingLoad()
|
|
|
|
{
|
|
|
|
if (mLoader) {
|
|
|
|
nsCOMPtr<nsIRequest> request;
|
|
|
|
mLoader->GetRequest(getter_AddRefs(request));
|
|
|
|
if (request)
|
|
|
|
request->Cancel(NS_ERROR_ABORT);
|
2012-07-30 07:20:58 -07:00
|
|
|
mLoader = nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2012-09-13 14:42:29 -07:00
|
|
|
nsPACMan::ProcessPendingQ(nsresult status)
|
2012-09-13 12:22:56 -07:00
|
|
|
{
|
2012-09-13 14:42:29 -07:00
|
|
|
// Now, start any pending queries
|
|
|
|
PRCList *node = PR_LIST_HEAD(&mPendingQ);
|
|
|
|
while (node != &mPendingQ) {
|
|
|
|
PendingPACQuery *query = static_cast<PendingPACQuery *>(node);
|
|
|
|
node = PR_NEXT_LINK(node);
|
|
|
|
if (NS_SUCCEEDED(status)) {
|
|
|
|
// keep the query in the list (so we can complete it from Shutdown if
|
|
|
|
// necessary).
|
|
|
|
status = query->Start(nsIDNSService::RESOLVE_SPECULATE);
|
|
|
|
}
|
|
|
|
if (status == NS_ERROR_DNS_LOOKUP_QUEUE_FULL) {
|
|
|
|
query->OnLookupComplete(NULL, NULL, NS_OK);
|
|
|
|
status = NS_OK;
|
|
|
|
} else if (NS_FAILED(status)) {
|
|
|
|
// remove the query from the list
|
|
|
|
PR_REMOVE_LINK(query);
|
|
|
|
query->Complete(status, EmptyCString());
|
|
|
|
NS_RELEASE(query);
|
|
|
|
}
|
2012-09-13 12:22:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
NS_IMPL_ISUPPORTS3(nsPACMan, nsIStreamLoaderObserver, nsIInterfaceRequestor,
|
|
|
|
nsIChannelEventSink)
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPACMan::OnStreamComplete(nsIStreamLoader *loader,
|
|
|
|
nsISupports *context,
|
|
|
|
nsresult status,
|
2012-08-22 08:56:38 -07:00
|
|
|
uint32_t dataLen,
|
|
|
|
const uint8_t *data)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
if (mLoader != loader) {
|
|
|
|
// If this happens, then it means that LoadPACFromURI was called more
|
|
|
|
// than once before the initial call completed. In this case, status
|
|
|
|
// should be NS_ERROR_ABORT, and if so, then we know that we can and
|
|
|
|
// should delay any processing.
|
|
|
|
if (status == NS_ERROR_ABORT)
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
mLoader = nullptr;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
if (NS_SUCCEEDED(status) && HttpRequestSucceeded(loader)) {
|
|
|
|
// Get the URI spec used to load this PAC script.
|
2012-09-01 19:35:17 -07:00
|
|
|
nsAutoCString pacURI;
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
nsCOMPtr<nsIRequest> request;
|
|
|
|
loader->GetRequest(getter_AddRefs(request));
|
|
|
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
|
|
|
if (channel) {
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
channel->GetURI(getter_AddRefs(uri));
|
|
|
|
if (uri)
|
|
|
|
uri->GetAsciiSpec(pacURI);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
if (!mPAC) {
|
|
|
|
mPAC = do_CreateInstance(NS_PROXYAUTOCONFIG_CONTRACTID, &status);
|
|
|
|
if (!mPAC)
|
|
|
|
NS_WARNING("failed to instantiate PAC component");
|
|
|
|
}
|
|
|
|
if (NS_SUCCEEDED(status)) {
|
|
|
|
// We assume that the PAC text is ASCII (or ISO-Latin-1). We've had this
|
|
|
|
// assumption forever, and some real-world PAC scripts actually have some
|
|
|
|
// non-ASCII text in comment blocks (see bug 296163).
|
|
|
|
const char *text = (const char *) data;
|
|
|
|
status = mPAC->Init(pacURI, NS_ConvertASCIItoUTF16(text, dataLen));
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// Even if the PAC file could not be parsed, we did succeed in loading the
|
|
|
|
// data for it.
|
|
|
|
mLoadFailureCount = 0;
|
|
|
|
} else {
|
|
|
|
// We were unable to load the PAC file (presumably because of a network
|
|
|
|
// failure). Try again a little later.
|
|
|
|
OnLoadFailure();
|
|
|
|
}
|
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
// Reset mPAC if necessary
|
|
|
|
if (mPAC && NS_FAILED(status))
|
|
|
|
mPAC = nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2012-09-13 14:42:29 -07:00
|
|
|
ProcessPendingQ(status);
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPACMan::GetInterface(const nsIID &iid, void **result)
|
|
|
|
{
|
|
|
|
// In case loading the PAC file requires authentication.
|
2010-06-16 17:06:17 -07:00
|
|
|
if (iid.Equals(NS_GET_IID(nsIAuthPrompt))) {
|
|
|
|
nsCOMPtr<nsIPromptFactory> promptFac = do_GetService("@mozilla.org/prompter;1");
|
|
|
|
NS_ENSURE_TRUE(promptFac, NS_ERROR_FAILURE);
|
2012-07-30 07:20:58 -07:00
|
|
|
return promptFac->GetPrompt(nullptr, iid, reinterpret_cast<void**>(result));
|
2010-06-16 17:06:17 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// In case loading the PAC file results in a redirect.
|
|
|
|
if (iid.Equals(NS_GET_IID(nsIChannelEventSink))) {
|
|
|
|
NS_ADDREF_THIS();
|
2007-07-08 00:08:04 -07:00
|
|
|
*result = static_cast<nsIChannelEventSink *>(this);
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_ERROR_NO_INTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2010-08-04 19:15:55 -07:00
|
|
|
nsPACMan::AsyncOnChannelRedirect(nsIChannel *oldChannel, nsIChannel *newChannel,
|
2012-08-22 08:56:38 -07:00
|
|
|
uint32_t flags,
|
2010-08-04 19:15:55 -07:00
|
|
|
nsIAsyncVerifyRedirectCallback *callback)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2010-08-04 19:15:55 -07:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (NS_FAILED((rv = newChannel->GetURI(getter_AddRefs(mPACURI)))))
|
|
|
|
return rv;
|
|
|
|
|
|
|
|
callback->OnRedirectVerifyCallback(NS_OK);
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|