зеркало из https://github.com/mozilla/gecko-dev.git
backing out 0a13ddc99c95, bug 475053
This commit is contained in:
Родитель
3f7b9b6a29
Коммит
9d5c6615df
|
@ -48,7 +48,7 @@ interface nsIAuthInformation;
|
||||||
* It can be used to prompt users for authentication information, either
|
* It can be used to prompt users for authentication information, either
|
||||||
* synchronously or asynchronously.
|
* synchronously or asynchronously.
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(651395EB-8612-4876-8AC0-A88D4DCE9E1E)]
|
[scriptable, uuid(447fc780-1d28-412a-91a1-466d48129c65)]
|
||||||
interface nsIAuthPrompt2 : nsISupports
|
interface nsIAuthPrompt2 : nsISupports
|
||||||
{
|
{
|
||||||
/** @name Security Levels */
|
/** @name Security Levels */
|
||||||
|
@ -110,23 +110,9 @@ interface nsIAuthPrompt2 : nsISupports
|
||||||
* dialog and MUST call nsIAuthPromptCallback::onAuthCancelled on the provided
|
* dialog and MUST call nsIAuthPromptCallback::onAuthCancelled on the provided
|
||||||
* callback.
|
* callback.
|
||||||
*
|
*
|
||||||
* This implementation may:
|
* @throw NS_ERROR_NOT_IMPLEMENTED
|
||||||
*
|
* Asynchronous authentication prompts are not supported;
|
||||||
* 1) Coalesce identical prompts. This means prompts that are guaranteed to
|
* the caller should fall back to promptUsernameAndPassword().
|
||||||
* want the same auth information from the user. A single prompt will be
|
|
||||||
* shown; then the callbacks for all the coalesced prompts will be notified
|
|
||||||
* with the resulting auth information.
|
|
||||||
* 2) Serialize prompts that are all in the same "context" (this might mean
|
|
||||||
* application-wide, for a given window, or something else depending on
|
|
||||||
* the user interface) so that the user is not deluged with prompts.
|
|
||||||
*
|
|
||||||
* @throw
|
|
||||||
* This method may throw any exception when the prompt fails to queue e.g
|
|
||||||
* because of out-of-memory error. It must not throw when the prompt
|
|
||||||
* could already be potentially shown to the user. In that case information
|
|
||||||
* about the failure has to come through the callback. This way we
|
|
||||||
* prevent multiple dialogs shown to the user because consumer may fall
|
|
||||||
* back to synchronous prompt on synchronous failure of this method.
|
|
||||||
*/
|
*/
|
||||||
nsICancelable asyncPromptAuth(in nsIChannel aChannel,
|
nsICancelable asyncPromptAuth(in nsIChannel aChannel,
|
||||||
in nsIAuthPromptCallback aCallback,
|
in nsIAuthPromptCallback aCallback,
|
||||||
|
@ -134,3 +120,5 @@ interface nsIAuthPrompt2 : nsISupports
|
||||||
in PRUint32 level,
|
in PRUint32 level,
|
||||||
in nsIAuthInformation authInfo);
|
in nsIAuthInformation authInfo);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,6 @@
|
||||||
#include "nsAuthInformationHolder.h"
|
#include "nsAuthInformationHolder.h"
|
||||||
#include "nsICacheService.h"
|
#include "nsICacheService.h"
|
||||||
#include "nsDNSPrefetch.h"
|
#include "nsDNSPrefetch.h"
|
||||||
#include "nsNetSegmentUtils.h"
|
|
||||||
|
|
||||||
// True if the local cache should be bypassed when processing a request.
|
// True if the local cache should be bypassed when processing a request.
|
||||||
#define BYPASS_LOCAL_CACHE(loadFlags) \
|
#define BYPASS_LOCAL_CACHE(loadFlags) \
|
||||||
|
@ -126,7 +125,6 @@ nsHttpChannel::nsHttpChannel()
|
||||||
, mTransactionReplaced(PR_FALSE)
|
, mTransactionReplaced(PR_FALSE)
|
||||||
, mUploadStreamHasHeaders(PR_FALSE)
|
, mUploadStreamHasHeaders(PR_FALSE)
|
||||||
, mAuthRetryPending(PR_FALSE)
|
, mAuthRetryPending(PR_FALSE)
|
||||||
, mProxyAuth(PR_FALSE)
|
|
||||||
, mSuppressDefensiveAuth(PR_FALSE)
|
, mSuppressDefensiveAuth(PR_FALSE)
|
||||||
, mResuming(PR_FALSE)
|
, mResuming(PR_FALSE)
|
||||||
, mInitedCacheEntry(PR_FALSE)
|
, mInitedCacheEntry(PR_FALSE)
|
||||||
|
@ -3119,13 +3117,13 @@ nsHttpChannel::ProcessAuthentication(PRUint32 httpStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *challenges;
|
const char *challenges;
|
||||||
mProxyAuth = (httpStatus == 407);
|
PRBool proxyAuth = (httpStatus == 407);
|
||||||
|
|
||||||
nsresult rv = PrepareForAuthentication(mProxyAuth);
|
nsresult rv = PrepareForAuthentication(proxyAuth);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
if (mProxyAuth) {
|
if (proxyAuth) {
|
||||||
// only allow a proxy challenge if we have a proxy server configured.
|
// only allow a proxy challenge if we have a proxy server configured.
|
||||||
// otherwise, we could inadvertantly expose the user's proxy
|
// otherwise, we could inadvertantly expose the user's proxy
|
||||||
// credentials to an origin server. We could attempt to proceed as
|
// credentials to an origin server. We could attempt to proceed as
|
||||||
|
@ -3150,24 +3148,12 @@ nsHttpChannel::ProcessAuthentication(PRUint32 httpStatus)
|
||||||
NS_ENSURE_TRUE(challenges, NS_ERROR_UNEXPECTED);
|
NS_ENSURE_TRUE(challenges, NS_ERROR_UNEXPECTED);
|
||||||
|
|
||||||
nsCAutoString creds;
|
nsCAutoString creds;
|
||||||
rv = GetCredentials(challenges, mProxyAuth, creds);
|
rv = GetCredentials(challenges, proxyAuth, creds);
|
||||||
if (rv == NS_ERROR_IN_PROGRESS) {
|
if (NS_FAILED(rv))
|
||||||
// authentication prompt has been invoked and result
|
|
||||||
// is expected asynchronously
|
|
||||||
mAuthRetryPending = PR_TRUE;
|
|
||||||
// suspend the transaction pump to stop receiving the
|
|
||||||
// unauthenticated content data. We will throw that data
|
|
||||||
// away when user provides credentials or resume the pump
|
|
||||||
// when user refuses to authenticate.
|
|
||||||
LOG(("Suspending the transaction, asynchronously prompting for credentials"));
|
|
||||||
mTransactionPump->Suspend();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
else if (NS_FAILED(rv))
|
|
||||||
LOG(("unable to authenticate\n"));
|
LOG(("unable to authenticate\n"));
|
||||||
else {
|
else {
|
||||||
// set the authentication credentials
|
// set the authentication credentials
|
||||||
if (mProxyAuth)
|
if (proxyAuth)
|
||||||
mRequestHead.SetHeader(nsHttp::Proxy_Authorization, creds);
|
mRequestHead.SetHeader(nsHttp::Proxy_Authorization, creds);
|
||||||
else
|
else
|
||||||
mRequestHead.SetHeader(nsHttp::Authorization, creds);
|
mRequestHead.SetHeader(nsHttp::Authorization, creds);
|
||||||
|
@ -3294,15 +3280,6 @@ nsHttpChannel::GetCredentials(const char *challenges,
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (rv == NS_ERROR_IN_PROGRESS) {
|
|
||||||
// authentication prompt has been invoked and result is
|
|
||||||
// expected asynchronously, save current challenge being
|
|
||||||
// processed and all remaining challenges to use later in
|
|
||||||
// OnAuthAvailable and now immediately return
|
|
||||||
mCurrentChallenge = challenge;
|
|
||||||
mRemainingChallenges = eol ? eol+1 : nsnull;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset the auth type and continuation state
|
// reset the auth type and continuation state
|
||||||
NS_IF_RELEASE(*currentContinuationState);
|
NS_IF_RELEASE(*currentContinuationState);
|
||||||
|
@ -3322,43 +3299,6 @@ nsHttpChannel::GetCredentials(const char *challenges,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsHttpChannel::GetAuthorizationMembers(PRBool proxyAuth,
|
|
||||||
nsCSubstring& scheme,
|
|
||||||
const char*& host,
|
|
||||||
PRInt32& port,
|
|
||||||
nsCSubstring& path,
|
|
||||||
nsHttpAuthIdentity*& ident,
|
|
||||||
nsISupports**& continuationState)
|
|
||||||
{
|
|
||||||
if (proxyAuth) {
|
|
||||||
NS_ASSERTION (mConnectionInfo->UsingHttpProxy(), "proxyAuth is true, but no HTTP proxy is configured!");
|
|
||||||
|
|
||||||
host = mConnectionInfo->ProxyHost();
|
|
||||||
port = mConnectionInfo->ProxyPort();
|
|
||||||
ident = &mProxyIdent;
|
|
||||||
scheme.AssignLiteral("http");
|
|
||||||
|
|
||||||
continuationState = &mProxyAuthContinuationState;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
host = mConnectionInfo->Host();
|
|
||||||
port = mConnectionInfo->Port();
|
|
||||||
ident = &mIdent;
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
rv = GetCurrentPath(path);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
rv = mURI->GetScheme(scheme);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
continuationState = &mAuthContinuationState;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHttpChannel::GetCredentialsForChallenge(const char *challenge,
|
nsHttpChannel::GetCredentialsForChallenge(const char *challenge,
|
||||||
const char *authType,
|
const char *authType,
|
||||||
|
@ -3400,16 +3340,35 @@ nsHttpChannel::GetCredentialsForChallenge(const char *challenge,
|
||||||
PRBool identFromURI = PR_FALSE;
|
PRBool identFromURI = PR_FALSE;
|
||||||
nsISupports **continuationState;
|
nsISupports **continuationState;
|
||||||
|
|
||||||
rv = GetAuthorizationMembers(proxyAuth, scheme, host, port, path, ident, continuationState);
|
if (proxyAuth) {
|
||||||
if (NS_FAILED(rv)) return rv;
|
NS_ASSERTION (mConnectionInfo->UsingHttpProxy(), "proxyAuth is true, but no HTTP proxy is configured!");
|
||||||
|
|
||||||
|
host = mConnectionInfo->ProxyHost();
|
||||||
|
port = mConnectionInfo->ProxyPort();
|
||||||
|
ident = &mProxyIdent;
|
||||||
|
scheme.AssignLiteral("http");
|
||||||
|
|
||||||
|
continuationState = &mProxyAuthContinuationState;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
host = mConnectionInfo->Host();
|
||||||
|
port = mConnectionInfo->Port();
|
||||||
|
ident = &mIdent;
|
||||||
|
|
||||||
|
rv = GetCurrentPath(path);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
rv = mURI->GetScheme(scheme);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
if (!proxyAuth) {
|
|
||||||
// if this is the first challenge, then try using the identity
|
// if this is the first challenge, then try using the identity
|
||||||
// specified in the URL.
|
// specified in the URL.
|
||||||
if (mIdent.IsEmpty()) {
|
if (mIdent.IsEmpty()) {
|
||||||
GetIdentityFromURI(authFlags, mIdent);
|
GetIdentityFromURI(authFlags, mIdent);
|
||||||
identFromURI = !mIdent.IsEmpty();
|
identFromURI = !mIdent.IsEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continuationState = &mAuthContinuationState;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -3663,163 +3622,23 @@ nsHttpChannel::PromptForIdentity(PRUint32 level,
|
||||||
nsDependentCString(authType));
|
nsDependentCString(authType));
|
||||||
if (!holder)
|
if (!holder)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
PRBool retval = PR_FALSE;
|
||||||
rv = authPrompt->AsyncPromptAuth(this, this, nsnull, level, holder,
|
rv = authPrompt->PromptAuth(this,
|
||||||
getter_AddRefs(mAsyncPromptAuthCancelable));
|
level,
|
||||||
|
holder, &retval);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_FAILED(rv))
|
||||||
// indicate using this error code that authentication prompt
|
return rv;
|
||||||
// result is expected asynchronously
|
|
||||||
rv = NS_ERROR_IN_PROGRESS;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Fall back to synchronous prompt
|
|
||||||
PRBool retval = PR_FALSE;
|
|
||||||
rv = authPrompt->PromptAuth(this, level, holder, &retval);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
if (!retval)
|
|
||||||
rv = NS_ERROR_ABORT;
|
|
||||||
else
|
|
||||||
holder->SetToHttpAuthIdentity(authFlags, ident);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remember that we successfully showed the user an auth dialog
|
// remember that we successfully showed the user an auth dialog
|
||||||
if (!proxyAuth)
|
if (!proxyAuth)
|
||||||
mSuppressDefensiveAuth = PR_TRUE;
|
mSuppressDefensiveAuth = PR_TRUE;
|
||||||
|
|
||||||
return rv;
|
if (!retval)
|
||||||
}
|
rv = NS_ERROR_ABORT;
|
||||||
|
|
||||||
NS_IMETHODIMP nsHttpChannel::OnAuthAvailable(nsISupports *aContext,
|
|
||||||
nsIAuthInformation *aAuthInfo)
|
|
||||||
{
|
|
||||||
LOG(("nsHttpChannel::OnAuthAvailable [this=%x]", this));
|
|
||||||
mAsyncPromptAuthCancelable = nsnull;
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
const char *host;
|
|
||||||
PRInt32 port;
|
|
||||||
nsHttpAuthIdentity *ident;
|
|
||||||
nsCAutoString path, scheme;
|
|
||||||
nsISupports **continuationState;
|
|
||||||
rv = GetAuthorizationMembers(mProxyAuth, scheme, host, port, path, ident, continuationState);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
OnAuthCancelled(aContext, PR_FALSE);
|
|
||||||
|
|
||||||
nsCAutoString realm;
|
|
||||||
ParseRealm(mCurrentChallenge.get(), realm);
|
|
||||||
|
|
||||||
nsHttpAuthCache *authCache = gHttpHandler->AuthCache();
|
|
||||||
nsHttpAuthEntry *entry = nsnull;
|
|
||||||
authCache->GetAuthEntryForDomain(scheme.get(), host, port, realm.get(), &entry);
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> sessionStateGrip;
|
|
||||||
if (entry)
|
|
||||||
sessionStateGrip = entry->mMetaData;
|
|
||||||
|
|
||||||
nsAuthInformationHolder* holder =
|
|
||||||
static_cast<nsAuthInformationHolder*>(aAuthInfo);
|
|
||||||
ident->Set(holder->Domain().get(),
|
|
||||||
holder->User().get(),
|
|
||||||
holder->Password().get());
|
|
||||||
|
|
||||||
nsCAutoString unused;
|
|
||||||
nsCOMPtr<nsIHttpAuthenticator> auth;
|
|
||||||
rv = GetAuthenticator(mCurrentChallenge.get(), unused, getter_AddRefs(auth));
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_ASSERTION(PR_FALSE, "GetAuthenticator failed");
|
|
||||||
OnAuthCancelled(aContext, PR_TRUE);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsXPIDLCString creds;
|
|
||||||
rv = GenCredsAndSetEntry(auth, mProxyAuth,
|
|
||||||
scheme.get(), host, port, path.get(),
|
|
||||||
realm.get(), mCurrentChallenge.get(), *ident, sessionStateGrip,
|
|
||||||
getter_Copies(creds));
|
|
||||||
|
|
||||||
mCurrentChallenge.Truncate();
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
OnAuthCancelled(aContext, PR_TRUE);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ContinueOnAuthAvailable(creds);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsHttpChannel::OnAuthCancelled(nsISupports *aContext,
|
|
||||||
PRBool userCancel)
|
|
||||||
{
|
|
||||||
LOG(("nsHttpChannel::OnAuthCancelled [this=%x]", this));
|
|
||||||
mAsyncPromptAuthCancelable = nsnull;
|
|
||||||
if (userCancel) {
|
|
||||||
if (!mRemainingChallenges.IsEmpty()) {
|
|
||||||
// there are still some challenges to process, do so
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
nsCAutoString creds;
|
|
||||||
rv = GetCredentials(mRemainingChallenges.get(), mProxyAuth, creds);
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
// GetCredentials loaded the credentials from the cache or
|
|
||||||
// some other way in a synchronous manner, process those
|
|
||||||
// credentials now
|
|
||||||
mRemainingChallenges.Truncate();
|
|
||||||
return ContinueOnAuthAvailable(creds);
|
|
||||||
}
|
|
||||||
else if (rv == NS_ERROR_IN_PROGRESS) {
|
|
||||||
// GetCredentials successfully queued another authprompt for
|
|
||||||
// a challenge from the list, we are now waiting for the user
|
|
||||||
// to provide the credentials
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise, we failed...
|
|
||||||
}
|
|
||||||
|
|
||||||
mRemainingChallenges.Truncate();
|
|
||||||
|
|
||||||
// ensure call of OnStartRequest of the current listener here,
|
|
||||||
// it would not be called otherwise at all
|
|
||||||
nsresult rv = CallOnStartRequest();
|
|
||||||
|
|
||||||
// drop mAuthRetryPending flag and resume the transaction
|
|
||||||
// this resumes load of the unauthenticated content data
|
|
||||||
mAuthRetryPending = PR_FALSE;
|
|
||||||
LOG(("Resuming the transaction, user cancelled the auth dialog"));
|
|
||||||
mTransactionPump->Resume();
|
|
||||||
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
mTransactionPump->Cancel(rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsHttpChannel::ContinueOnAuthAvailable(const nsCSubstring& creds)
|
|
||||||
{
|
|
||||||
if (mProxyAuth)
|
|
||||||
mRequestHead.SetHeader(nsHttp::Proxy_Authorization, creds);
|
|
||||||
else
|
else
|
||||||
mRequestHead.SetHeader(nsHttp::Authorization, creds);
|
holder->SetToHttpAuthIdentity(authFlags, ident);
|
||||||
|
|
||||||
// drop our remaining list of challenges. We don't need them, because we
|
return rv;
|
||||||
// have now authenticated against a challenge and will be sending that
|
|
||||||
// information to the server (or proxy). If it doesn't accept our
|
|
||||||
// authentication it'll respond with failure and resend the challenge list
|
|
||||||
mRemainingChallenges.Truncate();
|
|
||||||
|
|
||||||
// setting mAuthRetryPending flag and resuming the transaction
|
|
||||||
// triggers process of throwing away the unauthenticated data already
|
|
||||||
// coming from the network
|
|
||||||
mAuthRetryPending = PR_TRUE;
|
|
||||||
LOG(("Resuming the transaction, we got credentials from user"));
|
|
||||||
mTransactionPump->Resume();
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
|
@ -4077,7 +3896,6 @@ NS_INTERFACE_MAP_BEGIN(nsHttpChannel)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsITraceableChannel)
|
NS_INTERFACE_MAP_ENTRY(nsITraceableChannel)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheContainer)
|
NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheContainer)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheChannel)
|
NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheChannel)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIAuthPromptCallback)
|
|
||||||
NS_INTERFACE_MAP_END_INHERITING(nsHashPropertyBag)
|
NS_INTERFACE_MAP_END_INHERITING(nsHashPropertyBag)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -4125,8 +3943,6 @@ nsHttpChannel::Cancel(nsresult status)
|
||||||
mTransactionPump->Cancel(status);
|
mTransactionPump->Cancel(status);
|
||||||
if (mCachePump)
|
if (mCachePump)
|
||||||
mCachePump->Cancel(status);
|
mCachePump->Cancel(status);
|
||||||
if (mAsyncPromptAuthCancelable)
|
|
||||||
mAsyncPromptAuthCancelable->Cancel(status);
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5157,14 +4973,8 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
|
||||||
// keep the connection around after the transaction is finished.
|
// keep the connection around after the transaction is finished.
|
||||||
//
|
//
|
||||||
nsRefPtr<nsAHttpConnection> conn;
|
nsRefPtr<nsAHttpConnection> conn;
|
||||||
if (authRetry && (mCaps & NS_HTTP_STICKY_CONNECTION)) {
|
if (authRetry && (mCaps & NS_HTTP_STICKY_CONNECTION))
|
||||||
conn = mTransaction->Connection();
|
conn = mTransaction->Connection();
|
||||||
// This is so far a workaround to fix leak when reusing unpersistent
|
|
||||||
// connection for authentication retry. See bug 459620 comment 4
|
|
||||||
// for details.
|
|
||||||
if (conn && !conn->IsPersistent())
|
|
||||||
conn = nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
// at this point, we're done with the transaction
|
// at this point, we're done with the transaction
|
||||||
NS_RELEASE(mTransaction);
|
NS_RELEASE(mTransaction);
|
||||||
|
|
|
@ -84,7 +84,6 @@
|
||||||
#include "nsICancelable.h"
|
#include "nsICancelable.h"
|
||||||
#include "nsIProxiedChannel.h"
|
#include "nsIProxiedChannel.h"
|
||||||
#include "nsITraceableChannel.h"
|
#include "nsITraceableChannel.h"
|
||||||
#include "nsIAuthPromptCallback.h"
|
|
||||||
|
|
||||||
class nsHttpResponseHead;
|
class nsHttpResponseHead;
|
||||||
class nsAHttpConnection;
|
class nsAHttpConnection;
|
||||||
|
@ -110,7 +109,6 @@ class nsHttpChannel : public nsHashPropertyBag
|
||||||
, public nsIProxiedChannel
|
, public nsIProxiedChannel
|
||||||
, public nsITraceableChannel
|
, public nsITraceableChannel
|
||||||
, public nsIApplicationCacheChannel
|
, public nsIApplicationCacheChannel
|
||||||
, public nsIAuthPromptCallback
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
@ -132,7 +130,6 @@ public:
|
||||||
NS_DECL_NSITRACEABLECHANNEL
|
NS_DECL_NSITRACEABLECHANNEL
|
||||||
NS_DECL_NSIAPPLICATIONCACHECONTAINER
|
NS_DECL_NSIAPPLICATIONCACHECONTAINER
|
||||||
NS_DECL_NSIAPPLICATIONCACHECHANNEL
|
NS_DECL_NSIAPPLICATIONCACHECHANNEL
|
||||||
NS_DECL_NSIAUTHPROMPTCALLBACK
|
|
||||||
|
|
||||||
nsHttpChannel();
|
nsHttpChannel();
|
||||||
virtual ~nsHttpChannel();
|
virtual ~nsHttpChannel();
|
||||||
|
@ -226,38 +223,19 @@ private:
|
||||||
// auth specific methods
|
// auth specific methods
|
||||||
nsresult PrepareForAuthentication(PRBool proxyAuth);
|
nsresult PrepareForAuthentication(PRBool proxyAuth);
|
||||||
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 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 GetAuthenticator(const char *challenge, nsCString &scheme, nsIHttpAuthenticator **auth);
|
nsresult GetAuthenticator(const char *challenge, nsCString &scheme, nsIHttpAuthenticator **auth);
|
||||||
void ParseRealm(const char *challenge, nsACString &realm);
|
void ParseRealm(const char *challenge, nsACString &realm);
|
||||||
void GetIdentityFromURI(PRUint32 authFlags, nsHttpAuthIdentity&);
|
void GetIdentityFromURI(PRUint32 authFlags, nsHttpAuthIdentity&);
|
||||||
/**
|
|
||||||
* Following three methods return NS_ERROR_IN_PROGRESS when
|
|
||||||
* nsIAuthPrompt2.asyncPromptAuth method is called. This result indicates
|
|
||||||
* the user's decision will be gathered in a callback and is not an actual
|
|
||||||
* error.
|
|
||||||
*/
|
|
||||||
nsresult GetCredentials(const char *challenges, PRBool proxyAuth, nsAFlatCString &creds);
|
|
||||||
nsresult GetCredentialsForChallenge(const char *challenge, const char *scheme, PRBool proxyAuth, nsIHttpAuthenticator *auth, nsAFlatCString &creds);
|
|
||||||
nsresult PromptForIdentity(PRUint32 level, PRBool proxyAuth, const char *realm, const char *authType, PRUint32 authFlags, nsHttpAuthIdentity &);
|
nsresult PromptForIdentity(PRUint32 level, PRBool proxyAuth, const char *realm, const char *authType, PRUint32 authFlags, nsHttpAuthIdentity &);
|
||||||
|
|
||||||
PRBool ConfirmAuth(const nsString &bundleKey, PRBool doYesNoPrompt);
|
PRBool ConfirmAuth(const nsString &bundleKey, PRBool doYesNoPrompt);
|
||||||
void CheckForSuperfluousAuth();
|
void CheckForSuperfluousAuth();
|
||||||
void SetAuthorizationHeader(nsHttpAuthCache *, nsHttpAtom header, const char *scheme, const char *host, PRInt32 port, const char *path, nsHttpAuthIdentity &ident);
|
void SetAuthorizationHeader(nsHttpAuthCache *, nsHttpAtom header, const char *scheme, const char *host, PRInt32 port, const char *path, nsHttpAuthIdentity &ident);
|
||||||
void AddAuthorizationHeaders();
|
void AddAuthorizationHeaders();
|
||||||
nsresult GetCurrentPath(nsACString &);
|
nsresult GetCurrentPath(nsACString &);
|
||||||
/**
|
|
||||||
* Return all information needed to build authorization information,
|
|
||||||
* all paramters except proxyAuth are out parameters. proxyAuth specifies
|
|
||||||
* with what authorization we work (WWW or proxy).
|
|
||||||
*/
|
|
||||||
nsresult GetAuthorizationMembers(PRBool proxyAuth, nsCSubstring& scheme, const char*& host, PRInt32& port, nsCSubstring& path, nsHttpAuthIdentity*& ident, nsISupports**& continuationState);
|
|
||||||
nsresult DoAuthRetry(nsAHttpConnection *);
|
nsresult DoAuthRetry(nsAHttpConnection *);
|
||||||
PRBool MustValidateBasedOnQueryUrl();
|
PRBool MustValidateBasedOnQueryUrl();
|
||||||
/**
|
|
||||||
* Method called to resume suspended transaction after we got credentials
|
|
||||||
* from the user. Called from OnAuthAvailable callback or OnAuthCancelled
|
|
||||||
* when credentials for next challenge were obtained synchronously.
|
|
||||||
*/
|
|
||||||
nsresult ContinueOnAuthAvailable(const nsCSubstring& creds);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsCOMPtr<nsIURI> mOriginalURI;
|
nsCOMPtr<nsIURI> mOriginalURI;
|
||||||
|
@ -315,19 +293,6 @@ private:
|
||||||
nsHttpAuthIdentity mIdent;
|
nsHttpAuthIdentity mIdent;
|
||||||
nsHttpAuthIdentity mProxyIdent;
|
nsHttpAuthIdentity mProxyIdent;
|
||||||
|
|
||||||
// Reference to the prompt wating in prompt queue. The channel is
|
|
||||||
// responsible to call its cancel method when user in any way cancels
|
|
||||||
// this request.
|
|
||||||
nsCOMPtr<nsICancelable> mAsyncPromptAuthCancelable;
|
|
||||||
// Saved in GetCredentials when prompt is asynchronous, the first challenge
|
|
||||||
// we obtained from the server with 401/407 response, will be processed in
|
|
||||||
// OnAuthAvailable callback.
|
|
||||||
nsCString mCurrentChallenge;
|
|
||||||
// Saved in GetCredentials when prompt is asynchronous, remaning challenges
|
|
||||||
// we have to process when user cancels the auth dialog for the current
|
|
||||||
// challenge.
|
|
||||||
nsCString mRemainingChallenges;
|
|
||||||
|
|
||||||
// Resumable channel specific data
|
// Resumable channel specific data
|
||||||
nsCString mEntityID;
|
nsCString mEntityID;
|
||||||
PRUint64 mStartPos;
|
PRUint64 mStartPos;
|
||||||
|
@ -364,9 +329,6 @@ private:
|
||||||
PRUint32 mTransactionReplaced : 1;
|
PRUint32 mTransactionReplaced : 1;
|
||||||
PRUint32 mUploadStreamHasHeaders : 1;
|
PRUint32 mUploadStreamHasHeaders : 1;
|
||||||
PRUint32 mAuthRetryPending : 1;
|
PRUint32 mAuthRetryPending : 1;
|
||||||
// True when we need to authenticate to proxy, i.e. when we get 407
|
|
||||||
// response. Used in OnAuthAvailable and OnAuthCancelled callbacks.
|
|
||||||
PRUint32 mProxyAuth : 1;
|
|
||||||
PRUint32 mSuppressDefensiveAuth : 1;
|
PRUint32 mSuppressDefensiveAuth : 1;
|
||||||
PRUint32 mResuming : 1;
|
PRUint32 mResuming : 1;
|
||||||
PRUint32 mInitedCacheEntry : 1;
|
PRUint32 mInitedCacheEntry : 1;
|
||||||
|
|
|
@ -50,42 +50,18 @@ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
* Invoked by NS_NewAuthPrompter2()
|
* Invoked by NS_NewAuthPrompter2()
|
||||||
* [embedding/components/windowwatcher/src/nsPrompt.cpp]
|
* [embedding/components/windowwatcher/src/nsPrompt.cpp]
|
||||||
*/
|
*/
|
||||||
function LoginManagerPromptFactory() {
|
function LoginManagerPromptFactory() {}
|
||||||
var observerService = Cc["@mozilla.org/observer-service;1"].
|
|
||||||
getService(Ci.nsIObserverService);
|
|
||||||
observerService.addObserver(this, "quit-application-granted", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
LoginManagerPromptFactory.prototype = {
|
LoginManagerPromptFactory.prototype = {
|
||||||
|
|
||||||
classDescription : "LoginManagerPromptFactory",
|
classDescription : "LoginManagerPromptFactory",
|
||||||
contractID : "@mozilla.org/passwordmanager/authpromptfactory;1",
|
contractID : "@mozilla.org/passwordmanager/authpromptfactory;1",
|
||||||
classID : Components.ID("{749e62f4-60ae-4569-a8a2-de78b649660e}"),
|
classID : Components.ID("{749e62f4-60ae-4569-a8a2-de78b649660e}"),
|
||||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsIPromptFactory, Ci.nsIObserver, Ci.nsISupportsWeakReference]),
|
QueryInterface : XPCOMUtils.generateQI([Ci.nsIPromptFactory]),
|
||||||
|
|
||||||
_asyncPrompts : {},
|
|
||||||
_asyncPromptInProgress : false,
|
|
||||||
|
|
||||||
observe : function (subject, topic, data) {
|
|
||||||
if (topic == "quit-application-granted") {
|
|
||||||
var asyncPrompts = this._asyncPrompts;
|
|
||||||
this._asyncPrompts = {};
|
|
||||||
for each (var asyncPrompt in asyncPrompts) {
|
|
||||||
for each (var consumer in asyncPrompt.consumers) {
|
|
||||||
if (consumer.callback) {
|
|
||||||
this.log("Canceling async auth prompt callback " + consumer.callback);
|
|
||||||
try {
|
|
||||||
consumer.callback.onAuthCancelled(consumer.context, true);
|
|
||||||
} catch (e) { /* Just ignore exceptions from the callback */ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getPrompt : function (aWindow, aIID) {
|
getPrompt : function (aWindow, aIID) {
|
||||||
var prompt = new LoginManagerPrompter().QueryInterface(aIID);
|
var prompt = new LoginManagerPrompter().QueryInterface(aIID);
|
||||||
prompt.init(aWindow, this);
|
prompt.init(aWindow);
|
||||||
return prompt;
|
return prompt;
|
||||||
}
|
}
|
||||||
}; // end of LoginManagerPromptFactory implementation
|
}; // end of LoginManagerPromptFactory implementation
|
||||||
|
@ -122,7 +98,6 @@ LoginManagerPrompter.prototype = {
|
||||||
Ci.nsIAuthPrompt2,
|
Ci.nsIAuthPrompt2,
|
||||||
Ci.nsILoginManagerPrompter]),
|
Ci.nsILoginManagerPrompter]),
|
||||||
|
|
||||||
_factory : null,
|
|
||||||
_window : null,
|
_window : null,
|
||||||
_debug : false, // mirrors signon.debug
|
_debug : false, // mirrors signon.debug
|
||||||
|
|
||||||
|
@ -190,14 +165,6 @@ LoginManagerPrompter.prototype = {
|
||||||
return this.__ioService;
|
return this.__ioService;
|
||||||
},
|
},
|
||||||
|
|
||||||
__threadManager: null,
|
|
||||||
get _threadManager() {
|
|
||||||
if (!this.__threadManager)
|
|
||||||
this.__threadManager = Cc["@mozilla.org/thread-manager;1"].
|
|
||||||
getService(Ci.nsIThreadManager);
|
|
||||||
return this.__threadManager;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
__ellipsis : null,
|
__ellipsis : null,
|
||||||
get _ellipsis() {
|
get _ellipsis() {
|
||||||
|
@ -589,114 +556,10 @@ LoginManagerPrompter.prototype = {
|
||||||
return ok;
|
return ok;
|
||||||
},
|
},
|
||||||
|
|
||||||
asyncPromptAuth : function (aChannel, aCallback, aContext, aLevel, aAuthInfo) {
|
asyncPromptAuth : function () {
|
||||||
var cancelable = null;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
try {
|
|
||||||
this.log("===== asyncPromptAuth called =====");
|
|
||||||
|
|
||||||
// If the user submits a login but it fails, we need to remove the
|
|
||||||
// notification bar that was displayed. Conveniently, the user will
|
|
||||||
// be prompted for authentication again, which brings us here.
|
|
||||||
var notifyBox = this._getNotifyBox();
|
|
||||||
if (notifyBox)
|
|
||||||
this._removeLoginNotifications(notifyBox);
|
|
||||||
|
|
||||||
cancelable = this._newAsyncPromptConsumer(aCallback, aContext);
|
|
||||||
|
|
||||||
var [hostname, httpRealm] = this._getAuthTarget(aChannel, aAuthInfo);
|
|
||||||
|
|
||||||
var hashKey = aLevel + "|" + hostname + "|" + httpRealm;
|
|
||||||
this.log("Async prompt key = " + hashKey);
|
|
||||||
var asyncPrompt = this._factory._asyncPrompts[hashKey];
|
|
||||||
if (asyncPrompt) {
|
|
||||||
this.log("Prompt bound to an existing one in the queue, callback = " + aCallback);
|
|
||||||
asyncPrompt.consumers.push(cancelable);
|
|
||||||
return cancelable;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.log("Adding new prompt to the queue, callback = " + aCallback);
|
|
||||||
asyncPrompt = {
|
|
||||||
consumers: [cancelable],
|
|
||||||
channel: aChannel,
|
|
||||||
authInfo: aAuthInfo,
|
|
||||||
level: aLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
this._factory._asyncPrompts[hashKey] = asyncPrompt;
|
|
||||||
this._doAsyncPrompt();
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
Components.utils.reportError("LoginManagerPrompter: " +
|
|
||||||
"asyncPromptAuth: " + e + "\nFalling back to promptAuth\n");
|
|
||||||
// Fail the prompt operation to let the consumer fall back
|
|
||||||
// to synchronous promptAuth method
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cancelable;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_doAsyncPrompt : function() {
|
|
||||||
if (this._factory._asyncPromptInProgress) {
|
|
||||||
this.log("_doAsyncPrompt bypassed, already in progress");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the first prompt key we have in the queue
|
|
||||||
var hashKey = null;
|
|
||||||
for (hashKey in this._factory._asyncPrompts)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!hashKey) {
|
|
||||||
this.log("_doAsyncPrompt:run bypassed, no prompts in the queue");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._factory._asyncPromptInProgress = true;
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
var runnable = {
|
|
||||||
run : function() {
|
|
||||||
var ok = false;
|
|
||||||
var prompt = self._factory._asyncPrompts[hashKey];
|
|
||||||
try {
|
|
||||||
self.log("_doAsyncPrompt:run - performing the prompt for '" + hashKey + "'");
|
|
||||||
ok = self.promptAuth(
|
|
||||||
prompt.channel,
|
|
||||||
prompt.level,
|
|
||||||
prompt.authInfo
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
Components.utils.reportError("LoginManagerPrompter: " +
|
|
||||||
"_doAsyncPrompt:run: " + e + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
delete self._factory._asyncPrompts[hashKey];
|
|
||||||
self._factory._asyncPromptInProgress = false;
|
|
||||||
|
|
||||||
for each (var consumer in prompt.consumers) {
|
|
||||||
if (!consumer.callback)
|
|
||||||
// Not having a callback means that consumer didn't provide it
|
|
||||||
// or canceled the notification
|
|
||||||
continue;
|
|
||||||
|
|
||||||
self.log("Calling back to " + consumer.callback + " ok=" + ok);
|
|
||||||
try {
|
|
||||||
if (ok)
|
|
||||||
consumer.callback.onAuthAvailable(consumer.context, prompt.authInfo);
|
|
||||||
else
|
|
||||||
consumer.callback.onAuthCancelled(consumer.context, true);
|
|
||||||
} catch (e) { /* Throw away exceptions caused by callback */ }
|
|
||||||
}
|
|
||||||
self._doAsyncPrompt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this._threadManager.mainThread.dispatch(runnable,
|
|
||||||
Ci.nsIThread.DISPATCH_NORMAL);
|
|
||||||
this.log("_doAsyncPrompt:run dispatched");
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -709,9 +572,8 @@ LoginManagerPrompter.prototype = {
|
||||||
* init
|
* init
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
init : function (aWindow, aFactory) {
|
init : function (aWindow) {
|
||||||
this._window = aWindow;
|
this._window = aWindow;
|
||||||
this._factory = aFactory || null;
|
|
||||||
|
|
||||||
var prefBranch = Cc["@mozilla.org/preferences-service;1"].
|
var prefBranch = Cc["@mozilla.org/preferences-service;1"].
|
||||||
getService(Ci.nsIPrefService).getBranch("signon.");
|
getService(Ci.nsIPrefService).getBranch("signon.");
|
||||||
|
@ -1356,19 +1218,6 @@ LoginManagerPrompter.prototype = {
|
||||||
aAuthInfo.username = username;
|
aAuthInfo.username = username;
|
||||||
}
|
}
|
||||||
aAuthInfo.password = password;
|
aAuthInfo.password = password;
|
||||||
},
|
|
||||||
|
|
||||||
_newAsyncPromptConsumer : function(aCallback, aContext) {
|
|
||||||
return {
|
|
||||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
|
|
||||||
callback: aCallback,
|
|
||||||
context: aContext,
|
|
||||||
cancel: function() {
|
|
||||||
this.callback.onAuthCancelled(this.context, false);
|
|
||||||
this.callback = null;
|
|
||||||
this.context = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // end of LoginManagerPrompter implementation
|
}; // end of LoginManagerPrompter implementation
|
||||||
|
|
|
@ -74,7 +74,6 @@ MOCHI_TESTS = \
|
||||||
test_bug_391514.html \
|
test_bug_391514.html \
|
||||||
test_bug_427033.html \
|
test_bug_427033.html \
|
||||||
test_bug_444968.html \
|
test_bug_444968.html \
|
||||||
test_prompt_async.html \
|
|
||||||
test_notifications.html \
|
test_notifications.html \
|
||||||
test_prompt.html \
|
test_prompt.html \
|
||||||
test_xhr.html \
|
test_xhr.html \
|
||||||
|
@ -102,7 +101,6 @@ MOCHI_CONTENT = \
|
||||||
subtst_notifications_8.html \
|
subtst_notifications_8.html \
|
||||||
subtst_notifications_9.html \
|
subtst_notifications_9.html \
|
||||||
subtst_notifications_10.html \
|
subtst_notifications_10.html \
|
||||||
subtst_prompt_async.html \
|
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
XPCSHELL_TESTS = unit
|
XPCSHELL_TESTS = unit
|
||||||
|
|
|
@ -11,16 +11,13 @@ function handleRequest(request, response)
|
||||||
|
|
||||||
function reallyHandleRequest(request, response) {
|
function reallyHandleRequest(request, response) {
|
||||||
var match;
|
var match;
|
||||||
var requestAuth = true, requestProxyAuth = true;
|
var requestAuth = true;
|
||||||
|
|
||||||
// Allow the caller to drive how authentication is processed via the query.
|
// Allow the caller to drive how authentication is processed via the query.
|
||||||
// Eg, http://localhost:8888/authenticate.sjs?user=foo&realm=bar
|
// Eg, http://localhost:8888/authenticate.sjs?user=foo&realm=bar
|
||||||
var query = request.queryString;
|
var query = request.queryString;
|
||||||
|
|
||||||
var expected_user = "", expected_pass = "", realm = "mochitest";
|
var expected_user = "", expected_pass = "", realm = "mochitest";
|
||||||
var proxy_expected_user = "", proxy_expected_pass = "", proxy_realm = "mochi-proxy";
|
|
||||||
var huge = false;
|
|
||||||
var authHeaderCount = 1;
|
|
||||||
// user=xxx
|
// user=xxx
|
||||||
match = /user=([^&]*)/.exec(query);
|
match = /user=([^&]*)/.exec(query);
|
||||||
if (match)
|
if (match)
|
||||||
|
@ -36,31 +33,6 @@ function reallyHandleRequest(request, response) {
|
||||||
if (match)
|
if (match)
|
||||||
realm = match[1];
|
realm = match[1];
|
||||||
|
|
||||||
// proxy_user=xxx
|
|
||||||
match = /proxy_user=([^&]*)/.exec(query);
|
|
||||||
if (match)
|
|
||||||
proxy_expected_user = match[1];
|
|
||||||
|
|
||||||
// proxy_pass=xxx
|
|
||||||
match = /proxy_pass=([^&]*)/.exec(query);
|
|
||||||
if (match)
|
|
||||||
proxy_expected_pass = match[1];
|
|
||||||
|
|
||||||
// proxy_realm=xxx
|
|
||||||
match = /proxy_realm=([^&]*)/.exec(query);
|
|
||||||
if (match)
|
|
||||||
proxy_realm = match[1];
|
|
||||||
|
|
||||||
// huge=1
|
|
||||||
match = /huge=1/.exec(query);
|
|
||||||
if (match)
|
|
||||||
huge = true;
|
|
||||||
|
|
||||||
// multiple=1
|
|
||||||
match = /multiple=([^&]*)/.exec(query);
|
|
||||||
if (match)
|
|
||||||
authHeaderCount = match[1]+0;
|
|
||||||
|
|
||||||
|
|
||||||
// Look for an authentication header, if any, in the request.
|
// Look for an authentication header, if any, in the request.
|
||||||
//
|
//
|
||||||
|
@ -84,40 +56,16 @@ function reallyHandleRequest(request, response) {
|
||||||
actual_pass = match[2];
|
actual_pass = match[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
var proxy_actual_user = "", proxy_actual_pass = "";
|
|
||||||
if (request.hasHeader("Proxy-Authorization")) {
|
|
||||||
authHeader = request.getHeader("Proxy-Authorization");
|
|
||||||
match = /Basic (.+)/.exec(authHeader);
|
|
||||||
if (match.length != 2)
|
|
||||||
throw "Couldn't parse auth header: " + authHeader;
|
|
||||||
|
|
||||||
var userpass = base64ToString(match[1]); // no atob() :-(
|
|
||||||
match = /(.*):(.*)/.exec(userpass);
|
|
||||||
if (match.length != 3)
|
|
||||||
throw "Couldn't decode auth header: " + userpass;
|
|
||||||
proxy_actual_user = match[1];
|
|
||||||
proxy_actual_pass = match[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't request authentication if the credentials we got were what we
|
// Don't request authentication if the credentials we got were what we
|
||||||
// expected.
|
// expected.
|
||||||
if (expected_user == actual_user &&
|
if (expected_user == actual_user &&
|
||||||
expected_pass == actual_pass) {
|
expected_pass == actual_pass) {
|
||||||
requestAuth = false;
|
requestAuth = false;
|
||||||
}
|
|
||||||
if (proxy_expected_user == proxy_actual_user &&
|
|
||||||
proxy_expected_pass == proxy_actual_pass) {
|
|
||||||
requestProxyAuth = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestProxyAuth) {
|
if (requestAuth) {
|
||||||
response.setStatusLine("1.0", 407, "Proxy authentication required");
|
|
||||||
for (i = 0; i < authHeaderCount; ++i)
|
|
||||||
response.setHeader("Proxy-Authenticate", "basic realm=\"" + proxy_realm + "\"", true);
|
|
||||||
} else if (requestAuth) {
|
|
||||||
response.setStatusLine("1.0", 401, "Authentication required");
|
response.setStatusLine("1.0", 401, "Authentication required");
|
||||||
for (i = 0; i < authHeaderCount; ++i)
|
response.setHeader("WWW-Authenticate", "basic realm=\"" + realm + "\"", false);
|
||||||
response.setHeader("WWW-Authenticate", "basic realm=\"" + realm + "\"", true);
|
|
||||||
} else {
|
} else {
|
||||||
response.setStatusLine("1.0", 200, "OK");
|
response.setStatusLine("1.0", 200, "OK");
|
||||||
}
|
}
|
||||||
|
@ -125,20 +73,9 @@ function reallyHandleRequest(request, response) {
|
||||||
response.setHeader("Content-Type", "application/xhtml+xml", false);
|
response.setHeader("Content-Type", "application/xhtml+xml", false);
|
||||||
response.write("<html xmlns='http://www.w3.org/1999/xhtml'>");
|
response.write("<html xmlns='http://www.w3.org/1999/xhtml'>");
|
||||||
response.write("<p>Login: <span id='ok'>" + (requestAuth ? "FAIL" : "PASS") + "</span></p>\n");
|
response.write("<p>Login: <span id='ok'>" + (requestAuth ? "FAIL" : "PASS") + "</span></p>\n");
|
||||||
response.write("<p>Proxy: <span id='proxy'>" + (requestProxyAuth ? "FAIL" : "PASS") + "</span></p>\n");
|
|
||||||
response.write("<p>Auth: <span id='auth'>" + authHeader + "</span></p>\n");
|
response.write("<p>Auth: <span id='auth'>" + authHeader + "</span></p>\n");
|
||||||
response.write("<p>User: <span id='user'>" + actual_user + "</span></p>\n");
|
response.write("<p>User: <span id='user'>" + actual_user + "</span></p>\n");
|
||||||
response.write("<p>Pass: <span id='pass'>" + actual_pass + "</span></p>\n");
|
response.write("<p>Pass: <span id='pass'>" + actual_pass + "</span></p>\n");
|
||||||
|
|
||||||
if (huge) {
|
|
||||||
response.write("<div style='display: none'>");
|
|
||||||
for (i = 0; i < 100000; i++) {
|
|
||||||
response.write("123456789\n");
|
|
||||||
}
|
|
||||||
response.write("</div>");
|
|
||||||
response.write("<span id='footnote'>This is a footnote after the huge content fill</span>");
|
|
||||||
}
|
|
||||||
|
|
||||||
response.write("</html>");
|
response.write("</html>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Multiple auth request</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<iframe id="iframe1" src="http://example.com/tests/toolkit/components/passwordmgr/test/authenticate.sjs?r=1&user=user3name&pass=user3pass&realm=mochirealm3&proxy_user=proxy_user2&proxy_pass=proxy_pass2&proxy_realm=proxy_realm2"></iframe>
|
|
||||||
<iframe id="iframe2" src="http://example.com/tests/toolkit/components/passwordmgr/test/authenticate.sjs?r=2&user=user3name&pass=user3pass&realm=mochirealm3&proxy_user=proxy_user2&proxy_pass=proxy_pass2&proxy_realm=proxy_realm2"></iframe>
|
|
||||||
<iframe id="iframe3" src="http://example.com/tests/toolkit/components/passwordmgr/test/authenticate.sjs?r=3&user=user3name&pass=user3pass&realm=mochirealm3&proxy_user=proxy_user2&proxy_pass=proxy_pass2&proxy_realm=proxy_realm2"></iframe>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,492 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test for Async Auth Prompt</title>
|
|
||||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<script type="text/javascript" src="prompt_common.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
|
|
||||||
<script class="testbody" type="text/javascript">
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
|
||||||
|
|
||||||
|
|
||||||
// Class monitoring number of open dialog windows
|
|
||||||
// It checks there is always open just a single dialog per application
|
|
||||||
function dialogMonitor() {
|
|
||||||
var observerService = Cc["@mozilla.org/observer-service;1"].
|
|
||||||
getService(Ci.nsIObserverService);
|
|
||||||
observerService.addObserver(this, "domwindowopened", false);
|
|
||||||
observerService.addObserver(this, "domwindowclosed", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
dialogMonitor.prototype = {
|
|
||||||
windowsOpen : new Array(),
|
|
||||||
windowsRegistered : 0,
|
|
||||||
|
|
||||||
QueryInterface : function (iid) {
|
|
||||||
const interfaces = [Ci.nsIObserver,
|
|
||||||
Ci.nsISupports];
|
|
||||||
|
|
||||||
if (!interfaces.some( function(v) { return iid.equals(v) } ))
|
|
||||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
observe: function(subject, topic, data) {
|
|
||||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
|
||||||
if (topic === "domwindowopened") {
|
|
||||||
var win = subject.QueryInterface(Ci.nsIDOMWindow);
|
|
||||||
this.windowsOpen.push(win);
|
|
||||||
ok(this.windowsOpen.length == 1, "Didn't open more then one dialog at a time");
|
|
||||||
this.windowsRegistered++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (topic === "domwindowclosed") {
|
|
||||||
var win = subject.QueryInterface(Ci.nsIDOMWindow);
|
|
||||||
for (p in this.windowsOpen)
|
|
||||||
if (win == this.windowsOpen[p]) {
|
|
||||||
this.windowsOpen.splice(p, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
shutdown: function() {
|
|
||||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
|
||||||
var observerService = Cc["@mozilla.org/observer-service;1"].
|
|
||||||
getService(Ci.nsIObserverService);
|
|
||||||
observerService.removeObserver(this, "domwindowopened");
|
|
||||||
observerService.removeObserver(this, "domwindowclosed");
|
|
||||||
},
|
|
||||||
|
|
||||||
reset: function() {
|
|
||||||
while (this.windowsOpen.length)
|
|
||||||
this.windowsOpen.shift();
|
|
||||||
this.windowsRegistered = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var monitor = new dialogMonitor();
|
|
||||||
|
|
||||||
var pwmgr, logins = [];
|
|
||||||
|
|
||||||
function initLogins() {
|
|
||||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
|
||||||
|
|
||||||
pwmgr = Cc["@mozilla.org/login-manager;1"].
|
|
||||||
getService(Ci.nsILoginManager);
|
|
||||||
|
|
||||||
function addLogin(host, realm, user, pass) {
|
|
||||||
var login = Cc["@mozilla.org/login-manager/loginInfo;1"].
|
|
||||||
createInstance(Ci.nsILoginInfo);
|
|
||||||
login.init(host, null, realm, user, pass, "", "");
|
|
||||||
pwmgr.addLogin(login);
|
|
||||||
logins.push(login);
|
|
||||||
}
|
|
||||||
|
|
||||||
addLogin("moz-proxy://127.0.0.1:8888", "proxy_realm",
|
|
||||||
"proxy_user", "proxy_pass");
|
|
||||||
addLogin("moz-proxy://127.0.0.1:8888", "proxy_realm2",
|
|
||||||
"proxy_user2", "proxy_pass2");
|
|
||||||
addLogin("moz-proxy://127.0.0.1:8888", "proxy_realm3",
|
|
||||||
"proxy_user3", "proxy_pass3");
|
|
||||||
addLogin("moz-proxy://127.0.0.1:8888", "proxy_realm4",
|
|
||||||
"proxy_user4", "proxy_pass4");
|
|
||||||
addLogin("moz-proxy://127.0.0.1:8888", "proxy_realm5",
|
|
||||||
"proxy_user5", "proxy_pass5");
|
|
||||||
addLogin("http://example.com", "mochirealm",
|
|
||||||
"user1name", "user1pass");
|
|
||||||
addLogin("http://example.org", "mochirealm2",
|
|
||||||
"user2name", "user2pass");
|
|
||||||
addLogin("http://example.com", "mochirealm3",
|
|
||||||
"user3name", "user3pass");
|
|
||||||
addLogin("http://example.com", "mochirealm4",
|
|
||||||
"user4name", "user4pass");
|
|
||||||
addLogin("http://example.com", "mochirealm5",
|
|
||||||
"user5name", "user5pass");
|
|
||||||
addLogin("http://example.com", "mochirealm6",
|
|
||||||
"user6name", "user6pass");
|
|
||||||
}
|
|
||||||
|
|
||||||
function finishTest() {
|
|
||||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
|
||||||
|
|
||||||
ok(true, "finishTest removing testing logins...");
|
|
||||||
for (i in logins)
|
|
||||||
pwmgr.removeLogin(logins[i]);
|
|
||||||
|
|
||||||
var authMgr = Cc['@mozilla.org/network/http-auth-manager;1'].
|
|
||||||
getService(Ci.nsIHttpAuthManager);
|
|
||||||
authMgr.clearAll();
|
|
||||||
|
|
||||||
monitor.shutdown();
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// --------------- Test loop spin ----------------
|
|
||||||
var testNum = 1;
|
|
||||||
var iframe1;
|
|
||||||
var iframe2a;
|
|
||||||
var iframe2b;
|
|
||||||
window.onload = function () {
|
|
||||||
iframe1 = document.getElementById("iframe1");
|
|
||||||
iframe2a = document.getElementById("iframe2a");
|
|
||||||
iframe2b = document.getElementById("iframe2b");
|
|
||||||
iframe1.onload = onFrameLoad;
|
|
||||||
iframe2a.onload = onFrameLoad;
|
|
||||||
iframe2b.onload = onFrameLoad;
|
|
||||||
|
|
||||||
initLogins();
|
|
||||||
doTest(testNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
var expectedLoads;
|
|
||||||
var expectedDialogs;
|
|
||||||
function onFrameLoad()
|
|
||||||
{
|
|
||||||
if (--expectedLoads == 0) {
|
|
||||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
|
||||||
|
|
||||||
// All pages expected to load has loaded, continue with the next test
|
|
||||||
ok(true, "Expected frames loaded");
|
|
||||||
|
|
||||||
doCheck(testNum);
|
|
||||||
monitor.reset();
|
|
||||||
|
|
||||||
testNum++;
|
|
||||||
doTest(testNum);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function doTest(testNum)
|
|
||||||
{
|
|
||||||
var exampleCom = "http://example.com/tests/toolkit/components/passwordmgr/test/";
|
|
||||||
var exampleOrg = "http://example.org/tests/toolkit/components/passwordmgr/test/";
|
|
||||||
|
|
||||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
|
||||||
|
|
||||||
switch (testNum)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
// Load through a single proxy with authentication required 3 different
|
|
||||||
// pages, first with one login, other two with their own different login.
|
|
||||||
// We expect to show just a single dialog for proxy authentication and
|
|
||||||
// then two dialogs to authenticate to login 1 and then login 2.
|
|
||||||
ok(true, "doTest testNum 1");
|
|
||||||
expectedLoads = 3;
|
|
||||||
expectedDialogs = 3;
|
|
||||||
iframe1.src = exampleCom + "authenticate.sjs?"+
|
|
||||||
"r=1&"+
|
|
||||||
"user=user1name&"+
|
|
||||||
"pass=user1pass&"+
|
|
||||||
"realm=mochirealm&"+
|
|
||||||
"proxy_user=proxy_user&"+
|
|
||||||
"proxy_pass=proxy_pass&"+
|
|
||||||
"proxy_realm=proxy_realm";
|
|
||||||
iframe2a.src = exampleOrg + "authenticate.sjs?"+
|
|
||||||
"r=2&"+
|
|
||||||
"user=user2name&"+
|
|
||||||
"pass=user2pass&"+
|
|
||||||
"realm=mochirealm2&"+
|
|
||||||
"proxy_user=proxy_user&"+
|
|
||||||
"proxy_pass=proxy_pass&"+
|
|
||||||
"proxy_realm=proxy_realm";
|
|
||||||
iframe2b.src = exampleOrg + "authenticate.sjs?"+
|
|
||||||
"r=3&"+
|
|
||||||
"user=user2name&"+
|
|
||||||
"pass=user2pass&"+
|
|
||||||
"realm=mochirealm2&"+
|
|
||||||
"proxy_user=proxy_user&"+
|
|
||||||
"proxy_pass=proxy_pass&"+
|
|
||||||
"proxy_realm=proxy_realm";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
// Load an iframe with 3 subpages all requiring the same login through
|
|
||||||
// anuthenticated proxy. We expect 2 dialogs, proxy authentication
|
|
||||||
// and web authentication.
|
|
||||||
ok(true, "doTest testNum 2");
|
|
||||||
expectedLoads = 3;
|
|
||||||
expectedDialogs = 2;
|
|
||||||
iframe1.src = exampleCom + "subtst_prompt_async.html";
|
|
||||||
iframe2a.src = "about:blank";
|
|
||||||
iframe2b.src = "about:blank";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
// Load in the iframe page through unauthenticated proxy
|
|
||||||
// and discard the proxy authentication. We expect to see
|
|
||||||
// unauthenticated page content and just a single dialog.
|
|
||||||
ok(true, "doTest testNum 3");
|
|
||||||
expectedLoads = 1;
|
|
||||||
expectedDialogs = 1;
|
|
||||||
iframe1.src = exampleCom + "authenticate.sjs?"+
|
|
||||||
"user=user4name&"+
|
|
||||||
"pass=user4pass&"+
|
|
||||||
"realm=mochirealm4&"+
|
|
||||||
"proxy_user=proxy_user3&"+
|
|
||||||
"proxy_pass=proxy_pass3&"+
|
|
||||||
"proxy_realm=proxy_realm3";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
// Reload the frame from previous step and pass the proxy authentication
|
|
||||||
// but cancel the WWW authentication. We should get the proxy=ok and WWW=fail
|
|
||||||
// content as a result.
|
|
||||||
ok(true, "doTest testNum 4");
|
|
||||||
expectedLoads = 1;
|
|
||||||
expectedDialogs = 2;
|
|
||||||
iframe1.contentDocument.location.reload();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
// Same as the previous two steps but let the server generate
|
|
||||||
// huge content load to check http channel is capable to handle
|
|
||||||
// case when auth dialog is canceled or accepted before unauthenticated
|
|
||||||
// content data is load from the server. (This would be better to
|
|
||||||
// implement using delay of server response).
|
|
||||||
ok(true, "doTest testNum 5");
|
|
||||||
expectedLoads = 1;
|
|
||||||
expectedDialogs = 1;
|
|
||||||
iframe1.src = exampleCom + "authenticate.sjs?"+
|
|
||||||
"user=user5name&"+
|
|
||||||
"pass=user5pass&"+
|
|
||||||
"realm=mochirealm5&"+
|
|
||||||
"proxy_user=proxy_user4&"+
|
|
||||||
"proxy_pass=proxy_pass4&"+
|
|
||||||
"proxy_realm=proxy_realm4&"+
|
|
||||||
"huge=1";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
// Reload the frame from the previous step and let the proxy
|
|
||||||
// authentication pass but WWW fail. We expect two dialogs
|
|
||||||
// and an unathentiocated page content load.
|
|
||||||
ok(true, "doTest testNum 6");
|
|
||||||
expectedLoads = 1;
|
|
||||||
expectedDialogs = 2;
|
|
||||||
iframe1.contentDocument.location.reload();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 7:
|
|
||||||
// Reload again and let pass all authentication dialogs.
|
|
||||||
// Check we get the authenticated content not broken by
|
|
||||||
// the unauthenticated content.
|
|
||||||
ok(true, "doTest testNum 7");
|
|
||||||
expectedLoads = 1;
|
|
||||||
expectedDialogs = 1;
|
|
||||||
iframe1.contentDocument.location.reload();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 8:
|
|
||||||
// Check we proccess all challenges sent by server when
|
|
||||||
// user cancels prompts
|
|
||||||
ok(true, "doTest testNum 8");
|
|
||||||
expectedLoads = 1;
|
|
||||||
expectedDialogs = 5;
|
|
||||||
iframe1.src = exampleCom + "authenticate.sjs?"+
|
|
||||||
"user=user6name&"+
|
|
||||||
"pass=user6pass&"+
|
|
||||||
"realm=mochirealm6&"+
|
|
||||||
"proxy_user=proxy_user5&"+
|
|
||||||
"proxy_pass=proxy_pass5&"+
|
|
||||||
"proxy_realm=proxy_realm5&"+
|
|
||||||
"huge=1&"+
|
|
||||||
"multiple=3";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 9:
|
|
||||||
finishTest();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
startCallbackTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleDialog(doc, testNum)
|
|
||||||
{
|
|
||||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
|
||||||
var dialog = doc.getElementById("commonDialog");
|
|
||||||
|
|
||||||
switch (testNum)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
case 2:
|
|
||||||
dialog.acceptDialog();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
dialog.cancelDialog();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
if (expectedDialogs == 2)
|
|
||||||
dialog.acceptDialog();
|
|
||||||
else
|
|
||||||
dialog.cancelDialog();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
dialog.cancelDialog();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
if (expectedDialogs == 2)
|
|
||||||
dialog.acceptDialog();
|
|
||||||
else
|
|
||||||
dialog.cancelDialog();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 7:
|
|
||||||
dialog.acceptDialog();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 8:
|
|
||||||
if (expectedDialogs == 3 || expectedDialogs == 1)
|
|
||||||
dialog.acceptDialog();
|
|
||||||
else
|
|
||||||
dialog.cancelDialog();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ok(false, "Unhandled testNum "+testNum+" in handleDialog");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (--expectedDialogs > 0)
|
|
||||||
startCallbackTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
function doCheck(testNum)
|
|
||||||
{
|
|
||||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
|
||||||
|
|
||||||
switch (testNum)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
ok(true, "doCheck testNum 1");
|
|
||||||
is(monitor.windowsRegistered, 3, "Registered 3 open dialogs");
|
|
||||||
var authok1 = iframe1.contentDocument.getElementById("ok").textContent;
|
|
||||||
var proxyok1 = iframe1.contentDocument.getElementById("proxy").textContent;
|
|
||||||
|
|
||||||
var authok2a = iframe2a.contentDocument.getElementById("ok").textContent;
|
|
||||||
var proxyok2a = iframe2a.contentDocument.getElementById("proxy").textContent;
|
|
||||||
|
|
||||||
var authok2b = iframe2b.contentDocument.getElementById("ok").textContent;
|
|
||||||
var proxyok2b = iframe2b.contentDocument.getElementById("proxy").textContent;
|
|
||||||
|
|
||||||
is(authok1, "PASS", "WWW Authorization OK, frame1");
|
|
||||||
is(authok2a, "PASS", "WWW Authorization OK, frame2a");
|
|
||||||
is(authok2b, "PASS", "WWW Authorization OK, frame2b");
|
|
||||||
is(proxyok1, "PASS", "Proxy Authorization OK, frame1");
|
|
||||||
is(proxyok2a, "PASS", "Proxy Authorization OK, frame2a");
|
|
||||||
is(proxyok2b, "PASS", "Proxy Authorization OK, frame2b");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
is(monitor.windowsRegistered, 2, "Registered 2 open dialogs");
|
|
||||||
ok(true, "doCheck testNum 2");
|
|
||||||
|
|
||||||
function checkIframe(frame) {
|
|
||||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
|
||||||
var authok = frame.contentDocument.getElementById("ok").textContent;
|
|
||||||
var proxyok = frame.contentDocument.getElementById("proxy").textContent;
|
|
||||||
|
|
||||||
is(authok, "PASS", "WWW Authorization OK, " + frame.id);
|
|
||||||
is(proxyok, "PASS", "Proxy Authorization OK, " + frame.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
checkIframe(iframe1.contentDocument.getElementById("iframe1"));
|
|
||||||
checkIframe(iframe1.contentDocument.getElementById("iframe2"));
|
|
||||||
checkIframe(iframe1.contentDocument.getElementById("iframe3"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
ok(true, "doCheck testNum 3");
|
|
||||||
is(monitor.windowsRegistered, 1, "Registered 1 open dialog");
|
|
||||||
var authok1 = iframe1.contentDocument.getElementById("ok").textContent;
|
|
||||||
var proxyok1 = iframe1.contentDocument.getElementById("proxy").textContent;
|
|
||||||
|
|
||||||
is(authok1, "FAIL", "WWW Authorization FAILED, frame1");
|
|
||||||
is(proxyok1, "FAIL", "Proxy Authorization FAILED, frame1");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
ok(true, "doCheck testNum 4");
|
|
||||||
is(monitor.windowsRegistered, 2, "Registered 2 open dialogs");
|
|
||||||
var authok1 = iframe1.contentDocument.getElementById("ok").textContent;
|
|
||||||
var proxyok1 = iframe1.contentDocument.getElementById("proxy").textContent;
|
|
||||||
|
|
||||||
is(authok1, "FAIL", "WWW Authorization FAILED, frame1");
|
|
||||||
is(proxyok1, "PASS", "Proxy Authorization OK, frame1");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
ok(true, "doCheck testNum 5");
|
|
||||||
is(monitor.windowsRegistered, 1, "Registered 1 open dialog");
|
|
||||||
var authok1 = iframe1.contentDocument.getElementById("ok").textContent;
|
|
||||||
var proxyok1 = iframe1.contentDocument.getElementById("proxy").textContent;
|
|
||||||
var footnote = iframe1.contentDocument.getElementById("footnote").textContent;
|
|
||||||
|
|
||||||
is(authok1, "FAIL", "WWW Authorization FAILED, frame1");
|
|
||||||
is(proxyok1, "FAIL", "Proxy Authorization FAILED, frame1");
|
|
||||||
is(footnote, "This is a footnote after the huge content fill",
|
|
||||||
"Footnote present and loaded completely");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
ok(true, "doCheck testNum 6");
|
|
||||||
is(monitor.windowsRegistered, 2, "Registered 2 open dialogs");
|
|
||||||
var authok1 = iframe1.contentDocument.getElementById("ok").textContent;
|
|
||||||
var proxyok1 = iframe1.contentDocument.getElementById("proxy").textContent;
|
|
||||||
var footnote = iframe1.contentDocument.getElementById("footnote").textContent;
|
|
||||||
|
|
||||||
is(authok1, "FAIL", "WWW Authorization FAILED, frame1");
|
|
||||||
is(proxyok1, "PASS", "Proxy Authorization OK, frame1");
|
|
||||||
is(footnote, "This is a footnote after the huge content fill",
|
|
||||||
"Footnote present and loaded completely");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 7:
|
|
||||||
ok(true, "doCheck testNum 7");
|
|
||||||
is(monitor.windowsRegistered, 1, "Registered 1 open dialogs");
|
|
||||||
var authok1 = iframe1.contentDocument.getElementById("ok").textContent;
|
|
||||||
var proxyok1 = iframe1.contentDocument.getElementById("proxy").textContent;
|
|
||||||
var footnote = iframe1.contentDocument.getElementById("footnote").textContent;
|
|
||||||
|
|
||||||
is(authok1, "PASS", "WWW Authorization OK, frame1");
|
|
||||||
is(proxyok1, "PASS", "Proxy Authorization OK, frame1");
|
|
||||||
is(footnote, "This is a footnote after the huge content fill",
|
|
||||||
"Footnote present and loaded completely");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 8:
|
|
||||||
ok(true, "doCheck testNum 8");
|
|
||||||
is(monitor.windowsRegistered, 5, "Registered 5 open dialogs");
|
|
||||||
var authok1 = iframe1.contentDocument.getElementById("ok").textContent;
|
|
||||||
var proxyok1 = iframe1.contentDocument.getElementById("proxy").textContent;
|
|
||||||
var footnote = iframe1.contentDocument.getElementById("footnote").textContent;
|
|
||||||
|
|
||||||
is(authok1, "PASS", "WWW Authorization OK, frame1");
|
|
||||||
is(proxyok1, "PASS", "Proxy Authorization OK, frame1");
|
|
||||||
is(footnote, "This is a footnote after the huge content fill",
|
|
||||||
"Footnote present and loaded completely");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ok(false, "Unhandled testNum "+testNum+" in doCheck");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<iframe id="iframe1"></iframe>
|
|
||||||
<iframe id="iframe2a"></iframe>
|
|
||||||
<iframe id="iframe2b"></iframe>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Загрузка…
Ссылка в новой задаче