Fixed bug 27024. Changed nsIHTTPChannel.idl to have proxy host/port

accessors and modifiers. Channels may now override the proxy setting
from the HTTP handler. r=valeski

Fixed bug 24329. Made mProxyAuthList in nsAuthEngine to keep the list of proxy authentications. Logout now clears both proxy and basic auths. r=rjc

Fixed bug 26149. Authenticate now aborts only if the user doesn't click cancel on the PromptUserPass dialog. Removed the unnecessary nsIChannel* parameter on Authenticate. r=rjc

Fixed bug 24304. We now register a callback for proxy preferences. r=rjc

Fixed bug 17158. We now honor "network.proxy.no_proxies_on" preference to diable proxy activity on specified host or domain. We still need a fix for 27141 to read and write this pref correctly. r=rjc

Fixed bug 16442. Referer is only added if its an http URI. r=rjc
This commit is contained in:
gagan%netscape.com 2000-02-11 00:47:50 +00:00
parent 1f2e7dbe1b
commit fa0c3e93e6
12 changed files with 507 additions and 168 deletions

View File

@ -4,3 +4,4 @@
netCore.h
nsNetUtil.h
nsUnixColorPrintf.h

View File

@ -59,6 +59,7 @@ XPIDLSRCS = \
EXPORTS = \
netCore.h \
nsNetUtil.h \
nsUnixColorPrintf.h \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -27,6 +27,7 @@ include <$(DEPTH)/config/config.mak>
EXPORTS = \
netCore.h \
nsNetUtil.h \
nsUnixColorPrintf.h \
$(NULL)
XPIDLSRCS = \

View File

