fixes bug 226278 "HTTP authentication cache should include URI scheme in its key" r=cneberg@sandia.gov sr=dveditz a=chofmann
This commit is contained in:
Родитель
1c888c7563
Коммит
4e96b346fa
|
@ -143,7 +143,7 @@ nsJVMAuthTools::GetAuthenticationInfo(const char* protocol,
|
|||
const char* realm,
|
||||
nsIAuthenticationInfo **_retval)
|
||||
{
|
||||
if (!protocol || !host || !realm)
|
||||
if (!protocol || !host || !scheme || !realm)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (!PL_strcasecmp(protocol, "HTTP") && !PL_strcasecmp(protocol, "HTTPS"))
|
||||
|
@ -153,29 +153,32 @@ nsJVMAuthTools::GetAuthenticationInfo(const char* protocol,
|
|||
if (!authManager)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsDependentCString protocolString(protocol);
|
||||
nsDependentCString hostString(host);
|
||||
nsDependentCString schemeString(scheme);
|
||||
nsDependentCString realmString(realm);
|
||||
nsAutoString domainString, username, password;
|
||||
|
||||
nsresult rv = authManager->GetAuthIdentity(hostString,
|
||||
nsresult rv = authManager->GetAuthIdentity(protocolString,
|
||||
hostString,
|
||||
port,
|
||||
schemeString,
|
||||
realmString,
|
||||
nsCString(),
|
||||
EmptyCString(),
|
||||
domainString,
|
||||
username,
|
||||
password);
|
||||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE;
|
||||
else {
|
||||
nsAuthenticationInfoImp* authInfo = new nsAuthenticationInfoImp(
|
||||
ToNewUTF8String(username),
|
||||
ToNewUTF8String(password));
|
||||
NS_ENSURE_TRUE(authInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ADDREF(authInfo);
|
||||
*_retval = authInfo;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAuthenticationInfoImp* authInfo = new nsAuthenticationInfoImp(
|
||||
ToNewUTF8String(username),
|
||||
ToNewUTF8String(password));
|
||||
NS_ENSURE_TRUE(authInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ADDREF(authInfo);
|
||||
*_retval = authInfo;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
|
@ -187,7 +190,7 @@ nsJVMAuthTools::SetAuthenticationInfo(const char* protocol,
|
|||
const char *username,
|
||||
const char *password)
|
||||
{
|
||||
if (!protocol || !host || !realm)
|
||||
if (!protocol || !host || !scheme || !realm)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (!PL_strcasecmp(protocol, "HTTP") && !PL_strcasecmp(protocol, "HTTPS"))
|
||||
|
@ -197,13 +200,17 @@ nsJVMAuthTools::SetAuthenticationInfo(const char* protocol,
|
|||
if (!authManager)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsDependentCString protocolString(protocol);
|
||||
nsDependentCString hostString(host);
|
||||
nsDependentCString schemeString(scheme);
|
||||
nsDependentCString realmString(realm);
|
||||
|
||||
nsresult rv = authManager->SetAuthIdentity(hostString,
|
||||
nsresult rv = authManager->SetAuthIdentity(protocolString,
|
||||
hostString,
|
||||
port,
|
||||
schemeString,
|
||||
realmString,
|
||||
nsCString(),
|
||||
EmptyCString(),
|
||||
nsString(),
|
||||
NS_ConvertUTF8toUCS2(username),
|
||||
NS_ConvertUTF8toUCS2(password));
|
||||
|
|
|
@ -17,61 +17,97 @@
|
|||
* by Sun Microsystem. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
* Darin Fisher <darin@meer.net>
|
||||
* Louie Zhao <louie.zhao@sun.com>
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(81328d02-74df-4724-8a53-8fac43841c5c)]
|
||||
/**
|
||||
* nsIHttpAuthManager
|
||||
*
|
||||
* This service provides access to cached HTTP authentication
|
||||
* user credentials (domain, username, password) for sites
|
||||
* visited during the current browser session.
|
||||
*
|
||||
* This interface exists to provide other HTTP stacks with the
|
||||
* ability to share HTTP authentication credentials with Necko.
|
||||
* This is currently used by the Java plugin (version 1.5 and
|
||||
* higher) to avoid duplicate authentication prompts when the
|
||||
* Java client fetches content from a HTTP site that the user
|
||||
* has already logged into.
|
||||
*/
|
||||
[scriptable, uuid(7ce8e9d1-8b4b-4883-a307-66fe12a50153)]
|
||||
interface nsIHttpAuthManager : nsISupports
|
||||
{
|
||||
/**
|
||||
* Lookup auth identity.
|
||||
*
|
||||
* @param hostPort
|
||||
* the "host:port" of the server issuing a challenge.
|
||||
* @param realm
|
||||
* @param aScheme
|
||||
* the URL scheme (e.g., "http"). NOTE: for proxy authentication,
|
||||
* this should be "http" (this includes authentication for SSL
|
||||
* tunneling).
|
||||
* @param aHost
|
||||
* the host of the server issuing a challenge (ASCII only).
|
||||
* @param aPort
|
||||
* the port of the server issuing a challenge.
|
||||
* @param aAuthType
|
||||
* optional string identifying auth type used (e.g., "basic")
|
||||
* @param aRealm
|
||||
* optional string identifying auth realm.
|
||||
* @param path
|
||||
* @param aPath
|
||||
* optional string identifying auth path. empty for proxy auth.
|
||||
* @param userDomain
|
||||
* @param aUserDomain
|
||||
* return value containing user domain.
|
||||
* @param userName
|
||||
* @param aUserName
|
||||
* return value containing user name.
|
||||
* @param userPassword
|
||||
* @param aUserPassword
|
||||
* return value containing user password.
|
||||
*/
|
||||
void getAuthIdentity(in ACString aHost,
|
||||
void getAuthIdentity(in ACString aScheme,
|
||||
in ACString aHost,
|
||||
in PRInt32 aPort,
|
||||
in ACString aAuthType,
|
||||
in ACString aRealm,
|
||||
in ACString aPath,
|
||||
out AString aUserDomain,
|
||||
out AString aUserName,
|
||||
out AString aUserPassword);
|
||||
|
||||
/**
|
||||
* Store auth identity.
|
||||
*
|
||||
* @param hostPort
|
||||
* the "host:port" of the server issuing a challenge.
|
||||
* @param realm
|
||||
* @param aScheme
|
||||
* the URL scheme (e.g., "http"). NOTE: for proxy authentication,
|
||||
* this should be "http" (this includes authentication for SSL
|
||||
* tunneling).
|
||||
* @param aHost
|
||||
* the host of the server issuing a challenge (ASCII only).
|
||||
* @param aPort
|
||||
* the port of the server issuing a challenge.
|
||||
* @param aAuthType
|
||||
* optional string identifying auth type used (e.g., "basic")
|
||||
* @param aRealm
|
||||
* optional string identifying auth realm.
|
||||
* @param path
|
||||
* @param aPath
|
||||
* optional string identifying auth path. empty for proxy auth.
|
||||
* @param userDomain
|
||||
* @param aUserDomain
|
||||
* optional string containing user domain.
|
||||
* @param userName
|
||||
* @param aUserName
|
||||
* optional string containing user name.
|
||||
* @param userPassword
|
||||
* @param aUserPassword
|
||||
* optional string containing user password.
|
||||
*/
|
||||
void setAuthIdentity(in ACString aHost,
|
||||
void setAuthIdentity(in ACString aScheme,
|
||||
in ACString aHost,
|
||||
in PRInt32 aPort,
|
||||
in ACString aAuthType,
|
||||
in ACString aRealm,
|
||||
in ACString aPath,
|
||||
in AString aUserDomain,
|
||||
in AString aUserName,
|
||||
in AString aUserPassword);
|
||||
|
||||
/**
|
||||
* Clear all auth cache.
|
||||
*/
|
||||
|
|
|
@ -29,10 +29,12 @@
|
|||
#include "prprf.h"
|
||||
|
||||
static inline void
|
||||
GetAuthKey(const char *host, PRInt32 port, nsCString &key)
|
||||
GetAuthKey(const char *scheme, const char *host, PRInt32 port, nsCString &key)
|
||||
{
|
||||
key.Assign(host);
|
||||
key.Append(':');
|
||||
key.Assign(nsDependentCString(scheme) +
|
||||
NS_LITERAL_CSTRING("://") +
|
||||
nsDependentCString(host) +
|
||||
NS_LITERAL_CSTRING(":"));
|
||||
key.AppendInt(port);
|
||||
}
|
||||
|
||||
|
@ -83,16 +85,17 @@ nsHttpAuthCache::Init()
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsHttpAuthCache::GetAuthEntryForPath(const char *host,
|
||||
nsHttpAuthCache::GetAuthEntryForPath(const char *scheme,
|
||||
const char *host,
|
||||
PRInt32 port,
|
||||
const char *path,
|
||||
nsHttpAuthEntry **entry)
|
||||
{
|
||||
LOG(("nsHttpAuthCache::GetAuthEntryForPath [host=%s:%d path=%s]\n",
|
||||
host, port, path));
|
||||
LOG(("nsHttpAuthCache::GetAuthEntryForPath [key=%s://%s:%d path=%s]\n",
|
||||
scheme, host, port, path));
|
||||
|
||||
nsCAutoString key;
|
||||
nsHttpAuthNode *node = LookupAuthNode(host, port, key);
|
||||
nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, key);
|
||||
if (!node)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
|
@ -101,17 +104,18 @@ nsHttpAuthCache::GetAuthEntryForPath(const char *host,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsHttpAuthCache::GetAuthEntryForDomain(const char *host,
|
||||
nsHttpAuthCache::GetAuthEntryForDomain(const char *scheme,
|
||||
const char *host,
|
||||
PRInt32 port,
|
||||
const char *realm,
|
||||
nsHttpAuthEntry **entry)
|
||||
|
||||
{
|
||||
LOG(("nsHttpAuthCache::GetAuthEntryForDomain [host=%s:%d realm=%s]\n",
|
||||
host, port, realm));
|
||||
LOG(("nsHttpAuthCache::GetAuthEntryForDomain [key=%s://%s:%d realm=%s]\n",
|
||||
scheme, host, port, realm));
|
||||
|
||||
nsCAutoString key;
|
||||
nsHttpAuthNode *node = LookupAuthNode(host, port, key);
|
||||
nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, key);
|
||||
if (!node)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
|
@ -120,7 +124,8 @@ nsHttpAuthCache::GetAuthEntryForDomain(const char *host,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsHttpAuthCache::SetAuthEntry(const char *host,
|
||||
nsHttpAuthCache::SetAuthEntry(const char *scheme,
|
||||
const char *host,
|
||||
PRInt32 port,
|
||||
const char *path,
|
||||
const char *realm,
|
||||
|
@ -131,8 +136,8 @@ nsHttpAuthCache::SetAuthEntry(const char *host,
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
LOG(("nsHttpAuthCache::SetAuthEntry [host=%s:%d realm=%s path=%s metadata=%x]\n",
|
||||
host, port, realm, path, metadata));
|
||||
LOG(("nsHttpAuthCache::SetAuthEntry [key=%s://%s:%d realm=%s path=%s metadata=%x]\n",
|
||||
scheme, host, port, realm, path, metadata));
|
||||
|
||||
if (!mDB) {
|
||||
rv = Init();
|
||||
|
@ -140,7 +145,7 @@ nsHttpAuthCache::SetAuthEntry(const char *host,
|
|||
}
|
||||
|
||||
nsCAutoString key;
|
||||
nsHttpAuthNode *node = LookupAuthNode(host, port, key);
|
||||
nsHttpAuthNode *node = LookupAuthNode(scheme, host, port, key);
|
||||
|
||||
if (!node) {
|
||||
// create a new entry node and set the given entry
|
||||
|
@ -159,7 +164,8 @@ nsHttpAuthCache::SetAuthEntry(const char *host,
|
|||
}
|
||||
|
||||
void
|
||||
nsHttpAuthCache::ClearAuthEntry(const char *host,
|
||||
nsHttpAuthCache::ClearAuthEntry(const char *scheme,
|
||||
const char *host,
|
||||
PRInt32 port,
|
||||
const char *realm)
|
||||
{
|
||||
|
@ -167,7 +173,7 @@ nsHttpAuthCache::ClearAuthEntry(const char *host,
|
|||
return;
|
||||
|
||||
nsCAutoString key;
|
||||
GetAuthKey(host, port, key);
|
||||
GetAuthKey(scheme, host, port, key);
|
||||
PL_HashTableRemove(mDB, key.get());
|
||||
}
|
||||
|
||||
|
@ -188,12 +194,15 @@ nsHttpAuthCache::ClearAll()
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsHttpAuthNode *
|
||||
nsHttpAuthCache::LookupAuthNode(const char *host, PRInt32 port, nsCString &key)
|
||||
nsHttpAuthCache::LookupAuthNode(const char *scheme,
|
||||
const char *host,
|
||||
PRInt32 port,
|
||||
nsCString &key)
|
||||
{
|
||||
if (!mDB)
|
||||
return nsnull;
|
||||
|
||||
GetAuthKey(host, port, key);
|
||||
GetAuthKey(scheme, host, port, key);
|
||||
|
||||
return (nsHttpAuthNode *) PL_HashTableLookup(mDB, key.get());
|
||||
}
|
||||
|
|
|
@ -205,28 +205,31 @@ public:
|
|||
|
||||
nsresult Init();
|
||||
|
||||
// |host| and |port| are required
|
||||
// |scheme|, |host|, and |port| are required
|
||||
// |path| can be null
|
||||
// |entry| is either null or a weak reference
|
||||
nsresult GetAuthEntryForPath(const char *host,
|
||||
nsresult GetAuthEntryForPath(const char *scheme,
|
||||
const char *host,
|
||||
PRInt32 port,
|
||||
const char *path,
|
||||
nsHttpAuthEntry **entry);
|
||||
|
||||
// |host| and |port| are required
|
||||
// |scheme|, |host|, and |port| are required
|
||||
// |realm| must not be null
|
||||
// |entry| is either null or a weak reference
|
||||
nsresult GetAuthEntryForDomain(const char *host,
|
||||
nsresult GetAuthEntryForDomain(const char *scheme,
|
||||
const char *host,
|
||||
PRInt32 port,
|
||||
const char *realm,
|
||||
nsHttpAuthEntry **entry);
|
||||
|
||||
// |host| and |port| are required
|
||||
// |scheme|, |host|, and |port| are required
|
||||
// |path| can be null
|
||||
// |realm| must not be null
|
||||
// if |credentials|, |user|, |pass|, and |challenge| are each
|
||||
// null, then the entry is deleted.
|
||||
nsresult SetAuthEntry(const char *host,
|
||||
nsresult SetAuthEntry(const char *scheme,
|
||||
const char *host,
|
||||
PRInt32 port,
|
||||
const char *directory,
|
||||
const char *realm,
|
||||
|
@ -235,7 +238,8 @@ public:
|
|||
const nsHttpAuthIdentity &ident,
|
||||
nsISupports *metadata);
|
||||
|
||||
void ClearAuthEntry(const char *host,
|
||||
void ClearAuthEntry(const char *scheme,
|
||||
const char *host,
|
||||
PRInt32 port,
|
||||
const char *realm);
|
||||
|
||||
|
@ -243,7 +247,10 @@ public:
|
|||
nsresult ClearAll();
|
||||
|
||||
private:
|
||||
nsHttpAuthNode *LookupAuthNode(const char *host, PRInt32 port, nsCString &key);
|
||||
nsHttpAuthNode *LookupAuthNode(const char *scheme,
|
||||
const char *host,
|
||||
PRInt32 port,
|
||||
nsCString &key);
|
||||
|
||||
// hash table allocation functions
|
||||
static void* PR_CALLBACK AllocTable(void *, PRSize size);
|
||||
|
|
|
@ -49,13 +49,22 @@ nsHttpAuthManager::nsHttpAuthManager()
|
|||
|
||||
nsresult nsHttpAuthManager::Init()
|
||||
{
|
||||
// get reference to the auth cache. we assume that we will live
|
||||
// as long as gHttpHandler. instantiate it if necessary.
|
||||
|
||||
if (!gHttpHandler) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIIOService> ios = do_GetIOService(&rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIProtocolHandler> handler;
|
||||
rv = ios->GetProtocolHandler("http", getter_AddRefs(handler));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// maybe someone is overriding our HTTP handler implementation?
|
||||
NS_ENSURE_TRUE(gHttpHandler, NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
||||
mAuthCache = gHttpHandler->AuthCache();
|
||||
|
@ -68,8 +77,10 @@ nsHttpAuthManager::~nsHttpAuthManager()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpAuthManager::GetAuthIdentity(const nsACString & aHost,
|
||||
nsHttpAuthManager::GetAuthIdentity(const nsACString & aScheme,
|
||||
const nsACString & aHost,
|
||||
PRInt32 aPort,
|
||||
const nsACString & aAuthType,
|
||||
const nsACString & aRealm,
|
||||
const nsACString & aPath,
|
||||
nsAString & aUserDomain,
|
||||
|
@ -79,30 +90,34 @@ nsHttpAuthManager::GetAuthIdentity(const nsACString & aHost,
|
|||
nsHttpAuthEntry * entry = nsnull;
|
||||
nsresult rv;
|
||||
if (!aPath.IsEmpty())
|
||||
rv = mAuthCache->GetAuthEntryForPath(PromiseFlatCString(aHost).get(),
|
||||
rv = mAuthCache->GetAuthEntryForPath(PromiseFlatCString(aScheme).get(),
|
||||
PromiseFlatCString(aHost).get(),
|
||||
aPort,
|
||||
PromiseFlatCString(aPath).get(),
|
||||
&entry);
|
||||
else
|
||||
rv = mAuthCache->GetAuthEntryForDomain(PromiseFlatCString(aHost).get(),
|
||||
aPort,
|
||||
PromiseFlatCString(aRealm).get(),
|
||||
&entry);
|
||||
&entry);
|
||||
else
|
||||
rv = mAuthCache->GetAuthEntryForDomain(PromiseFlatCString(aScheme).get(),
|
||||
PromiseFlatCString(aHost).get(),
|
||||
aPort,
|
||||
PromiseFlatCString(aRealm).get(),
|
||||
&entry);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (!entry)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
aUserDomain.Assign(entry->Domain());
|
||||
aUserName.Assign(entry->User());
|
||||
aUserPassword.Assign(entry->Pass());
|
||||
//TODO: nsHttpAuthEntry has no "domain", which will be solved in bug 159015.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpAuthManager::SetAuthIdentity(const nsACString & aHost,
|
||||
nsHttpAuthManager::SetAuthIdentity(const nsACString & aScheme,
|
||||
const nsACString & aHost,
|
||||
PRInt32 aPort,
|
||||
const nsACString & aAuthType,
|
||||
const nsACString & aRealm,
|
||||
const nsACString & aPath,
|
||||
const nsAString & aUserDomain,
|
||||
|
@ -113,7 +128,8 @@ nsHttpAuthManager::SetAuthIdentity(const nsACString & aHost,
|
|||
PromiseFlatString(aUserName).get(),
|
||||
PromiseFlatString(aUserPassword).get());
|
||||
|
||||
return mAuthCache->SetAuthEntry(PromiseFlatCString(aHost).get(),
|
||||
return mAuthCache->SetAuthEntry(PromiseFlatCString(aScheme).get(),
|
||||
PromiseFlatCString(aHost).get(),
|
||||
aPort,
|
||||
PromiseFlatCString(aPath).get(),
|
||||
PromiseFlatCString(aRealm).get(),
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "nsICookieService.h"
|
||||
|
||||
static NS_DEFINE_CID(kStreamListenerTeeCID, NS_STREAMLISTENERTEE_CID);
|
||||
static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID);
|
||||
|
||||
static NS_METHOD DiscardSegments(nsIInputStream *input,
|
||||
void *closure,
|
||||
|
@ -216,14 +217,7 @@ nsHttpChannel::Init(nsIURI *uri,
|
|||
nsresult
|
||||
nsHttpChannel::AsyncCall(nsAsyncCallback funcPtr)
|
||||
{
|
||||
nsCOMPtr<nsIEventQueueService> eqs;
|
||||
nsCOMPtr<nsIEventQueue> eventQ;
|
||||
|
||||
gHttpHandler->GetEventQueueService(getter_AddRefs(eqs));
|
||||
if (eqs)
|
||||
eqs->ResolveEventQueue(NS_CURRENT_EVENTQ, getter_AddRefs(eventQ));
|
||||
if (!eventQ)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsresult rv;
|
||||
|
||||
nsAsyncCallEvent *event = new nsAsyncCallEvent;
|
||||
if (!event)
|
||||
|
@ -237,7 +231,7 @@ nsHttpChannel::AsyncCall(nsAsyncCallback funcPtr)
|
|||
nsHttpChannel::AsyncCall_EventHandlerFunc,
|
||||
nsHttpChannel::AsyncCall_EventCleanupFunc);
|
||||
|
||||
nsresult rv = eventQ->PostEvent(event);
|
||||
rv = mEventQ->PostEvent(event);
|
||||
if (NS_FAILED(rv)) {
|
||||
PL_DestroyEvent(event);
|
||||
NS_RELEASE_THIS();
|
||||
|
@ -349,8 +343,7 @@ nsHttpChannel::AsyncAbort(nsresult status)
|
|||
|
||||
// create a proxy for the listener..
|
||||
nsCOMPtr<nsIRequestObserver> observer;
|
||||
NS_NewRequestObserverProxy(getter_AddRefs(observer),
|
||||
mListener, NS_CURRENT_EVENTQ);
|
||||
NS_NewRequestObserverProxy(getter_AddRefs(observer), mListener, mEventQ);
|
||||
if (observer) {
|
||||
observer->OnStartRequest(this, mListenerContext);
|
||||
observer->OnStopRequest(this, mListenerContext, mStatus);
|
||||
|
@ -518,14 +511,6 @@ nsHttpChannel::SetupTransaction()
|
|||
mRequestHead.SetHeader(nsHttp::Pragma, NS_LITERAL_CSTRING("no-cache"), PR_TRUE);
|
||||
}
|
||||
|
||||
if (!mEventQ) {
|
||||
// grab a reference to the calling thread's event queue.
|
||||
nsCOMPtr<nsIEventQueueService> eqs;
|
||||
gHttpHandler->GetEventQueueService(getter_AddRefs(eqs));
|
||||
if (eqs)
|
||||
eqs->ResolveEventQueue(NS_CURRENT_EVENTQ, getter_AddRefs(mEventQ));
|
||||
}
|
||||
|
||||
// create the transaction object
|
||||
mTransaction = new nsHttpTransaction();
|
||||
if (!mTransaction)
|
||||
|
@ -1486,11 +1471,31 @@ nsHttpChannel::ReadFromCache()
|
|||
rv = mCacheEntry->OpenInputStream(0, getter_AddRefs(stream));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = NS_NewInputStreamPump(getter_AddRefs(mCachePump),
|
||||
stream, -1, -1, 0, 0, PR_TRUE);
|
||||
// the cache stream implements blocking reads, so we want to read from
|
||||
// it using the stream transport service.
|
||||
|
||||
nsCOMPtr<nsIStreamTransportService> sts =
|
||||
do_GetService(kStreamTransportServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return mCachePump->AsyncRead(this, mListenerContext);
|
||||
nsCOMPtr<nsITransport> transport;
|
||||
rv = sts->CreateInputTransport(stream, 0, -1, PR_TRUE, getter_AddRefs(transport));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// collect progress notifications from the stream as it is read.
|
||||
rv = transport->SetEventSink(this, mEventQ);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIInputStream> wrapper;
|
||||
rv = transport->OpenInputStream(0, 0, 0, getter_AddRefs(wrapper));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = NS_NewInputStreamPump(getter_AddRefs(mCachePump),
|
||||
wrapper, -1, -1, 0, 0, PR_TRUE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = mCachePump->AsyncRead(this, mListenerContext);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1908,6 +1913,7 @@ SetIdent(nsHttpAuthIdentity &ident,
|
|||
nsresult
|
||||
nsHttpChannel::GenCredsAndSetEntry(nsIHttpAuthenticator *auth,
|
||||
PRBool proxyAuth,
|
||||
const char *scheme,
|
||||
const char *host,
|
||||
PRInt32 port,
|
||||
const char *directory,
|
||||
|
@ -1957,7 +1963,7 @@ nsHttpChannel::GenCredsAndSetEntry(nsIHttpAuthenticator *auth,
|
|||
//
|
||||
// if the credentials are not reusable, then we don't bother sticking
|
||||
// them in the auth cache.
|
||||
rv = authCache->SetAuthEntry(host, port, directory, realm,
|
||||
rv = authCache->SetAuthEntry(scheme, host, port, directory, realm,
|
||||
saveCreds ? *result : nsnull,
|
||||
saveChallenge ? challenge : nsnull,
|
||||
ident, sessionState);
|
||||
|
@ -2042,7 +2048,7 @@ nsHttpChannel::GetCredentials(const char *challenges,
|
|||
|
||||
nsresult
|
||||
nsHttpChannel::GetCredentialsForChallenge(const char *challenge,
|
||||
const char *scheme,
|
||||
const char *authType,
|
||||
PRBool proxyAuth,
|
||||
nsIHttpAuthenticator *auth,
|
||||
nsAFlatCString &creds)
|
||||
|
@ -2060,14 +2066,14 @@ nsHttpChannel::GetCredentialsForChallenge(const char *challenge,
|
|||
nsCAutoString realm;
|
||||
ParseRealm(challenge, realm);
|
||||
|
||||
// if no realm, then use the auth scheme as the realm. ToUpperCase so the
|
||||
// if no realm, then use the auth type as the realm. ToUpperCase so the
|
||||
// ficticious realm stands out a bit more.
|
||||
// XXX this will cause some single signon misses!
|
||||
// XXX this will cause problems when we expose the auth cache to OJI!
|
||||
// XXX this was meant to be used with NTLM, which supplies no realm.
|
||||
/*
|
||||
if (realm.IsEmpty()) {
|
||||
realm = scheme;
|
||||
realm = authType;
|
||||
ToUpperCase(realm);
|
||||
}
|
||||
*/
|
||||
|
@ -2075,7 +2081,7 @@ nsHttpChannel::GetCredentialsForChallenge(const char *challenge,
|
|||
const char *host;
|
||||
PRInt32 port;
|
||||
nsHttpAuthIdentity *ident;
|
||||
nsCAutoString path;
|
||||
nsCAutoString path, scheme;
|
||||
PRBool identFromURI = PR_FALSE;
|
||||
|
||||
// it is possible for the origin server to fake a proxy challenge. if
|
||||
|
@ -2083,10 +2089,11 @@ nsHttpChannel::GetCredentialsForChallenge(const char *challenge,
|
|||
// domain. otherwise, we could inadvertantly expose the user's proxy
|
||||
// credentials to an origin server.
|
||||
|
||||
if (proxyAuth && mConnectionInfo->ProxyHost()) {
|
||||
if (proxyAuth && mConnectionInfo->UsingHttpProxy()) {
|
||||
host = mConnectionInfo->ProxyHost();
|
||||
port = mConnectionInfo->ProxyPort();
|
||||
ident = &mProxyIdent;
|
||||
scheme = NS_LITERAL_CSTRING("http");
|
||||
}
|
||||
else {
|
||||
host = mConnectionInfo->Host();
|
||||
|
@ -2096,6 +2103,9 @@ nsHttpChannel::GetCredentialsForChallenge(const char *challenge,
|
|||
rv = GetCurrentPath(path);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = mURI->GetScheme(scheme);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// if this is the first challenge, then try using the identity
|
||||
// specified in the URL.
|
||||
if (mIdent.IsEmpty()) {
|
||||
|
@ -2111,7 +2121,7 @@ nsHttpChannel::GetCredentialsForChallenge(const char *challenge,
|
|||
// try instead.
|
||||
//
|
||||
nsHttpAuthEntry *entry = nsnull;
|
||||
authCache->GetAuthEntryForDomain(host, port, realm.get(), &entry);
|
||||
authCache->GetAuthEntryForDomain(scheme.get(), host, port, realm.get(), &entry);
|
||||
|
||||
// hold reference to the auth session state (in case we clear our
|
||||
// reference to the entry).
|
||||
|
@ -2137,8 +2147,8 @@ nsHttpChannel::GetCredentialsForChallenge(const char *challenge,
|
|||
LOG((" clearing bad auth cache entry\n"));
|
||||
// ok, we've already tried this user identity, so clear the
|
||||
// corresponding entry from the auth cache.
|
||||
ClearPasswordManagerEntry(host, port, realm.get(), entry->User());
|
||||
authCache->ClearAuthEntry(host, port, realm.get());
|
||||
ClearPasswordManagerEntry(scheme.get(), host, port, realm.get(), entry->User());
|
||||
authCache->ClearAuthEntry(scheme.get(), host, port, realm.get());
|
||||
entry = nsnull;
|
||||
ident->Clear();
|
||||
}
|
||||
|
@ -2168,8 +2178,8 @@ nsHttpChannel::GetCredentialsForChallenge(const char *challenge,
|
|||
if (!entry && ident->IsEmpty()) {
|
||||
// at this point we are forced to interact with the user to get
|
||||
// their username and password for this domain.
|
||||
rv = PromptForIdentity(host, port, proxyAuth, realm.get(),
|
||||
scheme, authFlags, *ident);
|
||||
rv = PromptForIdentity(scheme.get(), host, port, proxyAuth, realm.get(),
|
||||
authType, authFlags, *ident);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
identFromURI = PR_FALSE;
|
||||
}
|
||||
|
@ -2186,7 +2196,7 @@ nsHttpChannel::GetCredentialsForChallenge(const char *challenge,
|
|||
// expecting to authenticate as.
|
||||
//
|
||||
nsXPIDLCString result;
|
||||
rv = GenCredsAndSetEntry(auth, proxyAuth, host, port, path.get(),
|
||||
rv = GenCredsAndSetEntry(auth, proxyAuth, scheme.get(), host, port, path.get(),
|
||||
realm.get(), challenge, *ident, sessionStateGrip,
|
||||
getter_Copies(result));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
|
@ -2196,7 +2206,7 @@ nsHttpChannel::GetCredentialsForChallenge(const char *challenge,
|
|||
|
||||
nsresult
|
||||
nsHttpChannel::ParseChallenge(const char *challenge,
|
||||
nsCString &scheme,
|
||||
nsCString &authType,
|
||||
nsIHttpAuthenticator **auth)
|
||||
{
|
||||
LOG(("nsHttpChannel::ParseChallenge [this=%x]\n", this));
|
||||
|
@ -2205,16 +2215,16 @@ nsHttpChannel::ParseChallenge(const char *challenge,
|
|||
|
||||
// get the challenge type
|
||||
if ((p = strchr(challenge, ' ')) != nsnull)
|
||||
scheme.Assign(challenge, p - challenge);
|
||||
authType.Assign(challenge, p - challenge);
|
||||
else
|
||||
scheme.Assign(challenge);
|
||||
authType.Assign(challenge);
|
||||
|
||||
// normalize to lowercase
|
||||
ToLowerCase(scheme);
|
||||
ToLowerCase(authType);
|
||||
|
||||
nsCAutoString contractid;
|
||||
contractid.Assign(NS_HTTP_AUTHENTICATOR_CONTRACTID_PREFIX);
|
||||
contractid.Append(scheme);
|
||||
contractid.Append(authType);
|
||||
|
||||
return CallGetService(contractid.get(), auth);
|
||||
}
|
||||
|
@ -2272,16 +2282,19 @@ nsHttpChannel::ParseRealm(const char *challenge, nsACString &realm)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsHttpChannel::PromptForIdentity(const char *host,
|
||||
PRInt32 port,
|
||||
PRBool proxyAuth,
|
||||
nsHttpChannel::PromptForIdentity(const char *scheme,
|
||||
const char *host,
|
||||
PRInt32 port,
|
||||
PRBool proxyAuth,
|
||||
const char *realm,
|
||||
const char *scheme,
|
||||
const char *authType,
|
||||
PRUint32 authFlags,
|
||||
nsHttpAuthIdentity &ident)
|
||||
{
|
||||
LOG(("nsHttpChannel::PromptForIdentity [this=%x]\n", this));
|
||||
|
||||
// XXX authType should be included in the prompt
|
||||
|
||||
// XXX i18n: IDN not supported.
|
||||
|
||||
nsCOMPtr<nsIAuthPrompt> authPrompt;
|
||||
|
@ -2296,6 +2309,11 @@ nsHttpChannel::PromptForIdentity(const char *host,
|
|||
// in password maanger. THE FORMAT OF THIS KEY IS SACROSANCT!! do not
|
||||
// even think about changing the format of this key.
|
||||
//
|
||||
// XXX we need to prefix this with "scheme://" at some point. however, that
|
||||
// has to be done very carefully and probably with some cooperation from the
|
||||
// password manager to ensure that passwords remembered under the old key
|
||||
// format are not lost.
|
||||
//
|
||||
nsAutoString key;
|
||||
key.AssignWithConversion(host);
|
||||
key.Append(PRUnichar(':'));
|
||||
|
@ -2339,6 +2357,12 @@ nsHttpChannel::PromptForIdentity(const char *host,
|
|||
realmU.AppendWithConversion(realm);
|
||||
realmU.Append(PRUnichar('\"'));
|
||||
|
||||
// prepend "scheme://" displayHost
|
||||
nsAutoString schemeU;
|
||||
schemeU.AssignWithConversion(scheme);
|
||||
schemeU.Append(NS_LITERAL_STRING("://"));
|
||||
displayHost.Insert(schemeU, 0);
|
||||
|
||||
const PRUnichar *strings[] = { realmU.get(), displayHost.get() };
|
||||
rv = bundle->FormatStringFromName(
|
||||
NS_LITERAL_STRING("EnterUserPasswordForRealm").get(),
|
||||
|
@ -2369,6 +2393,7 @@ nsHttpChannel::PromptForIdentity(const char *host,
|
|||
void
|
||||
nsHttpChannel::SetAuthorizationHeader(nsHttpAuthCache *authCache,
|
||||
nsHttpAtom header,
|
||||
const char *scheme,
|
||||
const char *host,
|
||||
PRInt32 port,
|
||||
const char *path,
|
||||
|
@ -2378,7 +2403,7 @@ nsHttpChannel::SetAuthorizationHeader(nsHttpAuthCache *authCache,
|
|||
nsHttpAuthEntry *entry = nsnull;
|
||||
nsresult rv;
|
||||
|
||||
rv = authCache->GetAuthEntryForPath(host, port, path, &entry);
|
||||
rv = authCache->GetAuthEntryForPath(scheme, host, port, path, &entry);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// if we are trying to add a header for origin server auth and if the
|
||||
// URL contains an explicit username, then try the given username first.
|
||||
|
@ -2414,7 +2439,7 @@ nsHttpChannel::SetAuthorizationHeader(nsHttpAuthCache *authCache,
|
|||
rv = ParseChallenge(challenge, unused, getter_AddRefs(auth));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRBool proxyAuth = (header == nsHttp::Proxy_Authorization);
|
||||
rv = GenCredsAndSetEntry(auth, proxyAuth, host, port, path,
|
||||
rv = GenCredsAndSetEntry(auth, proxyAuth, scheme, host, port, path,
|
||||
entry->Realm(), challenge, ident,
|
||||
entry->mMetaData, getter_Copies(temp));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
|
@ -2440,20 +2465,23 @@ nsHttpChannel::AddAuthorizationHeaders()
|
|||
|
||||
// check if proxy credentials should be sent
|
||||
const char *proxyHost = mConnectionInfo->ProxyHost();
|
||||
if (proxyHost)
|
||||
if (proxyHost && mConnectionInfo->UsingHttpProxy())
|
||||
SetAuthorizationHeader(authCache, nsHttp::Proxy_Authorization,
|
||||
proxyHost, mConnectionInfo->ProxyPort(),
|
||||
"http", proxyHost, mConnectionInfo->ProxyPort(),
|
||||
nsnull, // proxy has no path
|
||||
mProxyIdent);
|
||||
|
||||
// check if server credentials should be sent
|
||||
nsCAutoString path;
|
||||
if (NS_SUCCEEDED(GetCurrentPath(path)))
|
||||
nsCAutoString path, scheme;
|
||||
if (NS_SUCCEEDED(GetCurrentPath(path)) &&
|
||||
NS_SUCCEEDED(mURI->GetScheme(scheme))) {
|
||||
SetAuthorizationHeader(authCache, nsHttp::Authorization,
|
||||
scheme.get(),
|
||||
mConnectionInfo->Host(),
|
||||
mConnectionInfo->Port(),
|
||||
path.get(),
|
||||
mIdent);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -2759,8 +2787,18 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
|
|||
NS_ENSURE_ARG_POINTER(listener);
|
||||
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// we want to grab a reference to the calling thread's event queue at
|
||||
// this point. we will proxy all events back to the current thread via
|
||||
// this event queue.
|
||||
if (!mEventQ) {
|
||||
rv = gHttpHandler->GetCurrentEventQ(getter_AddRefs(mEventQ));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
PRInt32 port;
|
||||
nsresult rv = mURI->GetPort(&port);
|
||||
rv = mURI->GetPort(&port);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
@ -3651,8 +3689,14 @@ nsHttpChannel::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry,
|
|||
}
|
||||
|
||||
void
|
||||
nsHttpChannel::ClearPasswordManagerEntry(const char *host, PRInt32 port, const char *realm, const PRUnichar *user)
|
||||
nsHttpChannel::ClearPasswordManagerEntry(const char *scheme,
|
||||
const char *host,
|
||||
PRInt32 port,
|
||||
const char *realm,
|
||||
const PRUnichar *user)
|
||||
{
|
||||
// XXX scheme is currently unused. see comments in PromptForIdentity
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPasswordManager> passWordManager = do_GetService(NS_PASSWORDMANAGER_CONTRACTID, &rv);
|
||||
if (passWordManager) {
|
||||
|
|
|
@ -146,17 +146,17 @@ private:
|
|||
nsresult OnDoneReadingPartialCacheEntry(PRBool *streamDone);
|
||||
|
||||
// auth specific methods
|
||||
nsresult GenCredsAndSetEntry(nsIHttpAuthenticator *, PRBool proxyAuth, const char *host, PRInt32 port, const char *dir, const char *realm, const char *challenge, const nsHttpAuthIdentity &ident, nsCOMPtr<nsISupports> &session, char **result);
|
||||
nsresult GenCredsAndSetEntry(nsIHttpAuthenticator *, PRBool proxyAuth, const char *scheme, const char *host, PRInt32 port, const char *dir, const char *realm, const char *challenge, const nsHttpAuthIdentity &ident, nsCOMPtr<nsISupports> &session, char **result);
|
||||
nsresult GetCredentials(const char *challenges, PRBool proxyAuth, nsAFlatCString &creds);
|
||||
nsresult GetCredentialsForChallenge(const char *challenge, const char *scheme, PRBool proxyAuth, nsIHttpAuthenticator *auth, nsAFlatCString &creds);
|
||||
nsresult ParseChallenge(const char *challenge, nsCString &scheme, nsIHttpAuthenticator **auth);
|
||||
void ParseRealm(const char *challenge, nsACString &realm);
|
||||
void GetIdentityFromURI(PRUint32 authFlags, nsHttpAuthIdentity&);
|
||||
nsresult PromptForIdentity(const char *host, PRInt32 port, PRBool proxyAuth, const char *realm, const char *scheme, PRUint32 authFlags, nsHttpAuthIdentity &);
|
||||
void SetAuthorizationHeader(nsHttpAuthCache *, nsHttpAtom header, const char *host, PRInt32 port, const char *path, nsHttpAuthIdentity &ident);
|
||||
nsresult PromptForIdentity(const char *scheme, const char *host, PRInt32 port, PRBool proxyAuth, const char *realm, const char *scheme, PRUint32 authFlags, nsHttpAuthIdentity &);
|
||||
void SetAuthorizationHeader(nsHttpAuthCache *, nsHttpAtom header, const char *scheme, const char *host, PRInt32 port, const char *path, nsHttpAuthIdentity &ident);
|
||||
void AddAuthorizationHeaders();
|
||||
nsresult GetCurrentPath(nsACString &);
|
||||
void ClearPasswordManagerEntry(const char *host, PRInt32 port, const char *realm, const PRUnichar *user);
|
||||
void ClearPasswordManagerEntry(const char *scheme, const char *host, PRInt32 port, const char *realm, const PRUnichar *user);
|
||||
nsresult DoAuthRetry(nsAHttpConnection *);
|
||||
|
||||
static void *PR_CALLBACK AsyncCall_EventHandlerFunc(PLEvent *);
|
||||
|
|
Загрузка…
Ссылка в новой задаче