mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1184607 P4 Handle the RequestRedirect mode during service worker interception. r=nsm
* * * Bug 1184607 P4 interdiff 001 fix manual redirect assertion for navigations r=nsm * * * Bug 1184607 P4 interdiff 002 dom/worker nits
This commit is contained in:
parent
4dfeebb637
commit
0fbb3b30fe
@ -4970,6 +4970,7 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
|
||||
case NS_ERROR_INTERCEPTED_ERROR_RESPONSE:
|
||||
case NS_ERROR_INTERCEPTED_USED_RESPONSE:
|
||||
case NS_ERROR_CLIENT_REQUEST_OPAQUE_INTERCEPTION:
|
||||
case NS_ERROR_BAD_OPAQUE_REDIRECT_INTERCEPTION:
|
||||
// ServiceWorker intercepted request, but something went wrong.
|
||||
nsContentUtils::MaybeReportInterceptionErrorToConsole(GetDocument(),
|
||||
aError);
|
||||
|
@ -3458,6 +3458,8 @@ nsContentUtils::MaybeReportInterceptionErrorToConsole(nsIDocument* aDocument,
|
||||
messageName = "InterceptedUsedResponse";
|
||||
} else if (aError == NS_ERROR_CLIENT_REQUEST_OPAQUE_INTERCEPTION) {
|
||||
messageName = "ClientRequestOpaqueInterception";
|
||||
} else if (aError == NS_ERROR_BAD_OPAQUE_REDIRECT_INTERCEPTION) {
|
||||
messageName = "BadOpaqueRedirectInterception";
|
||||
}
|
||||
|
||||
if (messageName) {
|
||||
|
@ -173,5 +173,7 @@ BadOpaqueInterceptionRequestMode=A ServiceWorker passed an opaque Response to Fe
|
||||
InterceptedErrorResponse=A ServiceWorker passed an Error Response to FetchEvent.respondWith(). This typically means the ServiceWorker performed an invalid fetch() call.
|
||||
# LOCALIZATION NOTE: Do not translate "ServiceWorker", "Response", "FetchEvent.respondWith()", or "Response.clone()".
|
||||
InterceptedUsedResponse=A ServiceWorker passed a used Response to FetchEvent.respondWith(). The body of a Response may only be read once. Use Response.clone() to access the body multiple times.
|
||||
# LOCALIZATION NOTE: Do not translate "ServiceWorker", "Response", "FetchEvent.respondWith()", "FetchEvent.request", or "Worker".
|
||||
# LOCALIZATION NOTE: Do not translate "ServiceWorker", "opaque", "Response", "FetchEvent.respondWith()", "FetchEvent.request", or "Worker".
|
||||
ClientRequestOpaqueInterception=A ServiceWorker passed an opaque Response to FetchEvent.respondWith() while FetchEvent.request was a client request. A client request is generally a browser navigation or top-level Worker script.
|
||||
# LOCALIZATION NOTE: Do not translate "ServiceWorker", "opaqueredirect", "Response", "FetchEvent.respondWith()", or "FetchEvent.request".
|
||||
BadOpaqueRedirectInterception=A ServiceWorker passed an opaqueredirect Response to FetchEvent.respondWith() while FetchEvent.request was not a navigation request.
|
||||
|
@ -130,7 +130,8 @@ public:
|
||||
return rv;
|
||||
}
|
||||
|
||||
mChannel->SynthesizeStatus(mInternalResponse->GetStatus(), mInternalResponse->GetStatusText());
|
||||
mChannel->SynthesizeStatus(mInternalResponse->GetUnfilteredStatus(),
|
||||
mInternalResponse->GetUnfilteredStatusText());
|
||||
|
||||
nsAutoTArray<InternalHeaders::Entry, 5> entries;
|
||||
mInternalResponse->UnfilteredHeaders()->GetEntries(entries);
|
||||
@ -148,18 +149,21 @@ class RespondWithHandler final : public PromiseNativeHandler
|
||||
{
|
||||
nsMainThreadPtrHandle<nsIInterceptedChannel> mInterceptedChannel;
|
||||
nsMainThreadPtrHandle<ServiceWorker> mServiceWorker;
|
||||
RequestMode mRequestMode;
|
||||
bool mIsClientRequest;
|
||||
const RequestMode mRequestMode;
|
||||
const bool mIsClientRequest;
|
||||
const bool mIsNavigationRequest;
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
RespondWithHandler(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
|
||||
nsMainThreadPtrHandle<ServiceWorker>& aServiceWorker,
|
||||
RequestMode aRequestMode, bool aIsClientRequest)
|
||||
RequestMode aRequestMode, bool aIsClientRequest,
|
||||
bool aIsNavigationRequest)
|
||||
: mInterceptedChannel(aChannel)
|
||||
, mServiceWorker(aServiceWorker)
|
||||
, mRequestMode(aRequestMode)
|
||||
, mIsClientRequest(aIsClientRequest)
|
||||
, mIsNavigationRequest(aIsNavigationRequest)
|
||||
{
|
||||
}
|
||||
|
||||
@ -264,12 +268,14 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
||||
return;
|
||||
}
|
||||
|
||||
// Section 4.2, step 2.2:
|
||||
// Section "HTTP Fetch", step 2.2:
|
||||
// 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".
|
||||
|
||||
if (response->Type() == ResponseType::Error) {
|
||||
autoCancel.SetCancelStatus(NS_ERROR_INTERCEPTED_ERROR_RESPONSE);
|
||||
@ -281,12 +287,19 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
||||
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::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;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(response->BodyUsed())) {
|
||||
autoCancel.SetCancelStatus(NS_ERROR_INTERCEPTED_USED_RESPONSE);
|
||||
return;
|
||||
@ -300,7 +313,7 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
||||
nsAutoPtr<RespondWithClosure> closure(
|
||||
new RespondWithClosure(mInterceptedChannel, ir, worker->GetChannelInfo()));
|
||||
nsCOMPtr<nsIInputStream> body;
|
||||
ir->GetInternalBody(getter_AddRefs(body));
|
||||
ir->GetUnfilteredBody(getter_AddRefs(body));
|
||||
// Errors and redirects may not have a body.
|
||||
if (body) {
|
||||
response->SetBodyUsed();
|
||||
@ -359,7 +372,7 @@ FetchEvent::RespondWith(Promise& aArg, ErrorResult& aRv)
|
||||
mWaitToRespond = true;
|
||||
nsRefPtr<RespondWithHandler> handler =
|
||||
new RespondWithHandler(mChannel, mServiceWorker, mRequest->Mode(),
|
||||
ir->IsClientRequest());
|
||||
ir->IsClientRequest(), ir->IsNavigationRequest());
|
||||
aArg.AppendNativeHandler(handler);
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,15 @@ static_assert(nsIHttpChannelInternal::CORS_MODE_CORS == static_cast<uint32_t>(Re
|
||||
static_assert(nsIHttpChannelInternal::CORS_MODE_CORS_WITH_FORCED_PREFLIGHT == static_cast<uint32_t>(RequestMode::Cors_with_forced_preflight),
|
||||
"RequestMode enumeration value should match Necko CORS mode value.");
|
||||
|
||||
static_assert(nsIHttpChannelInternal::REDIRECT_MODE_FOLLOW == static_cast<uint32_t>(RequestRedirect::Follow),
|
||||
"RequestRedirect enumeration value should make Necko Redirect mode value.");
|
||||
static_assert(nsIHttpChannelInternal::REDIRECT_MODE_ERROR == static_cast<uint32_t>(RequestRedirect::Error),
|
||||
"RequestRedirect enumeration value should make Necko Redirect mode value.");
|
||||
static_assert(nsIHttpChannelInternal::REDIRECT_MODE_MANUAL == static_cast<uint32_t>(RequestRedirect::Manual),
|
||||
"RequestRedirect enumeration value should make Necko Redirect mode value.");
|
||||
static_assert(3 == static_cast<uint32_t>(RequestRedirect::EndGuard_),
|
||||
"RequestRedirect enumeration value should make Necko Redirect mode value.");
|
||||
|
||||
static StaticRefPtr<ServiceWorkerManager> gInstance;
|
||||
|
||||
// Tracks the "dom.disable_open_click_delay" preference. Modified on main
|
||||
@ -3616,7 +3625,9 @@ class FetchEventRunnable : public WorkerRunnable
|
||||
nsCString mSpec;
|
||||
nsCString mMethod;
|
||||
bool mIsReload;
|
||||
DebugOnly<bool> mIsHttpChannel;
|
||||
RequestMode mRequestMode;
|
||||
RequestRedirect mRequestRedirect;
|
||||
RequestCredentials mRequestCredentials;
|
||||
nsContentPolicyType mContentPolicyType;
|
||||
nsCOMPtr<nsIInputStream> mUploadStream;
|
||||
@ -3632,7 +3643,9 @@ public:
|
||||
, mServiceWorker(aServiceWorker)
|
||||
, mClientInfo(aClientInfo)
|
||||
, mIsReload(aIsReload)
|
||||
, mIsHttpChannel(false)
|
||||
, mRequestMode(RequestMode::No_cors)
|
||||
, mRequestRedirect(RequestRedirect::Follow)
|
||||
// By default we set it to same-origin since normal HTTP fetches always
|
||||
// send credentials to same-origin websites unless explicitly forbidden.
|
||||
, mRequestCredentials(RequestCredentials::Same_origin)
|
||||
@ -3688,15 +3701,17 @@ public:
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
|
||||
if (httpChannel) {
|
||||
mIsHttpChannel = true;
|
||||
|
||||
rv = httpChannel->GetRequestMethod(mMethod);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIHttpChannelInternal> internalChannel = do_QueryInterface(httpChannel);
|
||||
NS_ENSURE_TRUE(internalChannel, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
uint32_t mode;
|
||||
internalChannel->GetCorsMode(&mode);
|
||||
switch (mode) {
|
||||
uint32_t corsMode;
|
||||
internalChannel->GetCorsMode(&corsMode);
|
||||
switch (corsMode) {
|
||||
case nsIHttpChannelInternal::CORS_MODE_SAME_ORIGIN:
|
||||
mRequestMode = RequestMode::Same_origin;
|
||||
break;
|
||||
@ -3711,6 +3726,11 @@ public:
|
||||
MOZ_CRASH("Unexpected CORS mode");
|
||||
}
|
||||
|
||||
// This is safe due to static_asserts at top of file.
|
||||
uint32_t redirectMode;
|
||||
internalChannel->GetRedirectMode(&redirectMode);
|
||||
mRequestRedirect = static_cast<RequestRedirect>(redirectMode);
|
||||
|
||||
if (loadFlags & nsIRequest::LOAD_ANONYMOUS) {
|
||||
mRequestCredentials = RequestCredentials::Omit;
|
||||
} else {
|
||||
@ -3803,6 +3823,7 @@ private:
|
||||
reqInit.mHeaders.Value().SetAsHeaders() = headers;
|
||||
|
||||
reqInit.mMode.Construct(mRequestMode);
|
||||
reqInit.mRedirect.Construct(mRequestRedirect);
|
||||
reqInit.mCredentials.Construct(mRequestCredentials);
|
||||
|
||||
ErrorResult result;
|
||||
@ -3821,6 +3842,11 @@ private:
|
||||
|
||||
request->SetContentPolicyType(mContentPolicyType);
|
||||
|
||||
// TODO: remove conditional on http here once app protocol support is
|
||||
// removed from service worker interception
|
||||
MOZ_ASSERT_IF(mIsHttpChannel && internalReq->IsNavigationRequest(),
|
||||
request->Redirect() == RequestRedirect::Manual);
|
||||
|
||||
RootedDictionary<FetchEventInit> init(aCx);
|
||||
init.mRequest.Construct();
|
||||
init.mRequest.Value() = request;
|
||||
|
@ -333,6 +333,8 @@
|
||||
ERROR(NS_ERROR_INTERCEPTED_USED_RESPONSE, FAILURE(104)),
|
||||
/* Service worker intercepted a client request with an opaque response */
|
||||
ERROR(NS_ERROR_CLIENT_REQUEST_OPAQUE_INTERCEPTION, FAILURE(105)),
|
||||
/* Service worker intercepted a non-navigation with an opaque redirect */
|
||||
ERROR(NS_ERROR_BAD_OPAQUE_REDIRECT_INTERCEPTION, FAILURE(106)),
|
||||
#undef MODULE
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user