@ -55,6 +55,11 @@ interface nsIHTTPChannel : nsIChannel
*/
attribute nsIInputStream PostDataStream;
/* Since multiple inheritence is not supported in idl */
attribute string ProxyHost;
attribute long ProxyPort;
attribute PRBool UsingProxy;
/*
Response funtions. A call to any of these implicitly calls Load() on this
protocol instance.

View File

@ -26,22 +26,33 @@
#include "nsCRT.h"
#include "plstr.h"
#include "nsXPIDLString.h"
#include "nsString.h"
#include "nsIIOService.h"
#include "nsUnixColorPrintf.h"
#include "nsIServiceManager.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
nsAuthEngine::nsAuthEngine()
{
if (NS_FAILED(NS_NewISupportsArray(getter_AddRefs(mAuthList))))
NS_ERROR("unable to create new auth list");
if (NS_FAILED(NS_NewISupportsArray(getter_AddRefs(mProxyAuthList))))
NS_ERROR("unable to create new auth list");
}
nsAuthEngine::~nsAuthEngine()
{
mAuthList->Clear();
mProxyAuthList->Clear();
}
nsresult
nsAuthEngine::Logout()
{
return mAuthList->Clear();
return NS_SUCCEEDED(mAuthList->Clear()) &&
NS_SUCCEEDED(mProxyAuthList->Clear()) ?
NS_OK : NS_ERROR_FAILURE;
}
nsresult
@ -52,7 +63,6 @@ nsAuthEngine::GetAuthString(nsIURI* i_URI, char** o_AuthString)
return NS_ERROR_NULL_POINTER;
*o_AuthString = nsnull;
NS_ASSERTION(mAuthList, "No auth list!");
// or should we try and make this
if (!mAuthList) return NS_ERROR_FAILURE;
nsXPIDLCString host;
@ -82,8 +92,7 @@ nsAuthEngine::GetAuthString(nsIURI* i_URI, char** o_AuthString)
if (auth->uri.get() == i_URI)
{
*o_AuthString = nsCRT::strdup(auth->encodedString);
if (!*o_AuthString) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
return (!*o_AuthString) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}
/*
@ -124,26 +133,93 @@ nsAuthEngine::GetAuthString(nsIURI* i_URI, char** o_AuthString)
PL_strlen(authDir))))
{
*o_AuthString = nsCRT::strdup(auth->encodedString);
if (!*o_AuthString) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
return (!*o_AuthString) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}
}
return rv;
}
nsresult
nsAuthEngine::SetAuthString(nsIURI* i_URI, const char* i_AuthString)
nsAuthEngine::SetAuth(nsIURI* i_URI,
const char* i_AuthString,
PRBool bProxyAuth)
{
if (!i_URI || !i_AuthString)
return NS_ERROR_NULL_POINTER;
NS_ASSERTION(mAuthList, "No authentication list");
NS_ASSERTION(bProxyAuth ? mProxyAuthList : mAuthList,
"No authentication list");
if ((bProxyAuth && !mProxyAuthList) || (!bProxyAuth && !mAuthList))
return NS_ERROR_FAILURE;
// TODO Extract user/pass info if available
nsAuth* auth = new nsAuth(i_URI, i_AuthString);
if (!auth)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = mAuthList->AppendElement(auth) ? NS_OK : NS_ERROR_FAILURE;
// We have to replace elements with earliar matching...TODO
return
bProxyAuth ?
(mProxyAuthList->AppendElement(auth) ? NS_OK : NS_ERROR_FAILURE):
(mAuthList->AppendElement(auth) ? NS_OK : NS_ERROR_FAILURE);
}
nsresult
nsAuthEngine::GetProxyAuthString(const char* i_Host,
PRInt32 i_Port,
char* *o_AuthString)
{
nsresult rv = NS_OK;
if (!o_AuthString)
return NS_ERROR_NULL_POINTER;
*o_AuthString = nsnull;
NS_ASSERTION(mProxyAuthList, "No proxy auth list!");
if (!mProxyAuthList)
return NS_ERROR_FAILURE;
PRUint32 count=0;
(void)mProxyAuthList->Count(&count);
if (count <=0)
return NS_OK; // not found...
nsXPIDLCString authHost;
PRInt32 authPort;
for (PRInt32 i = count-1; i>=0; --i)
{
nsAuth* auth = (nsAuth*)mProxyAuthList->ElementAt(i);
(void) auth->uri->GetHost(getter_Copies(authHost));
(void)auth->uri->GetPort(&authPort);
if ((0 == PL_strncasecmp(authHost, i_Host,
PL_strlen(authHost))) &&
(i_Port == authPort))
{
*o_AuthString = nsCRT::strdup(auth->encodedString);
return (!*o_AuthString) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}
}
return rv;
}
nsresult
nsAuthEngine::SetProxyAuthString(const char* host,
PRInt32 port,
const char* i_AuthString)
{
nsresult rv;
nsCAutoString spec("http://");
nsCOMPtr<nsIURI> uri;
spec.Append(host);
spec.Append(':');
spec.Append(port);
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = serv->NewURI(spec.GetBuffer(), nsnull, getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
return SetAuth(uri, i_AuthString, PR_TRUE);
}

View File

@ -31,6 +31,9 @@ class nsIURI;
The nsAuthEngine class is the central class for handling
authentication lists, checks etc.
There should be a class nsProxyAuthEngine that shares all this...
I will move it that way... someday...
-Gagan Saksena 11/12/99
*/
class nsAuthEngine
@ -40,26 +43,44 @@ public:
nsAuthEngine(void);
virtual ~nsAuthEngine();
/*
enum authType { Basic, Digest }
*/
// Set an auth string
NS_IMETHOD SetAuthString(nsIURI* i_URI,
const char* i_AuthString /*, int* type */);
// Get an auth string
NS_IMETHOD GetAuthString(nsIURI* i_URI,
char** o_AuthString /*, int* type */);
NS_IMETHOD GetAuthString(nsIURI* i_URI, char** o_AuthString);
// Set an auth string
NS_IMETHOD SetAuthString(nsIURI* i_URI, const char* i_AuthString);
// Get a proxy auth string with host/port
NS_IMETHOD GetProxyAuthString(const char* host,
PRInt32 port,
char** o_AuthString);
// Set a proxy auth string
NS_IMETHOD SetProxyAuthString(const char* host,
PRInt32 port,
const char* i_AuthString);
/*
Expire all existing auth list entries.
Expire all existing auth list entries including proxy auths.
*/
NS_IMETHOD Logout(void);
protected:
NS_IMETHOD SetAuth(nsIURI* i_URI,
const char* i_AuthString,
PRBool bProxyAuth = PR_FALSE);
nsCOMPtr<nsISupportsArray> mAuthList;
// this needs to be a list becuz pac can produce more ...
nsCOMPtr<nsISupportsArray> mProxyAuthList;
};
inline nsresult
nsAuthEngine::SetAuthString(nsIURI* i_URI, const char* i_AuthString)
{
return SetAuth(i_URI, i_AuthString);
}
#endif /* _nsAuthEngine_h_ */

View File

