mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1221320 - XMLHttpRequest authentication should not require auth prompt dialog, r=honzab.moz
This commit is contained in:
parent
aa49b603d7
commit
be6fc8d36f
@ -178,72 +178,6 @@ static void AddLoadFlags(nsIRequest *request, nsLoadFlags newFlags)
|
||||
request->SetLoadFlags(flags);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// XMLHttpRequestAuthPrompt
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class XMLHttpRequestAuthPrompt : public nsIAuthPrompt
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIAUTHPROMPT
|
||||
|
||||
XMLHttpRequestAuthPrompt();
|
||||
|
||||
protected:
|
||||
virtual ~XMLHttpRequestAuthPrompt();
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(XMLHttpRequestAuthPrompt, nsIAuthPrompt)
|
||||
|
||||
XMLHttpRequestAuthPrompt::XMLHttpRequestAuthPrompt()
|
||||
{
|
||||
MOZ_COUNT_CTOR(XMLHttpRequestAuthPrompt);
|
||||
}
|
||||
|
||||
XMLHttpRequestAuthPrompt::~XMLHttpRequestAuthPrompt()
|
||||
{
|
||||
MOZ_COUNT_DTOR(XMLHttpRequestAuthPrompt);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XMLHttpRequestAuthPrompt::Prompt(const char16_t* aDialogTitle,
|
||||
const char16_t* aText,
|
||||
const char16_t* aPasswordRealm,
|
||||
uint32_t aSavePassword,
|
||||
const char16_t* aDefaultText,
|
||||
char16_t** aResult,
|
||||
bool* aRetval)
|
||||
{
|
||||
*aRetval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XMLHttpRequestAuthPrompt::PromptUsernameAndPassword(const char16_t* aDialogTitle,
|
||||
const char16_t* aDialogText,
|
||||
const char16_t* aPasswordRealm,
|
||||
uint32_t aSavePassword,
|
||||
char16_t** aUser,
|
||||
char16_t** aPwd,
|
||||
bool* aRetval)
|
||||
{
|
||||
*aRetval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
XMLHttpRequestAuthPrompt::PromptPassword(const char16_t* aDialogTitle,
|
||||
const char16_t* aText,
|
||||
const char16_t* aPasswordRealm,
|
||||
uint32_t aSavePassword,
|
||||
char16_t** aPwd,
|
||||
bool* aRetval)
|
||||
{
|
||||
*aRetval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXHREventTarget)
|
||||
@ -2901,6 +2835,10 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
|
||||
mChannel->GetNotificationCallbacks(getter_AddRefs(mNotificationCallbacks));
|
||||
mChannel->SetNotificationCallbacks(this);
|
||||
|
||||
if (internalHttpChannel) {
|
||||
internalHttpChannel->SetBlockAuthPrompt(ShouldBlockAuthPrompt());
|
||||
}
|
||||
|
||||
// Start reading from the channel
|
||||
// Because of bug 682305, we can't let listener be the XHR object itself
|
||||
// because JS wouldn't be able to use it. So create a listener around 'this'.
|
||||
@ -3521,59 +3459,6 @@ nsXMLHttpRequest::GetInterface(const nsIID & aIID, void **aResult)
|
||||
}
|
||||
else if (aIID.Equals(NS_GET_IID(nsIAuthPrompt)) ||
|
||||
aIID.Equals(NS_GET_IID(nsIAuthPrompt2))) {
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = mChannel->GetURI(getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Verify that it's ok to prompt for credentials here, per spec
|
||||
// http://xhr.spec.whatwg.org/#the-send%28%29-method
|
||||
bool showPrompt = true;
|
||||
|
||||
// If authentication fails, XMLHttpRequest origin and
|
||||
// the request URL are same origin, ...
|
||||
/* Disabled - bug: 799540
|
||||
if (IsCrossSiteCORSRequest()) {
|
||||
showPrompt = false;
|
||||
}
|
||||
*/
|
||||
|
||||
// ... Authorization is not in the list of author request headers, ...
|
||||
if (showPrompt) {
|
||||
for (uint32_t i = 0, len = mModifiedRequestHeaders.Length(); i < len; ++i) {
|
||||
if (mModifiedRequestHeaders[i].header.
|
||||
LowerCaseEqualsLiteral("authorization")) {
|
||||
showPrompt = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ... request username is null, and request password is null,
|
||||
if (showPrompt) {
|
||||
|
||||
nsCString username;
|
||||
rv = uri->GetUsername(username);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCString password;
|
||||
rv = uri->GetPassword(password);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!username.IsEmpty() || !password.IsEmpty()) {
|
||||
showPrompt = false;
|
||||
}
|
||||
}
|
||||
|
||||
// ... user agents should prompt the end user for their username and password.
|
||||
if (!showPrompt) {
|
||||
RefPtr<XMLHttpRequestAuthPrompt> prompt = new XMLHttpRequestAuthPrompt();
|
||||
if (!prompt)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return prompt->QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPromptFactory> wwatch =
|
||||
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -3721,6 +3606,45 @@ nsXMLHttpRequest::EnsureXPCOMifier()
|
||||
return newRef.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
nsXMLHttpRequest::ShouldBlockAuthPrompt()
|
||||
{
|
||||
// Verify that it's ok to prompt for credentials here, per spec
|
||||
// http://xhr.spec.whatwg.org/#the-send%28%29-method
|
||||
|
||||
for (uint32_t i = 0, len = mModifiedRequestHeaders.Length(); i < len; ++i) {
|
||||
if (mModifiedRequestHeaders[i].header.
|
||||
LowerCaseEqualsLiteral("authorization")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = mChannel->GetURI(getter_AddRefs(uri));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Also skip if a username and/or password is provided in the URI.
|
||||
nsCString username;
|
||||
rv = uri->GetUsername(username);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCString password;
|
||||
rv = uri->GetPassword(password);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!username.IsEmpty() || !password.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsXMLHttpRequest::nsHeaderVisitor, nsIHttpHeaderVisitor)
|
||||
|
||||
NS_IMETHODIMP nsXMLHttpRequest::
|
||||
|
@ -796,6 +796,8 @@ protected:
|
||||
|
||||
void ResetResponse();
|
||||
|
||||
bool ShouldBlockAuthPrompt();
|
||||
|
||||
struct RequestHeader
|
||||
{
|
||||
nsCString header;
|
||||
|
@ -415,7 +415,6 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' # b2g(clipboard undefined) b
|
||||
[test_bug276037-1.html]
|
||||
[test_bug276037-2.xhtml]
|
||||
[test_bug282547.html]
|
||||
skip-if = e10s
|
||||
[test_bug28293.html]
|
||||
[test_bug28293.xhtml]
|
||||
[test_bug298064.html]
|
||||
|
@ -115,6 +115,7 @@ struct HttpChannelOpenArgs
|
||||
nsCString schedulingContextID;
|
||||
OptionalCorsPreflightArgs preflightArgs;
|
||||
uint32_t initialRwin;
|
||||
bool blockAuthPrompt;
|
||||
bool suspendAfterSynthesizeResponse;
|
||||
bool allowStaleCacheContent;
|
||||
};
|
||||
|
@ -87,6 +87,7 @@ HttpBaseChannel::HttpBaseChannel()
|
||||
, mAllRedirectsSameOrigin(true)
|
||||
, mAllRedirectsPassTimingAllowCheck(true)
|
||||
, mResponseCouldBeSynthesized(false)
|
||||
, mBlockAuthPrompt(false)
|
||||
, mAllowStaleCacheContent(false)
|
||||
, mSuspendCount(0)
|
||||
, mInitialRwin(0)
|
||||
@ -3158,6 +3159,26 @@ HttpBaseChannel::SetCorsPreflightParameters(const nsTArray<nsCString>& aUnsafeHe
|
||||
mUnsafeHeaders = aUnsafeHeaders;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpBaseChannel::GetBlockAuthPrompt(bool* aValue)
|
||||
{
|
||||
if (!aValue) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aValue = mBlockAuthPrompt;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpBaseChannel::SetBlockAuthPrompt(bool aValue)
|
||||
{
|
||||
ENSURE_CALLED_BEFORE_CONNECT();
|
||||
|
||||
mBlockAuthPrompt = aValue;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
HttpBaseChannel::GetSecureUpgradedURI(nsIURI* aURI, nsIURI** aUpgradedURI)
|
||||
|
@ -126,6 +126,8 @@ public:
|
||||
NS_IMETHOD SetContentLength(int64_t aContentLength) override;
|
||||
NS_IMETHOD Open(nsIInputStream **aResult) override;
|
||||
NS_IMETHOD Open2(nsIInputStream **aResult) override;
|
||||
NS_IMETHOD GetBlockAuthPrompt(bool* aValue) override;
|
||||
NS_IMETHOD SetBlockAuthPrompt(bool aValue) override;
|
||||
|
||||
// nsIEncodedChannel
|
||||
NS_IMETHOD GetApplyConversion(bool *value) override;
|
||||
@ -431,6 +433,8 @@ protected:
|
||||
// True if this channel was intercepted and could receive a synthesized response.
|
||||
uint32_t mResponseCouldBeSynthesized : 1;
|
||||
|
||||
uint32_t mBlockAuthPrompt : 1;
|
||||
|
||||
// If true, we behave as if the LOAD_FROM_CACHE flag has been set.
|
||||
// Used to enforce that flag's behavior but not expose it externally.
|
||||
uint32_t mAllowStaleCacheContent : 1;
|
||||
|
@ -1964,6 +1964,8 @@ HttpChannelChild::ContinueAsyncOpen()
|
||||
}
|
||||
openArgs.cacheKey() = cacheKey;
|
||||
|
||||
openArgs.blockAuthPrompt() = mBlockAuthPrompt;
|
||||
|
||||
openArgs.allowStaleCacheContent() = mAllowStaleCacheContent;
|
||||
|
||||
nsresult rv = mozilla::ipc::LoadInfoToLoadInfoArgs(mLoadInfo, &openArgs.loadInfo());
|
||||
|
@ -131,7 +131,8 @@ HttpChannelParent::Init(const HttpChannelCreationArgs& aArgs)
|
||||
a.loadInfo(), a.synthesizedResponseHead(),
|
||||
a.synthesizedSecurityInfoSerialization(),
|
||||
a.cacheKey(), a.schedulingContextID(), a.preflightArgs(),
|
||||
a.initialRwin(), a.suspendAfterSynthesizeResponse(),
|
||||
a.initialRwin(), a.blockAuthPrompt(),
|
||||
a.suspendAfterSynthesizeResponse(),
|
||||
a.allowStaleCacheContent());
|
||||
}
|
||||
case HttpChannelCreationArgs::THttpChannelConnectArgs:
|
||||
@ -265,6 +266,7 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
|
||||
const nsCString& aSchedulingContextID,
|
||||
const OptionalCorsPreflightArgs& aCorsPreflightArgs,
|
||||
const uint32_t& aInitialRwin,
|
||||
const bool& aBlockAuthPrompt,
|
||||
const bool& aSuspendAfterSynthesizeResponse,
|
||||
const bool& aAllowStaleCacheContent)
|
||||
{
|
||||
@ -430,6 +432,7 @@ HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
|
||||
mChannel->SetAllowSpdy(allowSpdy);
|
||||
mChannel->SetAllowAltSvc(allowAltSvc);
|
||||
mChannel->SetInitialRwin(aInitialRwin);
|
||||
mChannel->SetBlockAuthPrompt(aBlockAuthPrompt);
|
||||
|
||||
nsCOMPtr<nsIApplicationCacheChannel> appCacheChan =
|
||||
do_QueryObject(mChannel);
|
||||
|
@ -137,6 +137,7 @@ protected:
|
||||
const nsCString& aSchedulingContextID,
|
||||
const OptionalCorsPreflightArgs& aCorsPreflightArgs,
|
||||
const uint32_t& aInitialRwin,
|
||||
const bool& aBlockAuthPrompt,
|
||||
const bool& aSuspendAfterSynthesizeResponse,
|
||||
const bool& aAllowStaleCacheContent);
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsHttpHandler.h"
|
||||
#include "nsIHttpAuthenticator.h"
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsIAuthPrompt2.h"
|
||||
#include "nsIAuthPromptProvider.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
@ -817,6 +818,18 @@ nsHttpChannelAuthProvider::GetCredentialsForChallenge(const char *challenge,
|
||||
bool
|
||||
nsHttpChannelAuthProvider::BlockPrompt()
|
||||
{
|
||||
// Verify that it's ok to prompt for credentials here, per spec
|
||||
// http://xhr.spec.whatwg.org/#the-send%28%29-method
|
||||
|
||||
nsCOMPtr<nsIHttpChannelInternal> chanInternal = do_QueryInterface(mAuthChannel);
|
||||
MOZ_ASSERT(chanInternal);
|
||||
|
||||
bool skipAuthentication = false;
|
||||
nsresult rv = chanInternal->GetBlockAuthPrompt(&skipAuthentication);
|
||||
if (NS_SUCCEEDED(rv) && skipAuthentication) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIChannel> chan = do_QueryInterface(mAuthChannel);
|
||||
nsCOMPtr<nsILoadInfo> loadInfo;
|
||||
chan->GetLoadInfo(getter_AddRefs(loadInfo));
|
||||
|
@ -39,7 +39,7 @@ interface nsIHttpUpgradeListener : nsISupports
|
||||
* using any feature exposed by this interface, be aware that this interface
|
||||
* will change and you will be broken. You have been warned.
|
||||
*/
|
||||
[scriptable, uuid(f292a080-f2f6-41d6-8aa4-71337e477360)]
|
||||
[scriptable, uuid(01b8296a-e206-4e5f-acab-82bd8b6a900c)]
|
||||
interface nsIHttpChannelInternal : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -264,4 +264,12 @@ interface nsIHttpChannelInternal : nsISupports
|
||||
*/
|
||||
[noscript, notxpcom, nostdcall]
|
||||
void setCorsPreflightParameters(in StringArrayRef unsafeHeaders);
|
||||
|
||||
/**
|
||||
* When set to true, the channel will not pop any authentication prompts up
|
||||
* to the user. When provided or cached credentials lead to an
|
||||
* authentication failure, that failure will be propagated to the channel
|
||||
* listener. Must be called before opening the channel, otherwise throws.
|
||||
*/
|
||||
attribute boolean blockAuthPrompt;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user