mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1184967 P1 Set RequestMode based on LoadInfo securityMode and client request content policy. r=nsm
This commit is contained in:
parent
293122e98b
commit
6fa0c8de16
@ -206,8 +206,9 @@ InternalRequest::MapContentPolicyTypeToRequestContext(nsContentPolicyType aConte
|
||||
return context;
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
InternalRequest::IsNavigationRequest() const
|
||||
InternalRequest::IsNavigationContentPolicy(nsContentPolicyType aContentPolicyType)
|
||||
{
|
||||
// https://fetch.spec.whatwg.org/#navigation-request-context
|
||||
//
|
||||
@ -215,17 +216,22 @@ InternalRequest::IsNavigationRequest() const
|
||||
// "iframe", "internal" (as long as context frame type is not "none"),
|
||||
// "location", "metarefresh", and "prerender".
|
||||
//
|
||||
// TODO: include equivalent check for "form" context
|
||||
// TODO: include equivalent check for "prerender" context
|
||||
return mContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT ||
|
||||
mContentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT ||
|
||||
mContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_FRAME ||
|
||||
mContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_IFRAME ||
|
||||
mContentPolicyType == nsIContentPolicy::TYPE_REFRESH;
|
||||
// Note, all of these request types are effectively initiated by nsDocShell.
|
||||
//
|
||||
// The TYPE_REFRESH is used in some code paths for metarefresh, but will not
|
||||
// be seen during the actual load. Instead the new load gets a normal
|
||||
// nsDocShell policy type. We include it here in case this utility method
|
||||
// is called before the load starts.
|
||||
return aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT ||
|
||||
aContentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT ||
|
||||
aContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_FRAME ||
|
||||
aContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_IFRAME ||
|
||||
aContentPolicyType == nsIContentPolicy::TYPE_REFRESH;
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
InternalRequest::IsWorkerRequest() const
|
||||
InternalRequest::IsWorkerContentPolicy(nsContentPolicyType aContentPolicyType)
|
||||
{
|
||||
// https://fetch.spec.whatwg.org/#worker-request-context
|
||||
//
|
||||
@ -235,8 +241,20 @@ InternalRequest::IsWorkerRequest() const
|
||||
// Note, service workers are not included here because currently there is
|
||||
// no way to generate a Request with a "serviceworker" RequestContext.
|
||||
// ServiceWorker scripts cannot be intercepted.
|
||||
return mContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
|
||||
mContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER;
|
||||
return aContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
|
||||
aContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER;
|
||||
}
|
||||
|
||||
bool
|
||||
InternalRequest::IsNavigationRequest() const
|
||||
{
|
||||
return IsNavigationContentPolicy(mContentPolicyType);
|
||||
}
|
||||
|
||||
bool
|
||||
InternalRequest::IsWorkerRequest() const
|
||||
{
|
||||
return IsWorkerContentPolicy(mContentPolicyType);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -245,5 +263,63 @@ InternalRequest::IsClientRequest() const
|
||||
return IsNavigationRequest() || IsWorkerRequest();
|
||||
}
|
||||
|
||||
// static
|
||||
RequestMode
|
||||
InternalRequest::MapChannelToRequestMode(nsIChannel* aChannel)
|
||||
{
|
||||
MOZ_ASSERT(aChannel);
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aChannel->GetLoadInfo(getter_AddRefs(loadInfo))));
|
||||
|
||||
// RequestMode deviates from our internal security mode for navigations.
|
||||
// While navigations normally allow cross origin we must set a same-origin
|
||||
// RequestMode to get the correct service worker interception restrictions
|
||||
// in place.
|
||||
// TODO: remove the worker override once securityMode is fully implemented (bug 1189945)
|
||||
nsContentPolicyType contentPolicy = loadInfo->InternalContentPolicyType();
|
||||
if (IsNavigationContentPolicy(contentPolicy) ||
|
||||
IsWorkerContentPolicy(contentPolicy)) {
|
||||
return RequestMode::Same_origin;
|
||||
}
|
||||
|
||||
uint32_t securityMode;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(loadInfo->GetSecurityMode(&securityMode)));
|
||||
|
||||
switch(securityMode) {
|
||||
case nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS:
|
||||
case nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED:
|
||||
return RequestMode::Same_origin;
|
||||
case nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS:
|
||||
case nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL:
|
||||
return RequestMode::No_cors;
|
||||
case nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS:
|
||||
// TODO: Check additional flag force-preflight after bug 1199693 (bug 1189945)
|
||||
return RequestMode::Cors;
|
||||
default:
|
||||
// TODO: assert never reached after CorsMode flag removed (bug 1189945)
|
||||
MOZ_ASSERT(securityMode == nsILoadInfo::SEC_NORMAL);
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: remove following code once securityMode is fully implemented (bug 1189945)
|
||||
|
||||
// We only support app:// protocol interception in non-release builds.
|
||||
#ifndef RELEASE_BUILD
|
||||
nsCOMPtr<nsIJARChannel> jarChannel = do_QueryInterface(aChannel);
|
||||
if (jarChannel) {
|
||||
return RequestMode::No_cors;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIHttpChannelInternal> httpChannel = do_QueryInterface(aChannel);
|
||||
|
||||
uint32_t corsMode;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(httpChannel->GetCorsMode(&corsMode)));
|
||||
|
||||
// This cast is valid due to static asserts in ServiceWorkerManager.cpp.
|
||||
return static_cast<RequestMode>(corsMode);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -377,6 +377,8 @@ public:
|
||||
bool
|
||||
IsClientRequest() const;
|
||||
|
||||
static RequestMode
|
||||
MapChannelToRequestMode(nsIChannel* aChannel);
|
||||
|
||||
private:
|
||||
// Does not copy mBodyStream. Use fallible Clone() for complete copy.
|
||||
@ -387,6 +389,12 @@ private:
|
||||
static RequestContext
|
||||
MapContentPolicyTypeToRequestContext(nsContentPolicyType aContentPolicyType);
|
||||
|
||||
static bool
|
||||
IsNavigationContentPolicy(nsContentPolicyType aContentPolicyType);
|
||||
|
||||
static bool
|
||||
IsWorkerContentPolicy(nsContentPolicyType aContentPolicyType);
|
||||
|
||||
nsCString mMethod;
|
||||
// mURL always stores the url with the ref stripped
|
||||
nsCString mURL;
|
||||
|
@ -150,7 +150,7 @@ class RespondWithHandler final : public PromiseNativeHandler
|
||||
nsMainThreadPtrHandle<nsIInterceptedChannel> mInterceptedChannel;
|
||||
nsMainThreadPtrHandle<ServiceWorker> mServiceWorker;
|
||||
const RequestMode mRequestMode;
|
||||
const bool mIsClientRequest;
|
||||
const DebugOnly<bool> mIsClientRequest;
|
||||
const bool mIsNavigationRequest;
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -272,8 +272,6 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
||||
// If one of the following conditions is true, return a network error:
|
||||
// * response's type is "error".
|
||||
// * request's mode is not "no-cors" and response's type is "opaque".
|
||||
// * request is a client request and response's type is neither "basic"
|
||||
// nor "default".
|
||||
// * request is not a navigation request and response's type is
|
||||
// "opaqueredirect".
|
||||
|
||||
@ -282,19 +280,13 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT_IF(mIsClientRequest, mRequestMode == RequestMode::Same_origin);
|
||||
|
||||
if (response->Type() == ResponseType::Opaque && mRequestMode != RequestMode::No_cors) {
|
||||
autoCancel.SetCancelStatus(NS_ERROR_BAD_OPAQUE_INTERCEPTION_REQUEST_MODE);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: remove this case as its no longer in the spec (bug 1184967)
|
||||
if (mIsClientRequest && response->Type() != ResponseType::Basic &&
|
||||
response->Type() != ResponseType::Default &&
|
||||
response->Type() != ResponseType::Opaqueredirect) {
|
||||
autoCancel.SetCancelStatus(NS_ERROR_CLIENT_REQUEST_OPAQUE_INTERCEPTION);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mIsNavigationRequest && response->Type() == ResponseType::Opaqueredirect) {
|
||||
autoCancel.SetCancelStatus(NS_ERROR_BAD_OPAQUE_REDIRECT_INTERCEPTION);
|
||||
return;
|
||||
|
@ -3709,22 +3709,7 @@ public:
|
||||
nsCOMPtr<nsIHttpChannelInternal> internalChannel = do_QueryInterface(httpChannel);
|
||||
NS_ENSURE_TRUE(internalChannel, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
uint32_t corsMode;
|
||||
internalChannel->GetCorsMode(&corsMode);
|
||||
switch (corsMode) {
|
||||
case nsIHttpChannelInternal::CORS_MODE_SAME_ORIGIN:
|
||||
mRequestMode = RequestMode::Same_origin;
|
||||
break;
|
||||
case nsIHttpChannelInternal::CORS_MODE_NO_CORS:
|
||||
mRequestMode = RequestMode::No_cors;
|
||||
break;
|
||||
case nsIHttpChannelInternal::CORS_MODE_CORS:
|
||||
case nsIHttpChannelInternal::CORS_MODE_CORS_WITH_FORCED_PREFLIGHT:
|
||||
mRequestMode = RequestMode::Cors;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unexpected CORS mode");
|
||||
}
|
||||
mRequestMode = InternalRequest::MapChannelToRequestMode(channel);
|
||||
|
||||
// This is safe due to static_asserts at top of file.
|
||||
uint32_t redirectMode;
|
||||
@ -3757,6 +3742,8 @@ public:
|
||||
|
||||
mMethod = "GET";
|
||||
|
||||
mRequestMode = InternalRequest::MapChannelToRequestMode(channel);
|
||||
|
||||
if (loadFlags & nsIRequest::LOAD_ANONYMOUS) {
|
||||
mRequestCredentials = RequestCredentials::Omit;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user