@ -50,6 +50,7 @@
#include "nsINetDataCacheManager.h"
#include "nsINetDataCache.h"
#include "nsIScriptSecurityManager.h"
#include "nsIProxy.h"
#include "nsMimeTypes.h"
#ifdef DEBUG_gagan
@ -105,6 +106,8 @@ nsHTTPChannel::nsHTTPChannel(nsIURI* i_URL,
mFiredOpenOnStartRequest(PR_FALSE),
mAuthTriedWithPrehost(PR_FALSE),
mUsingProxy(PR_FALSE),
mProxy(0),
mProxyPort(-1),
mBufferSegmentSize(bufferSegmentSize),
mBufferMaxSize(bufferMaxSize)
{
@ -130,6 +133,7 @@ nsHTTPChannel::~nsHTTPChannel()
mEventSink = null_nsCOMPtr();
mResponseContext = null_nsCOMPtr();
mLoadGroup = null_nsCOMPtr();
CRTFREEIF(mProxy);
}
NS_IMPL_ISUPPORTS4(nsHTTPChannel, nsIHTTPChannel, nsIChannel, nsIInterfaceRequestor, nsIProgressEventSink);
@ -614,7 +618,8 @@ nsHTTPChannel::OnStatus(nsIChannel *aChannel,
nsresult rv = NS_OK;
if (mCallbacks) {
nsCOMPtr<nsIProgressEventSink> progressProxy;
rv = mCallbacks->GetInterface(NS_GET_IID(nsIProgressEventSink), getter_AddRefs(progressProxy));
rv = mCallbacks->GetInterface(NS_GET_IID(nsIProgressEventSink),
getter_AddRefs(progressProxy));
if (NS_FAILED(rv)) return rv;
rv = progressProxy->OnStatus(this, aContext, aMsg);
}
@ -1250,7 +1255,7 @@ nsresult nsHTTPChannel::Redirect(const char *aNewLocation,
newURLSpec = nsnull;
log_rv = newURI->GetSpec(&newURLSpec);
if (NS_FAILED(log_rv))
newURLSpec = nsCRT::strdup("?");
newURLSpec = nsCRT::strdup("?");
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
("ProcessRedirect [this=%x].\tRedirecting to: %s.\n",
this, newURLSpec));
@ -1435,16 +1440,13 @@ nsresult nsHTTPChannel::OnHeadersAvailable()
nsresult
nsHTTPChannel::Authenticate(const char *iChallenge,
nsIChannel **oChannel, PRBool iProxyAuth)
nsHTTPChannel::Authenticate(const char *iChallenge, PRBool iProxyAuth)
{
nsresult rv = NS_ERROR_FAILURE;
nsCOMPtr <nsIChannel> channel;
if (!oChannel || !iChallenge)
nsIChannel* channel;
if (!iChallenge)
return NS_ERROR_NULL_POINTER;
*oChannel = nsnull; // Initialize...
// Determine the new username password combination to use
char* newUserPass = nsnull;
if (!mAuthTriedWithPrehost && !iProxyAuth) // Proxy auth's never in prehost
@ -1526,11 +1528,9 @@ nsHTTPChannel::Authenticate(const char *iChallenge,
}
CRTFREEIF(newUserPass);
newUserPass = temp.ToNewCString();
#ifdef DEBUG_gagan
PRINTF_BLUE;
printf("UserPassword- %s",newUserPass);
#endif
}
else
return rv;
}
// Construct the auth string request header based on info provided.
@ -1557,8 +1557,10 @@ nsHTTPChannel::Authenticate(const char *iChallenge,
mCallbacks,
mLoadAttributes, mOriginalURI,
mBufferSegmentSize, mBufferMaxSize,
getter_AddRefs(channel));
&channel);// delibrately...
if (NS_FAILED(rv)) return rv;
if (!channel)
return NS_ERROR_OUT_OF_MEMORY;
nsCOMPtr<nsIHTTPChannel> httpChannel = do_QueryInterface(channel);
NS_ASSERTION(httpChannel, "Something terrible happened..!");
@ -1575,16 +1577,13 @@ nsHTTPChannel::Authenticate(const char *iChallenge,
// Fire the new request...
rv = channel->AsyncRead(0, -1, mResponseContext, mResponseDataListener);
*oChannel = channel;
NS_ADDREF(*oChannel);
return rv;
}
nsresult
nsHTTPChannel::SetUsingProxy(PRBool i_UsingProxy)
{
mUsingProxy = i_UsingProxy;
return NS_OK;
// Abort the current response... This will disconnect the consumer from
// the response listener... Thus allowing the entity that follows to
// be discarded without notifying the consumer...
Abort();
return rv;
}
nsresult
@ -1622,9 +1621,7 @@ nsHTTPChannel::FinishedResponseHeaders(void)
// If a redirect (ie. 30x) occurs, the mResponseDataListener is
// released and a new request is issued...
//
rv = ProcessStatusCode();
return rv;
return ProcessStatusCode();
}
nsresult
@ -1636,18 +1633,32 @@ nsHTTPChannel::ProcessStatusCode(void)
statusCode = 0;
mResponse->GetStatus(&statusCode);
if ( statusCode != 401 && mAuthTriedWithPrehost) {
// We know this auth challenge response was successful. Cache any
// authentication so that future accesses can make use of it,
// particularly other URLs loaded from the body of this response.
nsAuthEngine* pEngine;
NS_ASSERTION(mHandler, "HTTP handler went away");
if (NS_SUCCEEDED(mHandler->GetAuthEngine(&pEngine))) {
nsXPIDLCString authString;
rv = GetRequestHeader(nsHTTPAtoms::Authorization, getter_Copies(authString));
if (NS_FAILED(rv)) return rv;
pEngine->SetAuthString(mURI, authString);
NS_ASSERTION(mHandler, "HTTP handler went away");
nsAuthEngine* pEngine;
// We know this auth challenge response was successful. Cache any
// authentication so that future accesses can make use of it,
// particularly other URLs loaded from the body of this response.
if (NS_SUCCEEDED(mHandler->GetAuthEngine(&pEngine)))
{
nsXPIDLCString authString;
if (statusCode != 407)
{
if (mUsingProxy)
{
rv = GetRequestHeader(nsHTTPAtoms::Proxy_Authorization,
getter_Copies(authString));
if (NS_FAILED(rv)) return rv;
pEngine->SetProxyAuthString(
mProxy, mProxyPort, authString);
}
if (statusCode != 401 && mAuthTriedWithPrehost)
{
rv = GetRequestHeader(nsHTTPAtoms::Authorization,
getter_Copies(authString));
pEngine->SetAuthString(mURI, authString);
}
}
}
@ -1835,16 +1846,98 @@ nsHTTPChannel::ProcessAuthentication(PRInt32 aStatusCode)
if (NS_FAILED(rv) || !challenge || !*challenge)
return rv;
nsCOMPtr<nsIChannel> channel;
if (NS_FAILED(rv = Authenticate(challenge,
getter_AddRefs(channel),
(407 == aStatusCode))))
return rv;
return Authenticate(challenge, (407 == aStatusCode));
}
// Abort the current response... This will disconnect the consumer from
// the response listener... Thus allowing the entity that follows to
// be discarded without notifying the consumer...
Abort();
// nsIProxy methods- but not. since we cant multi in idl.
NS_IMETHODIMP
nsHTTPChannel::GetProxyHost(char* *o_ProxyHost)
{
if (!o_ProxyHost)
return NS_ERROR_NULL_POINTER;
if (mProxy)
{
*o_ProxyHost = nsCRT::strdup(mProxy);
return (*o_ProxyHost == nsnull) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}
else
{
*o_ProxyHost = nsnull;
return NS_OK;
}
}
NS_IMETHODIMP
nsHTTPChannel::SetProxyHost(const char* i_ProxyHost)
{
CRTFREEIF(mProxy);
if (i_ProxyHost)
{
mProxy = nsCRT::strdup(i_ProxyHost);
return (mProxy == nsnull) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}
return NS_OK;
}
NS_IMETHODIMP
nsHTTPChannel::GetProxyPort(PRInt32 *aPort)
{
*aPort = mProxyPort;
return NS_OK;
}
NS_IMETHODIMP
nsHTTPChannel::SetProxyPort(PRInt32 i_ProxyPort)
{
mProxyPort = i_ProxyPort;
return NS_OK;
}
NS_IMETHODIMP
nsHTTPChannel::SetUsingProxy(PRBool i_UsingProxy)
{
mUsingProxy = i_UsingProxy;
nsresult rv = NS_OK;
// Check for proxy associated header if needed-
if (mUsingProxy)
{
nsAuthEngine* pAuthEngine = nsnull;
NS_ASSERTION(mHandler, "Handler went away!");
if (!mHandler) return rv;
rv = mHandler->GetAuthEngine(&pAuthEngine);
if (NS_SUCCEEDED(rv) && pAuthEngine)
{
nsXPIDLCString authStr;
nsXPIDLCString proxyHost;
PRInt32 proxyPort;
// When we switch on proxy auto config this will change...
mHandler->GetProxyHost(getter_Copies(proxyHost));
mHandler->GetProxyPort(&proxyPort);
if (NS_SUCCEEDED(pAuthEngine->GetProxyAuthString(proxyHost,
proxyPort,
getter_Copies(authStr))))
{
if (authStr && *authStr)
mRequest->SetHeader(nsHTTPAtoms::Proxy_Authorization,
authStr);
}
// check for auth as well...
if (NS_SUCCEEDED(pAuthEngine->GetAuthString(mURI,
getter_Copies(authStr))))
{
if (authStr && *authStr)
mRequest->SetHeader(nsHTTPAtoms::Authorization,
authStr);
}
}
}
return rv;
}
NS_IMETHODIMP
nsHTTPChannel::GetUsingProxy(PRBool* o_UsingProxy)
{
*o_UsingProxy = mUsingProxy;
return NS_OK;
}

View File

@ -81,7 +81,6 @@ public:
// nsHTTPChannel methods:
nsresult Authenticate(const char *iChallenge,
nsIChannel **oChannel,
PRBool bProxyAuth = PR_FALSE);
nsresult Init(nsILoadGroup *aGroup);
nsresult Open();
@ -100,9 +99,6 @@ public:
nsresult OnHeadersAvailable();
// Set if this channel is using proxy to connect
nsresult SetUsingProxy(PRBool i_UsingProxy);
nsresult FinishedResponseHeaders();
nsresult Abort();
@ -163,7 +159,10 @@ protected:
And so we need to throw a dialog box!
*/
PRBool mAuthTriedWithPrehost;
PRBool mUsingProxy;
char* mProxy;
PRInt32 mProxyPort;
PRUint32 mBufferSegmentSize;
PRUint32 mBufferMaxSize;

View File

@ -70,11 +70,13 @@
// the file nspr.log
//
PRLogModuleInfo* gHTTPLog = nsnull;
#endif /* PR_LOGGING */
#define MAX_NUMBER_OF_OPEN_TRANSPORTS 8
static PRInt32 PR_CALLBACK ProxyPrefsCallback(const char* pref, void* instance);
static const char PROXY_PREFS[] = "network.proxy";
static NS_DEFINE_CID(kStandardUrlCID, NS_STANDARDURL_CID);
static NS_DEFINE_CID(kAuthUrlParserCID, NS_AUTHORITYURLPARSER_CID);
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
@ -114,6 +116,7 @@ static nsresult
CategoryCreateService( const char *category )
{
nsresult rv = NS_OK;
int nFailed = 0;
nsCOMPtr<nsICategoryManager> categoryManager = do_GetService("mozilla.categorymanager.1", &rv);
if (!categoryManager) return rv;
@ -265,14 +268,27 @@ nsHTTPHandler::NewChannel(const char* verb, nsIURI* i_URL,
rv = pChannel->SetNotificationCallbacks(notificationCallbacks);
if (NS_FAILED(rv)) goto done;
PRBool useProxy = mUseProxy && CanUseProxy(i_URL);
if (useProxy)
{
rv = pChannel->SetProxyHost(mProxy);
if (NS_FAILED(rv)) goto done;
rv = pChannel->SetProxyPort(mProxyPort);
if (NS_FAILED(rv)) goto done;
}
rv = pChannel->SetUsingProxy(useProxy);
if (originalURI)
{
// Referer - misspelled, but per the HTTP spec
nsCOMPtr<nsIAtom> key = NS_NewAtom("referer");
nsXPIDLCString spec;
originalURI->GetSpec(getter_Copies(spec));
if (spec)
if (spec && (0 == PL_strncasecmp((const char*)spec,
"http",4)))
{
pChannel->SetRequestHeader(key, spec);
}
}
rv = pChannel->QueryInterface(NS_GET_IID(nsIChannel),
(void**)o_Instance);
@ -552,7 +568,8 @@ nsHTTPHandler::SetProxyPort(PRInt32 i_ProxyPort)
nsHTTPHandler::nsHTTPHandler():
mAcceptLanguages(nsnull),
mDoKeepAlive(PR_FALSE),
mProxy(nsnull),
mNoProxyFor(0),
mProxy(0),
mUseProxy(PR_FALSE)
{
NS_INIT_REFCNT();
@ -563,8 +580,13 @@ nsHTTPHandler::Init()
{
nsresult rv = NS_OK;
NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
mPrefs = do_GetService(kPrefServiceCID, &rv);
if (!mPrefs)
return NS_ERROR_OUT_OF_MEMORY;
mPrefs->RegisterCallback(PROXY_PREFS,
ProxyPrefsCallback, (void*)this);
PrefsChanged();
// initialize the version and app components
mAppName = "Mozilla";
@ -572,14 +594,14 @@ nsHTTPHandler::Init()
mAppSecurity = "N";
nsXPIDLCString locale;
rv = prefs->CopyCharPref("general.useragent.locale",
rv = mPrefs->CopyCharPref("general.useragent.locale",
getter_Copies(locale));
if (NS_SUCCEEDED(rv)) {
mAppLanguage = locale;
}
nsXPIDLCString milestone;
rv = prefs->CopyCharPref("general.milestone",
rv = mPrefs->CopyCharPref("general.milestone",
getter_Copies(milestone));
if (NS_SUCCEEDED(rv)) {
mAppVersion += milestone;
@ -662,49 +684,7 @@ nsHTTPHandler::Init()
rv = NS_NewISupportsArray(getter_AddRefs(mIdleTransports));
if (NS_FAILED(rv)) return rv;
#if 1 // only for keep alive
// This stuff only till Keep-Alive is not switched on by default
PRInt32 keepalive = -1;
rv = prefs->GetIntPref("network.http.keep-alive", &keepalive);
mDoKeepAlive = (keepalive == 1);
#ifdef DEBUG_gagan
printf("Keep-alive switched ");
printf(mDoKeepAlive ? STARTYELLOW "on\n" ENDCOLOR :
STARTRED "off\n" ENDCOLOR);
#endif //DEBUG_gagan
#endif // remove till here
nsXPIDLCString proxyServer;
nsXPIDLCString acceptLanguages;
PRInt32 proxyPort = -1;
PRInt32 type = -1;
rv = prefs->GetIntPref("network.proxy.type", &type);
//WARN for type==2
mUseProxy = (type == 1); //type == 2 is autoconfig stuff.
if (NS_FAILED(rv)) return rv;
rv = prefs->CopyCharPref("network.proxy.http",
getter_Copies(proxyServer));
if (NS_FAILED(rv)) return rv;
rv = prefs->GetIntPref("network.proxy.http_port",&proxyPort);
if (NS_FAILED(rv)) return rv;
if (NS_SUCCEEDED(rv) && (proxyPort>0)) // currently a bug in IntPref
{
rv = SetProxyHost(proxyServer);
if (NS_FAILED(rv)) return rv;
rv = SetProxyPort(proxyPort);
if (NS_FAILED(rv)) return rv;
}
rv = prefs->CopyCharPref("intl.accept_languages",
getter_Copies(acceptLanguages));
if (NS_FAILED(rv)) return rv;
rv = SetAcceptLanguages(acceptLanguages);
if (NS_FAILED(rv)) return rv;
// Startup the http category
// Bring alive the objects in the http-protocol-startup category
CategoryCreateService(NS_HTTP_STARTUP_CATEGORY);
@ -726,9 +706,13 @@ nsHTTPHandler::~nsHTTPHandler()
// Release the Atoms used by the HTTP protocol...
nsHTTPAtoms::ReleaseAtoms();
CRTFREEIF(mAcceptLanguages);
CRTFREEIF(mProxy);
if (mPrefs)
mPrefs->UnregisterCallback(PROXY_PREFS,
ProxyPrefsCallback, (void*)this);
CRTFREEIF(mAcceptLanguages);
CRTFREEIF(mNoProxyFor);
CRTFREEIF(mProxy);
}
nsresult nsHTTPHandler::RequestTransport(nsIURI* i_Uri,
@ -825,24 +809,50 @@ nsresult nsHTTPHandler::RequestTransport(nsIURI* i_Uri,
// if we didn't find any from the keep-alive idlelist
if (*o_pTrans == nsnull)
{
// Create a new one...
if (!mProxy || !mUseProxy)
// Ask the channel for proxy info... since that overrides
PRBool usingProxy;
i_Channel->GetUsingProxy(&usingProxy);
if (usingProxy)
{
rv = CreateTransport(host, port, host,
bufferSegmentSize, bufferMaxSize, &trans);
nsXPIDLCString proxy;
PRInt32 proxyPort = -1;
rv = i_Channel->GetProxyHost(getter_Copies(proxy));
if (NS_FAILED(rv)) return rv;
rv = i_Channel->GetProxyPort(&proxyPort);
if (NS_FAILED(rv)) return rv;
rv = CreateTransport(proxy, proxyPort, host,
bufferSegmentSize, bufferMaxSize, &trans);
}
else
{
rv = CreateTransport(mProxy, mProxyPort, host,
bufferSegmentSize, bufferMaxSize, &trans);
// Create a new one...
if (!mProxy || !mUseProxy || !CanUseProxy(i_Uri))
{
rv = CreateTransport(host, port, host,
bufferSegmentSize, bufferMaxSize, &trans);
// Update the proxy information on the channel
i_Channel->SetProxyHost(mProxy);
i_Channel->SetProxyPort(mProxyPort);
i_Channel->SetUsingProxy(PR_TRUE);
}
else
{
rv = CreateTransport(mProxy, mProxyPort, host,
bufferSegmentSize, bufferMaxSize, &trans);
i_Channel->SetUsingProxy(PR_FALSE);
}
}
if (NS_FAILED(rv)) return rv;
}
i_Channel->SetUsingProxy(mUseProxy);
// Put it in the table...
// XXX this method incorrectly returns a bool
rv = mTransportList->AppendElement(trans) ? NS_OK : NS_ERROR_FAILURE;
rv = mTransportList->AppendElement(trans) ?
NS_OK : NS_ERROR_FAILURE;
if (NS_FAILED(rv)) return rv;
*o_pTrans = trans;
@ -1015,3 +1025,156 @@ nsHTTPHandler::BuildUserAgent() {
return NS_OK;
}
void
nsHTTPHandler::PrefsChanged(const char* pref)
{
PRBool bChangedAll = (pref) ? PR_FALSE : PR_TRUE;
NS_ASSERTION(mPrefs, "No preference service available!");
if (!mPrefs)
return;
nsresult rv = NS_OK;
#if 1 // only for keep alive TODO
// This stuff only till Keep-Alive is not switched on by default
PRInt32 keepalive = -1;
rv = mPrefs->GetIntPref("network.http.keep-alive", &keepalive);
mDoKeepAlive = (keepalive == 1);
#endif // remove till here
if (bChangedAll || !PL_strcmp(pref, "network.proxy.type"))
{
PRInt32 type = -1;
rv = mPrefs->GetIntPref("network.proxy.type",&type);
if (NS_SUCCEEDED(rv))
mUseProxy = (type == 1); // type == 2 is autoconfig stuff
}
if (bChangedAll || !PL_strcmp(pref, "network.proxy.http"))
{
nsXPIDLCString proxyServer;
rv = mPrefs->CopyCharPref("network.proxy.http",
getter_Copies(proxyServer));
if (NS_SUCCEEDED(rv))
SetProxyHost(proxyServer);
}
if (bChangedAll || !PL_strcmp(pref, "network.proxy.http_port"))
{
PRInt32 proxyPort = -1;
rv = mPrefs->GetIntPref("network.proxy.http_port",&proxyPort);
if (NS_SUCCEEDED(rv) && proxyPort>0)
SetProxyPort(proxyPort);
}
if (bChangedAll || !PL_strcmp(pref, "network.proxy.no_proxies_on"))
{
nsXPIDLCString noProxy;
rv = mPrefs->CopyCharPref("network.proxy.no_proxies_on",
getter_Copies(noProxy));
if (NS_SUCCEEDED(rv))
SetDontUseProxyFor(noProxy);
}
// Things read only during initialization...
if (bChangedAll) // intl.accept_languages
{
nsXPIDLCString acceptLanguages;
rv = mPrefs->CopyCharPref("intl.accept_languages",
getter_Copies(acceptLanguages));
if (NS_SUCCEEDED(rv))
SetAcceptLanguages(acceptLanguages);
}
}
PRInt32 PR_CALLBACK ProxyPrefsCallback(const char* pref, void* instance)
{
nsHTTPHandler* pHandler = (nsHTTPHandler*) instance;
NS_ASSERTION(nsnull != pHandler, "bad instance data");
if (nsnull != pHandler)
pHandler->PrefsChanged(pref);
return 0;
}
nsresult
nsHTTPHandler::SetDontUseProxyFor(const char* i_hostlist)
{
CRTFREEIF(mNoProxyFor);
if (i_hostlist)
{
mNoProxyFor = nsCRT::strdup(i_hostlist);
return (mNoProxyFor == nsnull) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}
return NS_OK;
}
PRBool
nsHTTPHandler::CanUseProxy(nsIURI* i_Uri)
{
NS_ASSERTION(mProxy,
"This shouldn't even get called if mProxy is null");
PRBool rv = PR_TRUE;
if (!mNoProxyFor || !*mNoProxyFor)
return rv;
PRInt32 port;
char* host;
rv = i_Uri->GetHost(&host);
if (NS_FAILED(rv)) return rv;
rv = i_Uri->GetPort(&port);
if (NS_FAILED(rv))
{
nsCRT::free(host);
return rv;
}
if (!host)
return rv;
// mNoProxyFor is of type "foo bar:8080, baz.com ..."
char* brk = PL_strpbrk(mNoProxyFor, " ,:");
char* noProxy = mNoProxyFor;
PRInt32 noProxyPort = -1;
int hostLen = PL_strlen(host);
char* end = (char*)host+hostLen;
char* nextbrk = end;
int matchLen = 0;
do
{
if (brk)
{
if (*brk == ':')
{
noProxyPort = atoi(brk+1);
nextbrk = PL_strpbrk(brk+1, " ,");
if (!nextbrk)
nextbrk = end;
}
matchLen = brk-noProxy;
}
else
matchLen = end-noProxy;
if (matchLen <= hostLen) // match is smaller than host
{
if (((noProxyPort == -1) || (noProxyPort == port)) &&
(0 == PL_strncasecmp(host+hostLen-matchLen,
noProxy, matchLen)))
{
nsCRT::free(host);
return PR_FALSE;
}
}
noProxy = nextbrk;
brk = PL_strpbrk(noProxy, " ,:");
}
while (brk);
CRTFREEIF(host);
return rv;
}

View File

@ -45,7 +45,7 @@
#include "nsISupportsArray.h"
#include "nsCRT.h"
#include "nsAuthEngine.h"
#include "nsIProxy.h"
#include "nsIPref.h"
#include "prtime.h"
#include "nsString.h"
@ -89,25 +89,36 @@ public:
virtual nsresult ReleaseTransport(nsIChannel* i_pTrans);
virtual nsresult CancelPendingChannel(nsHTTPChannel* aChannel);
PRTime GetSessionStartTime() { return mSessionStartTime; }
void PrefsChanged(const char* pref = 0);
nsresult FollowRedirects(PRBool bFollow=PR_TRUE);
nsresult SetDontUseProxyFor(const char* i_hostlist);
protected:
virtual ~nsHTTPHandler();
// Determine if this host/port can connect thru proxy
PRBool CanUseProxy(nsIURI* i_Uri);
// This is the array of connections that the handler thread
// maintains to verify unique requests.
nsCOMPtr<nsISupportsArray> mConnections;
nsCOMPtr<nsISupportsArray> mPendingChannelList;
nsAuthEngine mAuthEngine;
nsCOMPtr<nsISupportsArray> mTransportList;
// Transports that are idle (ready to be used again)
nsCOMPtr<nsISupportsArray> mIdleTransports;
char* mAcceptLanguages;
PRBool mDoKeepAlive;
char* mProxy;
PRInt32 mProxyPort;
PRTime mSessionStartTime;
PRBool mUseProxy;
char* mAcceptLanguages;
nsAuthEngine mAuthEngine;
PRBool mDoKeepAlive;
char* mNoProxyFor;
nsCOMPtr<nsIPref> mPrefs;
char* mProxy;
PRInt32 mProxyPort;
PRTime mSessionStartTime;
PRBool mUseProxy;
nsresult BuildUserAgent();
nsCAutoString mAppName;

View File

@ -237,37 +237,6 @@ nsresult nsHTTPRequest::WriteRequest(nsIChannel *aTransport, PRBool aIsProxied)
mTransport = aTransport;
mUsingProxy = aIsProxied;
#if 0 // Make proxy auth persistent later
if (mUsingProxy)
{
// Additional headers for proxy usage
// When Keep-Alive gets ready TODO
//SetHeader(nsHTTPAtoms::Proxy-Connection, "Keep-Alive");
// Add proxy auth stuff-
// Check to see if an authentication header is required
nsAuthEngine* pAuthEngine = nsnull;
NS_WITH_SERVICE(nsIHTTPProtocolHandler, httpHandler, kHTTPHandlerCID, &rv);
if (NS_SUCCEEDED(rv))
{
rv = httpHandler->GetAuthEngine(&pAuthEngine);
if (NS_SUCCEEDED(rv) && pAuthEngine)
{
// Qvq lbh xabj gung t?? Ebg13f n yvar va IVZ? Jbj.
nsXPIDLCString authStr;
//PRUint32 authType = 0;
if (NS_SUCCEEDED(pAuthEngine->GetAuthString(nsnull,
getter_Copies(authStr))))
//&authType)) && (authType == 1))
{
if (authStr && *authStr)
SetHeader(nsHTTPAtoms::Proxy_Authorization, authStr);
}
}
}
}
#endif // 0
PRUint32 loadAttributes;
mConnection->GetLoadAttributes(&loadAttributes);

View File

@ -21,7 +21,6 @@
*/
#include "nspr.h"
#include "nsAuthEngine.h"
#include "nsHTTPRequest.h"
#include "nsIStreamListener.h"
#include "nsHTTPResponseListener.h"