mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1197379 - Remove support for intercepting app:// URIs using service workers; r=jdm
This commit is contained in:
parent
99925bf95f
commit
dc29e5f515
1
dom/cache/CacheStorage.cpp
vendored
1
dom/cache/CacheStorage.cpp
vendored
@ -119,7 +119,6 @@ IsTrusted(const PrincipalInfo& aPrincipalInfo, bool aTestingPrefEnabled)
|
|||||||
|
|
||||||
nsAutoCString scheme(Substring(flatURL, schemePos, schemeLen));
|
nsAutoCString scheme(Substring(flatURL, schemePos, schemeLen));
|
||||||
if (scheme.LowerCaseEqualsLiteral("https") ||
|
if (scheme.LowerCaseEqualsLiteral("https") ||
|
||||||
scheme.LowerCaseEqualsLiteral("app") ||
|
|
||||||
scheme.LowerCaseEqualsLiteral("file")) {
|
scheme.LowerCaseEqualsLiteral("file")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
3
dom/cache/TypeUtils.cpp
vendored
3
dom/cache/TypeUtils.cpp
vendored
@ -417,8 +417,7 @@ TypeUtils::ProcessURL(nsACString& aUrl, bool* aSchemeValidOut,
|
|||||||
if (aSchemeValidOut) {
|
if (aSchemeValidOut) {
|
||||||
nsAutoCString scheme(Substring(flatURL, schemePos, schemeLen));
|
nsAutoCString scheme(Substring(flatURL, schemePos, schemeLen));
|
||||||
*aSchemeValidOut = scheme.LowerCaseEqualsLiteral("http") ||
|
*aSchemeValidOut = scheme.LowerCaseEqualsLiteral("http") ||
|
||||||
scheme.LowerCaseEqualsLiteral("https") ||
|
scheme.LowerCaseEqualsLiteral("https");
|
||||||
scheme.LowerCaseEqualsLiteral("app");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t queryPos;
|
uint32_t queryPos;
|
||||||
|
@ -13,8 +13,6 @@
|
|||||||
#include "nsSerializationHelper.h"
|
#include "nsSerializationHelper.h"
|
||||||
#include "mozilla/net/HttpBaseChannel.h"
|
#include "mozilla/net/HttpBaseChannel.h"
|
||||||
#include "mozilla/ipc/ChannelInfo.h"
|
#include "mozilla/ipc/ChannelInfo.h"
|
||||||
#include "nsIJARChannel.h"
|
|
||||||
#include "nsJARChannel.h"
|
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
@ -90,32 +88,20 @@ ChannelInfo::ResurrectInfoOnChannel(nsIChannel* aChannel)
|
|||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
MOZ_ASSERT(mInited);
|
MOZ_ASSERT(mInited);
|
||||||
|
|
||||||
// These pointers may be null at this point. They must be checked before
|
|
||||||
// being dereferenced.
|
|
||||||
nsCOMPtr<nsIHttpChannel> httpChannel =
|
|
||||||
do_QueryInterface(aChannel);
|
|
||||||
nsCOMPtr<nsIJARChannel> jarChannel =
|
|
||||||
do_QueryInterface(aChannel);
|
|
||||||
|
|
||||||
if (!mSecurityInfo.IsEmpty()) {
|
if (!mSecurityInfo.IsEmpty()) {
|
||||||
nsCOMPtr<nsISupports> infoObj;
|
nsCOMPtr<nsISupports> infoObj;
|
||||||
nsresult rv = NS_DeserializeObject(mSecurityInfo, getter_AddRefs(infoObj));
|
nsresult rv = NS_DeserializeObject(mSecurityInfo, getter_AddRefs(infoObj));
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
if (httpChannel) {
|
nsCOMPtr<nsIHttpChannel> httpChannel =
|
||||||
net::HttpBaseChannel* httpBaseChannel =
|
do_QueryInterface(aChannel);
|
||||||
static_cast<net::HttpBaseChannel*>(httpChannel.get());
|
MOZ_ASSERT(httpChannel);
|
||||||
rv = httpBaseChannel->OverrideSecurityInfo(infoObj);
|
net::HttpBaseChannel* httpBaseChannel =
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
static_cast<net::HttpBaseChannel*>(httpChannel.get());
|
||||||
return rv;
|
rv = httpBaseChannel->OverrideSecurityInfo(infoObj);
|
||||||
}
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
} else {
|
return rv;
|
||||||
if (NS_WARN_IF(!jarChannel)) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
static_cast<nsJARChannel*>(jarChannel.get())->
|
|
||||||
OverrideSecurityInfo(infoObj);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include "nsIHttpChannel.h"
|
#include "nsIHttpChannel.h"
|
||||||
#include "nsIHttpChannelInternal.h"
|
#include "nsIHttpChannelInternal.h"
|
||||||
#include "nsIHttpHeaderVisitor.h"
|
#include "nsIHttpHeaderVisitor.h"
|
||||||
#include "nsIJARChannel.h"
|
|
||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
#include "nsIThreadRetargetableRequest.h"
|
#include "nsIThreadRetargetableRequest.h"
|
||||||
#include "nsIUploadChannel2.h"
|
#include "nsIUploadChannel2.h"
|
||||||
@ -463,7 +462,6 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
|
|||||||
RefPtr<InternalResponse> response;
|
RefPtr<InternalResponse> response;
|
||||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
|
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
|
||||||
nsCOMPtr<nsIJARChannel> jarChannel = do_QueryInterface(aRequest);
|
|
||||||
|
|
||||||
// On a successful redirect we perform the following substeps of HTTP Fetch,
|
// On a successful redirect we perform the following substeps of HTTP Fetch,
|
||||||
// step 5, "redirect status", step 11.
|
// step 5, "redirect status", step 11.
|
||||||
@ -508,18 +506,6 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
|
|||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
NS_WARNING("Failed to visit all headers.");
|
NS_WARNING("Failed to visit all headers.");
|
||||||
}
|
}
|
||||||
} else if (jarChannel) {
|
|
||||||
// We simulate the http protocol for jar/app requests
|
|
||||||
uint32_t responseStatus = 200;
|
|
||||||
nsAutoCString statusText;
|
|
||||||
response = new InternalResponse(responseStatus, NS_LITERAL_CSTRING("OK"));
|
|
||||||
ErrorResult result;
|
|
||||||
nsAutoCString contentType;
|
|
||||||
jarChannel->GetContentType(contentType);
|
|
||||||
response->Headers()->Append(NS_LITERAL_CSTRING("content-type"),
|
|
||||||
contentType,
|
|
||||||
result);
|
|
||||||
MOZ_ASSERT(!result.Failed());
|
|
||||||
} else {
|
} else {
|
||||||
response = new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
|
response = new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
|
||||||
|
|
||||||
|
@ -306,14 +306,6 @@ InternalRequest::MapChannelToRequestMode(nsIChannel* aChannel)
|
|||||||
|
|
||||||
// TODO: remove following code once securityMode is fully implemented (bug 1189945)
|
// 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);
|
nsCOMPtr<nsIHttpChannelInternal> httpChannel = do_QueryInterface(aChannel);
|
||||||
|
|
||||||
uint32_t corsMode;
|
uint32_t corsMode;
|
||||||
|
@ -36,8 +36,6 @@ IPDL_SOURCES += [
|
|||||||
|
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
'../workers',
|
'../workers',
|
||||||
# For nsJARChannel.h
|
|
||||||
'/modules/libjar',
|
|
||||||
# For HttpBaseChannel.h dependencies
|
# For HttpBaseChannel.h dependencies
|
||||||
'/netwerk/base',
|
'/netwerk/base',
|
||||||
# For nsDataHandler.h
|
# For nsDataHandler.h
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include "nsIHttpChannel.h"
|
#include "nsIHttpChannel.h"
|
||||||
#include "nsIHttpChannelInternal.h"
|
#include "nsIHttpChannelInternal.h"
|
||||||
#include "nsIHttpHeaderVisitor.h"
|
#include "nsIHttpHeaderVisitor.h"
|
||||||
#include "nsIJARChannel.h"
|
|
||||||
#include "nsINetworkInterceptController.h"
|
#include "nsINetworkInterceptController.h"
|
||||||
#include "nsIMutableArray.h"
|
#include "nsIMutableArray.h"
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
@ -1766,15 +1765,7 @@ ServiceWorkerManager::Register(nsIDOMWindow* aWindow,
|
|||||||
aScriptURI->SchemeIs("http", &isHttp);
|
aScriptURI->SchemeIs("http", &isHttp);
|
||||||
aScriptURI->SchemeIs("https", &isHttps);
|
aScriptURI->SchemeIs("https", &isHttps);
|
||||||
if (NS_WARN_IF(!isHttp && !isHttps)) {
|
if (NS_WARN_IF(!isHttp && !isHttps)) {
|
||||||
#ifdef RELEASE_BUILD
|
|
||||||
return NS_ERROR_DOM_SECURITY_ERR;
|
return NS_ERROR_DOM_SECURITY_ERR;
|
||||||
#else
|
|
||||||
bool isApp = false;
|
|
||||||
aScriptURI->SchemeIs("app", &isApp);
|
|
||||||
if (NS_WARN_IF(!isApp)) {
|
|
||||||
return NS_ERROR_DOM_SECURITY_ERR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCString cleanedScope;
|
nsCString cleanedScope;
|
||||||
|
@ -998,7 +998,6 @@ class FetchEventRunnable : public ExtendableFunctionalEventWorkerRunnable
|
|||||||
nsCString mMethod;
|
nsCString mMethod;
|
||||||
nsString mClientId;
|
nsString mClientId;
|
||||||
bool mIsReload;
|
bool mIsReload;
|
||||||
DebugOnly<bool> mIsHttpChannel;
|
|
||||||
RequestMode mRequestMode;
|
RequestMode mRequestMode;
|
||||||
RequestRedirect mRequestRedirect;
|
RequestRedirect mRequestRedirect;
|
||||||
RequestCredentials mRequestCredentials;
|
RequestCredentials mRequestCredentials;
|
||||||
@ -1021,7 +1020,6 @@ public:
|
|||||||
, mScriptSpec(aScriptSpec)
|
, mScriptSpec(aScriptSpec)
|
||||||
, mClientId(aDocumentId)
|
, mClientId(aDocumentId)
|
||||||
, mIsReload(aIsReload)
|
, mIsReload(aIsReload)
|
||||||
, mIsHttpChannel(false)
|
|
||||||
, mRequestMode(RequestMode::No_cors)
|
, mRequestMode(RequestMode::No_cors)
|
||||||
, mRequestRedirect(RequestRedirect::Follow)
|
, mRequestRedirect(RequestRedirect::Follow)
|
||||||
// By default we set it to same-origin since normal HTTP fetches always
|
// By default we set it to same-origin since normal HTTP fetches always
|
||||||
@ -1070,61 +1068,46 @@ public:
|
|||||||
|
|
||||||
nsCOMPtr<nsIURI> referrerURI;
|
nsCOMPtr<nsIURI> referrerURI;
|
||||||
rv = NS_GetReferrerFromChannel(channel, getter_AddRefs(referrerURI));
|
rv = NS_GetReferrerFromChannel(channel, getter_AddRefs(referrerURI));
|
||||||
// We can't bail on failure since certain non-http channels like JAR
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
// channels are intercepted but don't have referrers.
|
if (referrerURI) {
|
||||||
if (NS_SUCCEEDED(rv) && referrerURI) {
|
|
||||||
rv = referrerURI->GetSpec(mReferrer);
|
rv = referrerURI->GetSpec(mReferrer);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
|
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
|
||||||
if (httpChannel) {
|
MOZ_ASSERT(httpChannel, "How come we don't have an HTTP channel?");
|
||||||
mIsHttpChannel = true;
|
|
||||||
|
|
||||||
rv = httpChannel->GetRequestMethod(mMethod);
|
rv = httpChannel->GetRequestMethod(mMethod);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIHttpChannelInternal> internalChannel = do_QueryInterface(httpChannel);
|
||||||
|
NS_ENSURE_TRUE(internalChannel, NS_ERROR_NOT_AVAILABLE);
|
||||||
|
|
||||||
|
mRequestMode = InternalRequest::MapChannelToRequestMode(channel);
|
||||||
|
|
||||||
|
// This is safe due to static_asserts at top of file.
|
||||||
|
uint32_t redirectMode;
|
||||||
|
internalChannel->GetRedirectMode(&redirectMode);
|
||||||
|
mRequestRedirect = static_cast<RequestRedirect>(redirectMode);
|
||||||
|
|
||||||
|
mRequestCredentials = InternalRequest::MapChannelToRequestCredentials(channel);
|
||||||
|
|
||||||
|
rv = httpChannel->VisitNonDefaultRequestHeaders(this);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(httpChannel);
|
||||||
|
if (uploadChannel) {
|
||||||
|
MOZ_ASSERT(!mUploadStream);
|
||||||
|
bool bodyHasHeaders = false;
|
||||||
|
rv = uploadChannel->GetUploadStreamHasHeaders(&bodyHasHeaders);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
nsCOMPtr<nsIInputStream> uploadStream;
|
||||||
nsCOMPtr<nsIHttpChannelInternal> internalChannel = do_QueryInterface(httpChannel);
|
rv = uploadChannel->CloneUploadStream(getter_AddRefs(uploadStream));
|
||||||
NS_ENSURE_TRUE(internalChannel, NS_ERROR_NOT_AVAILABLE);
|
|
||||||
|
|
||||||
mRequestMode = InternalRequest::MapChannelToRequestMode(channel);
|
|
||||||
|
|
||||||
// This is safe due to static_asserts at top of file.
|
|
||||||
uint32_t redirectMode;
|
|
||||||
internalChannel->GetRedirectMode(&redirectMode);
|
|
||||||
mRequestRedirect = static_cast<RequestRedirect>(redirectMode);
|
|
||||||
|
|
||||||
mRequestCredentials = InternalRequest::MapChannelToRequestCredentials(channel);
|
|
||||||
|
|
||||||
rv = httpChannel->VisitNonDefaultRequestHeaders(this);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
if (bodyHasHeaders) {
|
||||||
nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(httpChannel);
|
HandleBodyWithHeaders(uploadStream);
|
||||||
if (uploadChannel) {
|
} else {
|
||||||
MOZ_ASSERT(!mUploadStream);
|
mUploadStream = uploadStream;
|
||||||
bool bodyHasHeaders = false;
|
|
||||||
rv = uploadChannel->GetUploadStreamHasHeaders(&bodyHasHeaders);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
nsCOMPtr<nsIInputStream> uploadStream;
|
|
||||||
rv = uploadChannel->CloneUploadStream(getter_AddRefs(uploadStream));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
if (bodyHasHeaders) {
|
|
||||||
HandleBodyWithHeaders(uploadStream);
|
|
||||||
} else {
|
|
||||||
mUploadStream = uploadStream;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
nsCOMPtr<nsIJARChannel> jarChannel = do_QueryInterface(channel);
|
|
||||||
// If it is not an HTTP channel it must be a JAR one.
|
|
||||||
NS_ENSURE_TRUE(jarChannel, NS_ERROR_NOT_AVAILABLE);
|
|
||||||
|
|
||||||
mMethod = "GET";
|
|
||||||
|
|
||||||
mRequestMode = InternalRequest::MapChannelToRequestMode(channel);
|
|
||||||
|
|
||||||
if (loadFlags & nsIRequest::LOAD_ANONYMOUS) {
|
|
||||||
mRequestCredentials = RequestCredentials::Omit;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1213,9 +1196,7 @@ private:
|
|||||||
}
|
}
|
||||||
RefPtr<Request> request = new Request(global, internalReq);
|
RefPtr<Request> request = new Request(global, internalReq);
|
||||||
|
|
||||||
// TODO: remove conditional on http here once app protocol support is
|
MOZ_ASSERT_IF(internalReq->IsNavigationRequest(),
|
||||||
// removed from service worker interception
|
|
||||||
MOZ_ASSERT_IF(mIsHttpChannel && internalReq->IsNavigationRequest(),
|
|
||||||
request->Redirect() == RequestRedirect::Manual);
|
request->Redirect() == RequestRedirect::Manual);
|
||||||
|
|
||||||
RootedDictionary<FetchEventInit> init(aCx);
|
RootedDictionary<FetchEventInit> init(aCx);
|
||||||
|
@ -724,83 +724,54 @@ CompareNetwork::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(request);
|
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(request);
|
||||||
if (httpChannel) {
|
MOZ_ASSERT(httpChannel, "How come we don't have an HTTP channel?");
|
||||||
bool requestSucceeded;
|
|
||||||
rv = httpChannel->GetRequestSucceeded(&requestSucceeded);
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
mManager->NetworkFinished(rv);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_WARN_IF(!requestSucceeded)) {
|
bool requestSucceeded;
|
||||||
mManager->NetworkFinished(NS_ERROR_FAILURE);
|
rv = httpChannel->GetRequestSucceeded(&requestSucceeded);
|
||||||
return NS_OK;
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
}
|
mManager->NetworkFinished(rv);
|
||||||
|
return NS_OK;
|
||||||
nsAutoCString maxScope;
|
|
||||||
// Note: we explicitly don't check for the return value here, because the
|
|
||||||
// absence of the header is not an error condition.
|
|
||||||
Unused << httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Service-Worker-Allowed"),
|
|
||||||
maxScope);
|
|
||||||
|
|
||||||
mManager->SetMaxScope(maxScope);
|
|
||||||
|
|
||||||
bool isFromCache = false;
|
|
||||||
nsCOMPtr<nsICacheInfoChannel> cacheChannel(do_QueryInterface(httpChannel));
|
|
||||||
if (cacheChannel) {
|
|
||||||
cacheChannel->IsFromCache(&isFromCache);
|
|
||||||
}
|
|
||||||
|
|
||||||
// [9.2 Update]4.13, If response's cache state is not "local",
|
|
||||||
// set registration's last update check time to the current time
|
|
||||||
if (!isFromCache) {
|
|
||||||
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
|
||||||
mManager->GetRegistration();
|
|
||||||
registration->RefreshLastUpdateCheckTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoCString mimeType;
|
|
||||||
rv = httpChannel->GetContentType(mimeType);
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
mManager->NetworkFinished(NS_ERROR_DOM_SECURITY_ERR);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mimeType.LowerCaseEqualsLiteral("text/javascript") &&
|
|
||||||
!mimeType.LowerCaseEqualsLiteral("application/x-javascript") &&
|
|
||||||
!mimeType.LowerCaseEqualsLiteral("application/javascript")) {
|
|
||||||
mManager->NetworkFinished(NS_ERROR_DOM_SECURITY_ERR);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// The only supported request schemes are http, https, and app.
|
|
||||||
// Above, we check to ensure that the request is http or https
|
|
||||||
// based on the channel qi. Here we test the scheme to ensure
|
|
||||||
// that it is app. Otherwise, bail.
|
|
||||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
|
||||||
if (NS_WARN_IF(!channel)) {
|
|
||||||
mManager->NetworkFinished(NS_ERROR_FAILURE);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
nsCOMPtr<nsIURI> uri;
|
|
||||||
rv = channel->GetURI(getter_AddRefs(uri));
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
mManager->NetworkFinished(rv);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoCString scheme;
|
if (NS_WARN_IF(!requestSucceeded)) {
|
||||||
rv = uri->GetScheme(scheme);
|
mManager->NetworkFinished(NS_ERROR_FAILURE);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
return NS_OK;
|
||||||
mManager->NetworkFinished(rv);
|
}
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_WARN_IF(!scheme.LowerCaseEqualsLiteral("app"))) {
|
nsAutoCString maxScope;
|
||||||
mManager->NetworkFinished(NS_ERROR_FAILURE);
|
// Note: we explicitly don't check for the return value here, because the
|
||||||
return NS_OK;
|
// absence of the header is not an error condition.
|
||||||
}
|
Unused << httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Service-Worker-Allowed"),
|
||||||
|
maxScope);
|
||||||
|
|
||||||
|
mManager->SetMaxScope(maxScope);
|
||||||
|
|
||||||
|
bool isFromCache = false;
|
||||||
|
nsCOMPtr<nsICacheInfoChannel> cacheChannel(do_QueryInterface(httpChannel));
|
||||||
|
if (cacheChannel) {
|
||||||
|
cacheChannel->IsFromCache(&isFromCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
// [9.2 Update]4.13, If response's cache state is not "local",
|
||||||
|
// set registration's last update check time to the current time
|
||||||
|
if (!isFromCache) {
|
||||||
|
RefPtr<ServiceWorkerRegistrationInfo> registration =
|
||||||
|
mManager->GetRegistration();
|
||||||
|
registration->RefreshLastUpdateCheckTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoCString mimeType;
|
||||||
|
rv = httpChannel->GetContentType(mimeType);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
mManager->NetworkFinished(NS_ERROR_DOM_SECURITY_ERR);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mimeType.LowerCaseEqualsLiteral("text/javascript") &&
|
||||||
|
!mimeType.LowerCaseEqualsLiteral("application/x-javascript") &&
|
||||||
|
!mimeType.LowerCaseEqualsLiteral("application/javascript")) {
|
||||||
|
mManager->NetworkFinished(NS_ERROR_DOM_SECURITY_ERR);
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
char16_t* buffer = nullptr;
|
char16_t* buffer = nullptr;
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
application.list contains a list of files that are in application.zip.
|
|
||||||
|
|
||||||
To update application.zip when changing one of those files, run makezip.sh.
|
|
@ -1,8 +0,0 @@
|
|||||||
controlled.html
|
|
||||||
foo.txt
|
|
||||||
index.html
|
|
||||||
manifest.webapp
|
|
||||||
sw.js
|
|
||||||
test.js
|
|
||||||
test_doc_load_interception.js
|
|
||||||
unregister.html
|
|
Binary file not shown.
@ -1,36 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test app for bug 1161684</title>
|
|
||||||
<script src='test.js'></script>
|
|
||||||
<script src='test_doc_load_interception.js'></script>
|
|
||||||
<script type='application/javascript;version=1.7'>
|
|
||||||
|
|
||||||
function runTests() {
|
|
||||||
return Promise.resolve()
|
|
||||||
.then(navigator.serviceWorker.ready)
|
|
||||||
.then(() => {
|
|
||||||
return testFetchAppResource('foo.txt',
|
|
||||||
'swresponse', 'text/plain');
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
return testFetchAppResource('foo.txt?fetch=1',
|
|
||||||
'networkresponse', 'text/plain');
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
return testFetchAppResource('test_custom_content_type',
|
|
||||||
'customContentType', 'text/html');
|
|
||||||
})
|
|
||||||
// XXX: Cross-origin interceptions without CORS result in opaque responses
|
|
||||||
// which are illegal for navigations like iframes. (bug 1183313)
|
|
||||||
//.then(testRedirectedResponse)
|
|
||||||
//.then(testRedirectedHttpsResponse)
|
|
||||||
//.then(testCachedRedirectedResponse)
|
|
||||||
//.then(testCachedRedirectedHttpsResponse)
|
|
||||||
.then(done);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body onload='runTests()'>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1 +0,0 @@
|
|||||||
networkresponse
|
|
@ -1,31 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test app for bug 1161684</title>
|
|
||||||
<script src='test.js'></script>
|
|
||||||
<script type='application/javascript;version=1.7'>
|
|
||||||
function registerServiceWorker() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
navigator.serviceWorker.ready.then(() => {
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
navigator.serviceWorker.register('sw.js', {scope: '.'})
|
|
||||||
.then(registration => {
|
|
||||||
ok(true, 'service worker registered');
|
|
||||||
})
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function runTests() {
|
|
||||||
return Promise.resolve()
|
|
||||||
.then(() => { return testFetchAppResource('foo.txt',
|
|
||||||
'networkresponse'); })
|
|
||||||
.then(registerServiceWorker)
|
|
||||||
.then(ready);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body onload='runTests()'>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,4 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
rm application.zip
|
|
||||||
zip application.zip `cat application.list`
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "App",
|
|
||||||
"launch_path": "/index.html",
|
|
||||||
"description": "Test app for bug 1161684"
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
real index
|
|
@ -1 +0,0 @@
|
|||||||
Access-Control-Allow-Origin: *
|
|
@ -1,5 +0,0 @@
|
|||||||
function handleRequest(request, response) {
|
|
||||||
response.setStatusLine(null, 308, "Permanent Redirect");
|
|
||||||
response.setHeader("Access-Control-Allow-Origin", "*", false);
|
|
||||||
response.setHeader("Location", "https://example.org/tests/dom/workers/test/serviceworkers/app-protocol/realindex.html", false);
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
function handleRequest(request, response) {
|
|
||||||
response.setStatusLine(null, 308, "Permanent Redirect");
|
|
||||||
response.setHeader("Access-Control-Allow-Origin", "*", false);
|
|
||||||
response.setHeader("Location", "http://example.org/tests/dom/workers/test/serviceworkers/app-protocol/realindex.html", false);
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
const kHTTPRedirect = "http://example.com/tests/dom/workers/test/serviceworkers/app-protocol/redirect.sjs";
|
|
||||||
const kHTTPSRedirect = "https://example.com/tests/dom/workers/test/serviceworkers/app-protocol/redirect-https.sjs";
|
|
||||||
|
|
||||||
self.addEventListener('install', (event) => {
|
|
||||||
event.waitUntil(
|
|
||||||
self.caches.open("origin-app-cache")
|
|
||||||
.then(c => {
|
|
||||||
return Promise.all(
|
|
||||||
[
|
|
||||||
c.add(kHTTPRedirect),
|
|
||||||
c.add(kHTTPSRedirect),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
self.addEventListener('fetch', (event) => {
|
|
||||||
if (event.request.url.indexOf('foo.txt') >= 0) {
|
|
||||||
var url = new URL(event.request.url);
|
|
||||||
var shouldFetch = url.searchParams.get('fetch');
|
|
||||||
if (shouldFetch) {
|
|
||||||
event.respondWith(fetch(event.request));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
event.respondWith(new Response('swresponse', {
|
|
||||||
headers: {'Content-Type': 'text/plain'}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.request.url.indexOf('test_doc_load_interception.js') >= 0 ) {
|
|
||||||
var scriptContent = 'alert("OK: Script modified by service worker")';
|
|
||||||
event.respondWith(new Response(scriptContent, {
|
|
||||||
headers: {'Content-Type': 'application/javascript'}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.request.url.indexOf('test_custom_content_type') >= 0) {
|
|
||||||
event.respondWith(new Response('customContentType', {
|
|
||||||
headers: {'Content-Type': 'text/html'}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.request.url.indexOf('redirected.html') >= 0) {
|
|
||||||
event.respondWith(fetch(kHTTPRedirect));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.request.url.indexOf('redirected-https.html') >= 0) {
|
|
||||||
event.respondWith(fetch(kHTTPSRedirect));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.request.url.indexOf('redirected-cached.html') >= 0) {
|
|
||||||
event.respondWith(
|
|
||||||
self.caches.open("origin-app-cache")
|
|
||||||
.then(c => {
|
|
||||||
return c.match(kHTTPRedirect);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.request.url.indexOf('redirected-https-cached.html') >= 0) {
|
|
||||||
event.respondWith(
|
|
||||||
self.caches.open("origin-app-cache")
|
|
||||||
.then(c => {
|
|
||||||
return c.match(kHTTPSRedirect);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,72 +0,0 @@
|
|||||||
function ok(aCondition, aMessage) {
|
|
||||||
if (aCondition) {
|
|
||||||
alert('OK: ' + aMessage);
|
|
||||||
} else {
|
|
||||||
alert('KO: ' + aMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function ready() {
|
|
||||||
alert('READY');
|
|
||||||
}
|
|
||||||
|
|
||||||
function done() {
|
|
||||||
alert('DONE');
|
|
||||||
}
|
|
||||||
|
|
||||||
function testFetchAppResource(aUrl,
|
|
||||||
aExpectedResponse,
|
|
||||||
aExpectedContentType) {
|
|
||||||
return fetch(aUrl).then(res => {
|
|
||||||
ok(true, 'fetch should resolve for ' + aUrl);
|
|
||||||
if (res.type == 'error') {
|
|
||||||
ok(false, 'fetch failed');
|
|
||||||
}
|
|
||||||
ok(res.status == 200, 'status should be 200');
|
|
||||||
ok(res.statusText == 'OK', 'statusText should be OK');
|
|
||||||
if (aExpectedContentType) {
|
|
||||||
var headers = res.headers.getAll('Content-Type');
|
|
||||||
ok(headers.length, "Headers length");
|
|
||||||
var contentType = res.headers.get('Content-Type');
|
|
||||||
ok(contentType == aExpectedContentType, ('content type ' +
|
|
||||||
contentType + ' should match with ' + aExpectedContentType));
|
|
||||||
}
|
|
||||||
return res.text().then(body => {
|
|
||||||
ok(body == aExpectedResponse, 'body ' + body +
|
|
||||||
' should match with ' + aExpectedResponse);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function testRedirectedResponse() {
|
|
||||||
return testRedirectedResponseWorker("redirected", "IFRAMELOADED");
|
|
||||||
}
|
|
||||||
|
|
||||||
function testRedirectedHttpsResponse() {
|
|
||||||
return testRedirectedResponseWorker("redirected-https", "HTTPSIFRAMELOADED");
|
|
||||||
}
|
|
||||||
|
|
||||||
function testCachedRedirectedResponse() {
|
|
||||||
return testRedirectedResponseWorker("redirected-cached", "IFRAMELOADED");
|
|
||||||
}
|
|
||||||
|
|
||||||
function testCachedRedirectedHttpsResponse() {
|
|
||||||
return testRedirectedResponseWorker("redirected-https-cached", "HTTPSIFRAMELOADED");
|
|
||||||
}
|
|
||||||
|
|
||||||
function testRedirectedResponseWorker(aFrameId, aAlert) {
|
|
||||||
// Because of the CSP policies applied to privileged apps, we cannot run
|
|
||||||
// inline script inside realindex.html, and loading a script from the app://
|
|
||||||
// URI is also not an option, so we let the parent iframe which has access
|
|
||||||
// to the SpecialPowers API use those privileges to access the document.
|
|
||||||
var iframe = document.createElement("iframe");
|
|
||||||
document.body.appendChild(iframe);
|
|
||||||
iframe.src = aFrameId + ".html";
|
|
||||||
iframe.id = aFrameId;
|
|
||||||
return new Promise(resolve => {
|
|
||||||
iframe.addEventListener("load", event => {
|
|
||||||
alert(aAlert);
|
|
||||||
resolve();
|
|
||||||
}, false);
|
|
||||||
});
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
alert('KO: Should not load this file, but the sw modified version instead');
|
|
@ -1,24 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<script src='test.js'></script>
|
|
||||||
<script type='application/javascript;version=1.7'>
|
|
||||||
function unregisterServiceWorker() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
navigator.serviceWorker.getRegistration(".").then((reg) => {
|
|
||||||
reg.unregister().then(resolve);
|
|
||||||
})
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function onLoad() {
|
|
||||||
return Promise.resolve()
|
|
||||||
.then(unregisterServiceWorker)
|
|
||||||
.then(done);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body onload='onLoad()'>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "App",
|
|
||||||
"launch_path": "/index.html",
|
|
||||||
"description": "Test app for bug 1161684",
|
|
||||||
"package_path": "application.zip"
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
Content-Type: application/manifest+json
|
|
@ -1,41 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test app for bug 1169249</title>
|
|
||||||
<script type='application/javascript;version=1.7'>
|
|
||||||
function ok(aCondition, aMessage) {
|
|
||||||
if (aCondition) {
|
|
||||||
alert('OK: ' + aMessage);
|
|
||||||
} else {
|
|
||||||
alert('KO: ' + aMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function ready() {
|
|
||||||
alert('READY');
|
|
||||||
}
|
|
||||||
|
|
||||||
function registerServiceWorker() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
navigator.serviceWorker.ready.then(() => {
|
|
||||||
ready();
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
navigator.serviceWorker.register('sw.js', {scope: '.'})
|
|
||||||
.then(registration => {
|
|
||||||
ok(true, 'service worker registered');
|
|
||||||
})
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function runTests() {
|
|
||||||
return Promise.resolve()
|
|
||||||
.then(registerServiceWorker)
|
|
||||||
.then(ready)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body onload='runTests()'>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "App",
|
|
||||||
"launch_path": "/index.html",
|
|
||||||
"description": "Test app for bug 1169249"
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
Content-Type: application/manifest+json
|
|
@ -1 +0,0 @@
|
|||||||
// Useless service worker.
|
|
@ -1,17 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test app for bug 1178233</title>
|
|
||||||
<script type='application/javascript;version=1.7'>
|
|
||||||
|
|
||||||
function onLoad() {
|
|
||||||
navigator.serviceWorker.ready.then(function(swr) {
|
|
||||||
parent.postMessage({status: "callback", data: "done"}, '*');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body onload='onLoad()'>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,81 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test app for bug 1178233</title>
|
|
||||||
<script type='application/javascript;version=1.7'>
|
|
||||||
|
|
||||||
function ok(aCondition, aMessage) {
|
|
||||||
if (aCondition) {
|
|
||||||
alert('OK: ' + aMessage);
|
|
||||||
} else {
|
|
||||||
alert('KO: ' + aMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function done() {
|
|
||||||
alert('DONE');
|
|
||||||
}
|
|
||||||
|
|
||||||
function testFrame(src) {
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
var iframe = document.createElement("iframe");
|
|
||||||
iframe.src = src;
|
|
||||||
window.onmessage = function(e) {
|
|
||||||
if (e.data.status == "callback") {
|
|
||||||
window.onmessage = null;
|
|
||||||
var result = e.data.data;
|
|
||||||
iframe.src = "about:blank";
|
|
||||||
document.body.removeChild(iframe);
|
|
||||||
iframe = null;
|
|
||||||
resolve(result);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
document.body.appendChild(iframe);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function registerServiceWorker() {
|
|
||||||
return navigator.serviceWorker.register('sw.sjs', {scope: '.'});
|
|
||||||
}
|
|
||||||
|
|
||||||
function runTests() {
|
|
||||||
var lastSeenVersion;
|
|
||||||
return Promise.resolve()
|
|
||||||
.then(function() {
|
|
||||||
// Check whether the service worker is already registered and save its
|
|
||||||
// version.
|
|
||||||
return navigator.serviceWorker.getRegistration(".").then(function(swr) {
|
|
||||||
if (!swr) {
|
|
||||||
lastSeenVersion = 0;
|
|
||||||
return registerServiceWorker();
|
|
||||||
}
|
|
||||||
return testFrame('version.html').then(function(body) {
|
|
||||||
lastSeenVersion = parseInt(body);
|
|
||||||
return Promise.resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(function() {
|
|
||||||
// Wait until the service worker start controlling the client.
|
|
||||||
return testFrame('client.html');
|
|
||||||
})
|
|
||||||
.then(function() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
testFrame('wait_for_update.html').then(function() {
|
|
||||||
// Fetch current version. It should be greater than the last seen version.
|
|
||||||
testFrame('version.html').then(function(body) {
|
|
||||||
var currentVersion = parseInt(body);
|
|
||||||
ok(lastSeenVersion < currentVersion, "New service worker version seen");
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(done);
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body onload='runTests()'>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "App",
|
|
||||||
"launch_path": "/index.html",
|
|
||||||
"description": "Test app for bug 1178233"
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
Content-Type: application/manifest+json
|
|
@ -1,22 +0,0 @@
|
|||||||
function handleRequest(request, response) {
|
|
||||||
var stateName = request.scheme + 'counter';
|
|
||||||
if (!getState(stateName)) {
|
|
||||||
setState(stateName, '1');
|
|
||||||
} else {
|
|
||||||
// Make sure that we pass a string value to setState!
|
|
||||||
setState(stateName, "" + (parseInt(getState(stateName)) + 1));
|
|
||||||
}
|
|
||||||
response.setHeader("Content-Type", "application/javascript", false);
|
|
||||||
response.write(getScript(stateName));
|
|
||||||
}
|
|
||||||
|
|
||||||
function getScript(stateName) {
|
|
||||||
return "oninstall = function(evt) {" +
|
|
||||||
"evt.waitUntil(self.skipWaiting());" +
|
|
||||||
"}; " +
|
|
||||||
"onfetch = function(evt) {" +
|
|
||||||
"if (evt.request.url.indexOf('get-sw-version') > -1) {" +
|
|
||||||
"evt.respondWith(new Response('" + getState(stateName) + "'));" +
|
|
||||||
"}" +
|
|
||||||
"};";
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test app for bug 1178233</title>
|
|
||||||
<script type='application/javascript;version=1.7'>
|
|
||||||
|
|
||||||
function onLoad() {
|
|
||||||
fetch("get-sw-version").then(function(r) {
|
|
||||||
return r.text();
|
|
||||||
}).then(function(body) {
|
|
||||||
parent.postMessage({status: "callback", data: body}, "*");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body onload='onLoad()'>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,25 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test app for bug 1178233</title>
|
|
||||||
<script type='application/javascript;version=1.7'>
|
|
||||||
|
|
||||||
function update() {
|
|
||||||
alert('UPDATE');
|
|
||||||
}
|
|
||||||
|
|
||||||
function onLoad() {
|
|
||||||
navigator.serviceWorker.getRegistration(".").then(function(swr) {
|
|
||||||
swr.onupdatefound = function() {
|
|
||||||
swr.onupdatefound = null;
|
|
||||||
parent.postMessage({status: "callback", data: "done"}, "*");
|
|
||||||
};
|
|
||||||
update();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body onload='onLoad()'>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,51 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test app for bug 1169249</title>
|
|
||||||
<script type='application/javascript;version=1.7'>
|
|
||||||
function ok(aCondition, aMessage) {
|
|
||||||
if (aCondition) {
|
|
||||||
alert('OK: ' + aMessage);
|
|
||||||
} else {
|
|
||||||
alert('KO: ' + aMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function ready() {
|
|
||||||
alert('READY');
|
|
||||||
}
|
|
||||||
|
|
||||||
function registerServiceWorker() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
navigator.serviceWorker.ready.then(() => {
|
|
||||||
ready();
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
navigator.serviceWorker.register('../empty.js', {scope: '.'})
|
|
||||||
.then(registration => {
|
|
||||||
ok(true, 'service worker registered');
|
|
||||||
})
|
|
||||||
.catch(reject);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function AddIframe() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let iframe = document.createElement('iframe');
|
|
||||||
iframe.setAttribute('mozbrowser', 'true');
|
|
||||||
iframe.setAttribute('src', "http://test/chrome/dom/workers/test/serviceworkers/serviceworker.html");
|
|
||||||
document.body.appendChild(iframe);
|
|
||||||
iframe.addEventListener("mozbrowserloadend", resolve);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function runTests() {
|
|
||||||
return Promise.resolve()
|
|
||||||
.then(AddIframe)
|
|
||||||
.then(registerServiceWorker)
|
|
||||||
.then(ready)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body onload='runTests()'>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "App",
|
|
||||||
"launch_path": "/index.html",
|
|
||||||
"description": "Test app for bug 1169249"
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
Content-Type: application/manifest+json
|
|
@ -1,9 +1,6 @@
|
|||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
skip-if = buildapp == 'b2g' || os == 'android'
|
skip-if = buildapp == 'b2g' || os == 'android'
|
||||||
support-files =
|
support-files =
|
||||||
app/*
|
|
||||||
app2/*
|
|
||||||
app3/*
|
|
||||||
chrome_helpers.js
|
chrome_helpers.js
|
||||||
empty.js
|
empty.js
|
||||||
serviceworker.html
|
serviceworker.html
|
||||||
@ -13,10 +10,6 @@ support-files =
|
|||||||
worker.js
|
worker.js
|
||||||
worker2.js
|
worker2.js
|
||||||
|
|
||||||
[test_aboutserviceworkers.html]
|
|
||||||
skip-if = true #bug 1193319
|
|
||||||
[test_clear_origin_data.html]
|
|
||||||
[test_app_installation.html]
|
|
||||||
[test_privateBrowsing.html]
|
[test_privateBrowsing.html]
|
||||||
[test_serviceworkerinfo.xul]
|
[test_serviceworkerinfo.xul]
|
||||||
[test_serviceworkermanager.xul]
|
[test_serviceworkermanager.xul]
|
||||||
|
@ -161,7 +161,6 @@ support-files =
|
|||||||
claim_worker_2.js
|
claim_worker_2.js
|
||||||
claim_clients/client.html
|
claim_clients/client.html
|
||||||
claim_fetch_worker.js
|
claim_fetch_worker.js
|
||||||
app-protocol/*
|
|
||||||
force_refresh_worker.js
|
force_refresh_worker.js
|
||||||
sw_clients/refresher.html
|
sw_clients/refresher.html
|
||||||
sw_clients/refresher_compressed.html
|
sw_clients/refresher_compressed.html
|
||||||
@ -199,8 +198,6 @@ support-files =
|
|||||||
redirect.sjs
|
redirect.sjs
|
||||||
open_window/client.html
|
open_window/client.html
|
||||||
|
|
||||||
[test_app_protocol.html]
|
|
||||||
skip-if = release_build || (e10s && debug && os == 'win')
|
|
||||||
[test_bug1151916.html]
|
[test_bug1151916.html]
|
||||||
skip-if = e10s && debug && os == 'win'
|
skip-if = e10s && debug && os == 'win'
|
||||||
[test_claim.html]
|
[test_claim.html]
|
||||||
|
@ -1,164 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<!--
|
|
||||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1178233
|
|
||||||
-->
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Test for Bug 1178233</title>
|
|
||||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
|
||||||
<script type="application/javascript;version=1.7">
|
|
||||||
|
|
||||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "gServiceWorkerManager",
|
|
||||||
"@mozilla.org/serviceworkers/manager;1",
|
|
||||||
"nsIServiceWorkerManager");
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "gAppsService",
|
|
||||||
"@mozilla.org/AppsService;1",
|
|
||||||
"nsIAppsService");
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
const gOrigin = 'http://test/chrome/dom/workers/test/serviceworkers/app2';
|
|
||||||
const appManifestURL = gOrigin + '/manifest.webapp';
|
|
||||||
let gApp;
|
|
||||||
|
|
||||||
function uninstallApp() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (!gApp) {
|
|
||||||
return reject();
|
|
||||||
}
|
|
||||||
let req = navigator.mozApps.mgmt.uninstall(gApp);
|
|
||||||
req.onsuccess = resolve;
|
|
||||||
req.onerror = reject;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function update() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let registrations = [];
|
|
||||||
registrations = gServiceWorkerManager.getAllRegistrations();
|
|
||||||
|
|
||||||
ok(registrations.length === 1, "The registration shows up in about:serviceworker page");
|
|
||||||
|
|
||||||
for (let i = 0; i < registrations.length; i++) {
|
|
||||||
let registration = registrations.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
|
|
||||||
if (!registration) {
|
|
||||||
reject();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
info('Update service worker registration');
|
|
||||||
gServiceWorkerManager.propagateSoftUpdate(
|
|
||||||
registration.principal.originAttributes,
|
|
||||||
registration.scope
|
|
||||||
);
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function testApp() {
|
|
||||||
if (!gApp) {
|
|
||||||
ok(false, 'No test application to launch');
|
|
||||||
return Promise.reject();
|
|
||||||
}
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let iframe = document.createElement('iframe');
|
|
||||||
let domParent = document.getElementById('container');
|
|
||||||
iframe.setAttribute('mozbrowser', 'true');
|
|
||||||
iframe.setAttribute('mozapp', gApp.manifestURL);
|
|
||||||
iframe.addEventListener('mozbrowsershowmodalprompt', function listener(e) {
|
|
||||||
let message = e.detail.message;
|
|
||||||
if (/OK/.exec(message)) {
|
|
||||||
ok(true, "Message from app: " + message);
|
|
||||||
} else if (/UPDATE/.exec(message)) {
|
|
||||||
ok(true, "Message from app: " + message);
|
|
||||||
update();
|
|
||||||
} else if (/KO/.exec(message)) {
|
|
||||||
ok(false, "Message from app: " + message);
|
|
||||||
} else if (/DONE/.exec(message)) {
|
|
||||||
ok(true, "Message from app: " + message);
|
|
||||||
iframe.src = "about:blank";
|
|
||||||
domParent.removeChild(iframe);
|
|
||||||
iframe = null;
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
}, false);
|
|
||||||
domParent.appendChild(iframe);
|
|
||||||
ok(true, "origin " + gOrigin + gApp.manifest.launch_path);
|
|
||||||
SpecialPowers.wrap(iframe.contentWindow).location =
|
|
||||||
gOrigin + gApp.manifest.launch_path;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function installApp() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let req = navigator.mozApps.install(appManifestURL);
|
|
||||||
req.onsuccess = function() {
|
|
||||||
gApp = req.result;
|
|
||||||
is(req.result.manifestURL, appManifestURL, 'app installed');
|
|
||||||
if (req.result.installState == 'installed') {
|
|
||||||
is(req.result.installState, 'installed', 'app downloaded');
|
|
||||||
resolve()
|
|
||||||
} else {
|
|
||||||
req.result.ondownloadapplied = function() {
|
|
||||||
is(req.result.installState, 'installed', 'app downloaded');
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
req.onerror = reject;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function setup() {
|
|
||||||
info('Setting up');
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
SpecialPowers.setAllAppsLaunchable(true);
|
|
||||||
SpecialPowers.pushPrefEnv({'set': [
|
|
||||||
['dom.mozBrowserFramesEnabled', true],
|
|
||||||
['dom.serviceWorkers.exemptFromPerDomainMax', true],
|
|
||||||
['dom.serviceWorkers.enabled', true],
|
|
||||||
['dom.serviceWorkers.testing.enabled', true],
|
|
||||||
['dom.serviceWorkers.interception.enabled', true]
|
|
||||||
]}, () => {
|
|
||||||
SpecialPowers.pushPermissions([
|
|
||||||
{ 'type': 'webapps-manage', 'allow': 1, 'context': document },
|
|
||||||
{ 'type': 'browser', 'allow': 1, 'context': document },
|
|
||||||
{ 'type': 'embed-apps', 'allow': 1, 'context': document }
|
|
||||||
], () => {
|
|
||||||
SpecialPowers.autoConfirmAppInstall(() => {
|
|
||||||
SpecialPowers.autoConfirmAppUninstall(resolve);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function go() {
|
|
||||||
setup()
|
|
||||||
.then(installApp)
|
|
||||||
.then(testApp)
|
|
||||||
.then(uninstallApp)
|
|
||||||
.then(SimpleTest.finish)
|
|
||||||
.catch(function(e) {
|
|
||||||
ok(false, 'Unexpected error ' + e);
|
|
||||||
SimpleTest.finish();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body onload="go()">
|
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1171917">Mozilla Bug 1178233</a>
|
|
||||||
<p id="display"></p>
|
|
||||||
<div id="content" style="display: none">
|
|
||||||
</div>
|
|
||||||
<pre id="test">
|
|
||||||
</pre>
|
|
||||||
<div id="container"></div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,168 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<!--
|
|
||||||
https://bugzilla.mozilla.org/show_bug.cgi?id={1169249}
|
|
||||||
-->
|
|
||||||
<head>
|
|
||||||
<title>Test for Bug {1169249}</title>
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="chrome://mochikit/content/chrome-harness.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={1169249}">Mozilla Bug {1169249}</a>
|
|
||||||
<p id="display"></p>
|
|
||||||
<div id="content" style="display: none">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<pre id="test">
|
|
||||||
<script class="testbody" type="application/javascript;version=1.7">
|
|
||||||
|
|
||||||
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "gServiceWorkerManager",
|
|
||||||
"@mozilla.org/serviceworkers/manager;1",
|
|
||||||
"nsIServiceWorkerManager");
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "gAppsService",
|
|
||||||
"@mozilla.org/AppsService;1",
|
|
||||||
"nsIAppsService");
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
const gOrigin = 'http://test/chrome/dom/workers/test/serviceworkers/app';
|
|
||||||
const appManifestURL = gOrigin + '/manifest.webapp';
|
|
||||||
let gApp;
|
|
||||||
|
|
||||||
addLoadEvent(go);
|
|
||||||
|
|
||||||
function setup() {
|
|
||||||
info('Setting up');
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
SpecialPowers.setAllAppsLaunchable(true);
|
|
||||||
SpecialPowers.pushPrefEnv({'set': [
|
|
||||||
['dom.mozBrowserFramesEnabled', true],
|
|
||||||
['dom.serviceWorkers.exemptFromPerDomainMax', true],
|
|
||||||
['dom.serviceWorkers.enabled', true],
|
|
||||||
['dom.serviceWorkers.testing.enabled', true],
|
|
||||||
['dom.serviceWorkers.interception.enabled', true],
|
|
||||||
]}, () => {
|
|
||||||
SpecialPowers.pushPermissions([
|
|
||||||
{ 'type': 'webapps-manage', 'allow': 1, 'context': document },
|
|
||||||
{ 'type': 'browser', 'allow': 1, 'context': document },
|
|
||||||
{ 'type': 'embed-apps', 'allow': 1, 'context': document }
|
|
||||||
], () => {
|
|
||||||
SpecialPowers.autoConfirmAppInstall(() => {
|
|
||||||
SpecialPowers.autoConfirmAppUninstall(resolve);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function installApp() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let req = navigator.mozApps.install(appManifestURL);
|
|
||||||
req.onsuccess = function() {
|
|
||||||
gApp = req.result;
|
|
||||||
is(req.result.manifestURL, appManifestURL, 'app installed');
|
|
||||||
if (req.result.installState == 'installed') {
|
|
||||||
is(req.result.installState, 'installed', 'app downloaded');
|
|
||||||
resolve()
|
|
||||||
} else {
|
|
||||||
req.result.ondownloadapplied = function() {
|
|
||||||
is(req.result.installState, 'installed', 'app downloaded');
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
req.onerror = reject;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkSwRegistration(aExpectedRegistrations) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let registrations = [];
|
|
||||||
registrations = gServiceWorkerManager.getAllRegistrations();
|
|
||||||
is(registrations.length, aExpectedRegistrations.length,
|
|
||||||
"There should be " + aExpectedRegistrations.length + " registrations");
|
|
||||||
|
|
||||||
for (let i = 0; i < registrations.length; i++) {
|
|
||||||
let registration = registrations.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
|
|
||||||
if (!registration) {
|
|
||||||
reject();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
is(registration.principal.origin, aExpectedRegistrations[i].origin,
|
|
||||||
"Registration principal should be as expected");
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function launchApp() {
|
|
||||||
if (!gApp) {
|
|
||||||
ok(false, 'No test application to launch');
|
|
||||||
return Promise.reject();
|
|
||||||
}
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let iframe = document.createElement('iframe');
|
|
||||||
iframe.setAttribute('mozbrowser', 'true');
|
|
||||||
iframe.setAttribute('mozapp', gApp.manifestURL);
|
|
||||||
iframe.addEventListener('mozbrowsershowmodalprompt', function listener(e) {
|
|
||||||
let message = e.detail.message;
|
|
||||||
if (/OK/.exec(message)) {
|
|
||||||
ok(true, "Message from app: " + message);
|
|
||||||
} else if (/READY/.exec(message)) {
|
|
||||||
ok(true, 'Message from app: ' + message);
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
}, false);
|
|
||||||
let domParent = document.getElementById('container');
|
|
||||||
domParent.appendChild(iframe);
|
|
||||||
ok(true, "origin " + gOrigin + gApp.manifest.launch_path);
|
|
||||||
SpecialPowers.wrap(iframe.contentWindow).location =
|
|
||||||
gOrigin + gApp.manifest.launch_path;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function uninstallApp() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (!gApp) {
|
|
||||||
return reject();
|
|
||||||
}
|
|
||||||
let req = navigator.mozApps.mgmt.uninstall(gApp);
|
|
||||||
req.onsuccess = resolve;
|
|
||||||
req.onerror = reject;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function go() {
|
|
||||||
setup()
|
|
||||||
.then(installApp)
|
|
||||||
.then(launchApp)
|
|
||||||
.then(() => {
|
|
||||||
app = gAppsService.getAppByManifestURL(gApp.manifestURL);
|
|
||||||
return checkSwRegistration([{
|
|
||||||
origin: app.principal.origin
|
|
||||||
}]);
|
|
||||||
})
|
|
||||||
.then(uninstallApp)
|
|
||||||
.then(() => {
|
|
||||||
return checkSwRegistration([]);
|
|
||||||
})
|
|
||||||
.then(SimpleTest.finish)
|
|
||||||
.catch((e) => {
|
|
||||||
ok(false, 'Unexpected error ' + e);
|
|
||||||
SimpleTest.finish();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</pre>
|
|
||||||
<div id="container"></div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,193 +0,0 @@
|
|||||||
<!--
|
|
||||||
Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
-->
|
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Bug 1161684 - Allow JAR channels to be intercepted by service workers</title>
|
|
||||||
<script type='text/javascript' src='/tests/SimpleTest/SimpleTest.js'></script>
|
|
||||||
<link rel='stylesheet' type='text/css' href='/tests/SimpleTest/test.css' />
|
|
||||||
</head>
|
|
||||||
<body onload='runTests()'>
|
|
||||||
<p id='display'></p>
|
|
||||||
<div id='content' style='display: none'></div>
|
|
||||||
<pre id='test'></pre>
|
|
||||||
<script class='testbody' type='application/javascript;version=1.7'>
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
const appManifestURL =
|
|
||||||
'http://mochi.test:8888/tests/dom/workers/test/serviceworkers/app-protocol/update.webapp';
|
|
||||||
let gApp;
|
|
||||||
|
|
||||||
function setup() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
SpecialPowers.setAllAppsLaunchable(true);
|
|
||||||
SpecialPowers.pushPrefEnv({'set': [
|
|
||||||
['dom.mozBrowserFramesEnabled', true],
|
|
||||||
['dom.serviceWorkers.exemptFromPerDomainMax', true],
|
|
||||||
["dom.serviceWorkers.interception.enabled", true],
|
|
||||||
['dom.serviceWorkers.enabled', true],
|
|
||||||
['dom.serviceWorkers.testing.enabled', true],
|
|
||||||
['dom.caches.enabled', true],
|
|
||||||
]}, () => {
|
|
||||||
SpecialPowers.pushPermissions([
|
|
||||||
{ 'type': 'webapps-manage', 'allow': 1, 'context': document },
|
|
||||||
{ 'type': 'browser', 'allow': 1, 'context': document },
|
|
||||||
{ 'type': 'embed-apps', 'allow': 1, 'context': document }
|
|
||||||
], () => {
|
|
||||||
SpecialPowers.autoConfirmAppInstall(() => {
|
|
||||||
SpecialPowers.autoConfirmAppUninstall(resolve);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function installApp() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let req = navigator.mozApps.installPackage(appManifestURL);
|
|
||||||
req.onsuccess = function() {
|
|
||||||
gApp = req.result;
|
|
||||||
is(req.result.manifestURL, appManifestURL, 'app installed');
|
|
||||||
if (req.result.installState == 'installed') {
|
|
||||||
is(req.result.installState, 'installed', 'app downloaded');
|
|
||||||
resolve()
|
|
||||||
} else {
|
|
||||||
req.result.ondownloadapplied = function() {
|
|
||||||
is(req.result.installState, 'installed', 'app downloaded');
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
req.onerror = reject;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function launchApp() {
|
|
||||||
if (!gApp) {
|
|
||||||
ok(false, 'No test application to launch');
|
|
||||||
return Promise.reject();
|
|
||||||
}
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let iframe = document.createElement('iframe');
|
|
||||||
iframe.setAttribute('mozbrowser', 'true');
|
|
||||||
iframe.setAttribute('mozapp', gApp.manifestURL);
|
|
||||||
iframe.addEventListener('mozbrowsershowmodalprompt', function listener(e) {
|
|
||||||
let message = e.detail.message;
|
|
||||||
if (/OK/.exec(message)) {
|
|
||||||
ok(true, "Message from app: " + message);
|
|
||||||
} else if (/KO/.exec(message)) {
|
|
||||||
ok(false, "Message from app: " + message);
|
|
||||||
} else if (/READY/.exec(message)) {
|
|
||||||
ok(true, "Message from app: " + message);
|
|
||||||
resolve();
|
|
||||||
} else {
|
|
||||||
ok(false, "Unexpected message received: " + message);
|
|
||||||
}
|
|
||||||
}, false);
|
|
||||||
let domParent = document.getElementById('container');
|
|
||||||
domParent.appendChild(iframe);
|
|
||||||
SpecialPowers.wrap(iframe.contentWindow).location =
|
|
||||||
gApp.origin + gApp.manifest.launch_path;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadControlled() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let iframe = document.createElement('iframe');
|
|
||||||
iframe.setAttribute('mozbrowser', 'true');
|
|
||||||
iframe.setAttribute('mozapp', gApp.manifestURL);
|
|
||||||
iframe.addEventListener('mozbrowsershowmodalprompt', function listener(e) {
|
|
||||||
let message = e.detail.message;
|
|
||||||
if (/OK/.exec(message)) {
|
|
||||||
ok(true, "Message from app: " + message);
|
|
||||||
} else if (/KO/.exec(message)) {
|
|
||||||
ok(false, "Message from app: " + message);
|
|
||||||
} else if (/HTTPSIFRAMELOADED/.exec(message)) {
|
|
||||||
let doc = SpecialPowers.wrap(iframe).contentDocument;
|
|
||||||
let innerDoc = SpecialPowers.wrap(doc.getElementById("redirected-https").contentDocument);
|
|
||||||
let innerLocation = innerDoc.defaultView.location;
|
|
||||||
is(innerDoc.domain, "example.org", "Correct domain expected (https)");
|
|
||||||
is(innerLocation.origin, "https://example.org", "Correct origin expected (https)");
|
|
||||||
} else if (/IFRAMELOADED/.exec(message)) {
|
|
||||||
let doc = SpecialPowers.wrap(iframe).contentDocument;
|
|
||||||
let innerDoc = SpecialPowers.wrap(doc.getElementById("redirected").contentDocument);
|
|
||||||
let innerLocation = innerDoc.defaultView.location;
|
|
||||||
is(innerDoc.domain, "example.org", "Correct domain expected");
|
|
||||||
is(innerLocation.origin, "http://example.org", "Correct origin expected");
|
|
||||||
} else if (/DONE/.exec(message)) {
|
|
||||||
ok(true, "Messaging from app complete");
|
|
||||||
iframe.removeEventListener('mozbrowsershowmodalprompt', listener);
|
|
||||||
let domParent = document.getElementById('container');
|
|
||||||
domParent.removeChild(iframe);
|
|
||||||
resolve();
|
|
||||||
} else {
|
|
||||||
ok(false, "Unexpected message received: " + message);
|
|
||||||
}
|
|
||||||
}, false);
|
|
||||||
let domParent = document.getElementById('container');
|
|
||||||
domParent.appendChild(iframe);
|
|
||||||
SpecialPowers.wrap(iframe.contentWindow).location =
|
|
||||||
gApp.origin + '/controlled.html';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadUnregister() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let iframe = document.createElement('iframe');
|
|
||||||
iframe.setAttribute('mozbrowser', 'true');
|
|
||||||
iframe.setAttribute('mozapp', gApp.manifestURL);
|
|
||||||
iframe.addEventListener('mozbrowsershowmodalprompt', function listener(e) {
|
|
||||||
let message = e.detail.message;
|
|
||||||
if (/OK/.exec(message)) {
|
|
||||||
ok(true, "Message from app: " + message);
|
|
||||||
} else if (/KO/.exec(message)) {
|
|
||||||
ok(false, "Message from app: " + message);
|
|
||||||
} else if (/DONE/.exec(message)) {
|
|
||||||
ok(true, "Messaging from app complete");
|
|
||||||
iframe.removeEventListener('mozbrowsershowmodalprompt', listener);
|
|
||||||
let domParent = document.getElementById('container');
|
|
||||||
domParent.removeChild(iframe);
|
|
||||||
resolve();
|
|
||||||
} else {
|
|
||||||
ok(false, "Unexpected message received: " + message);
|
|
||||||
}
|
|
||||||
}, false);
|
|
||||||
let domParent = document.getElementById('container');
|
|
||||||
domParent.appendChild(iframe);
|
|
||||||
SpecialPowers.wrap(iframe.contentWindow).location =
|
|
||||||
gApp.origin + '/unregister.html';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function uninstallApp() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (!gApp) {
|
|
||||||
return reject();
|
|
||||||
}
|
|
||||||
let req = navigator.mozApps.mgmt.uninstall(gApp);
|
|
||||||
req.onsuccess = resolve;
|
|
||||||
req.onerror = reject;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function runTests() {
|
|
||||||
setup()
|
|
||||||
.then(installApp)
|
|
||||||
.then(launchApp)
|
|
||||||
.then(loadControlled)
|
|
||||||
.then(loadUnregister)
|
|
||||||
.then(uninstallApp)
|
|
||||||
.then(SimpleTest.finish)
|
|
||||||
.catch((e) => {
|
|
||||||
ok(false, 'Unexpected error ' + e);
|
|
||||||
SimpleTest.finish();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<div id='container'></div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,152 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<!--
|
|
||||||
https://bugzilla.mozilla.org/show_bug.cgi?id={1233644}
|
|
||||||
-->
|
|
||||||
<head>
|
|
||||||
<title>Test for Bug {1233644}</title>
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="chrome://mochikit/content/chrome-harness.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={1233644}">Mozilla Bug {1233644}</a>
|
|
||||||
<p id="display"></p>
|
|
||||||
<div id="content" style="display: none">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<pre id="test">
|
|
||||||
<script class="testbody" type="application/javascript;version=1.7">
|
|
||||||
|
|
||||||
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "gServiceWorkerManager",
|
|
||||||
"@mozilla.org/serviceworkers/manager;1",
|
|
||||||
"nsIServiceWorkerManager");
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
const gOrigin = 'http://test/chrome/dom/workers/test/serviceworkers/app3';
|
|
||||||
const appManifestURL = gOrigin + '/manifest.webapp';
|
|
||||||
let gApp;
|
|
||||||
|
|
||||||
addLoadEvent(go);
|
|
||||||
|
|
||||||
function setup() {
|
|
||||||
info('Setting up');
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
SpecialPowers.setAllAppsLaunchable(true);
|
|
||||||
SpecialPowers.pushPrefEnv({'set': [
|
|
||||||
['dom.mozBrowserFramesEnabled', true],
|
|
||||||
['dom.serviceWorkers.exemptFromPerDomainMax', true],
|
|
||||||
['dom.serviceWorkers.enabled', true],
|
|
||||||
['dom.serviceWorkers.testing.enabled', true],
|
|
||||||
['dom.serviceWorkers.interception.enabled', true],
|
|
||||||
]}, () => {
|
|
||||||
SpecialPowers.pushPermissions([
|
|
||||||
{ 'type': 'webapps-manage', 'allow': 1, 'context': document },
|
|
||||||
{ 'type': 'browser', 'allow': 1, 'context': document },
|
|
||||||
{ 'type': 'embed-apps', 'allow': 1, 'context': document }
|
|
||||||
], () => {
|
|
||||||
SpecialPowers.autoConfirmAppInstall(() => {
|
|
||||||
SpecialPowers.autoConfirmAppUninstall(resolve);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function installApp() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let req = navigator.mozApps.install(appManifestURL);
|
|
||||||
req.onsuccess = function() {
|
|
||||||
gApp = req.result;
|
|
||||||
is(req.result.manifestURL, appManifestURL, 'app installed');
|
|
||||||
if (req.result.installState == 'installed') {
|
|
||||||
is(req.result.installState, 'installed', 'app downloaded');
|
|
||||||
resolve()
|
|
||||||
} else {
|
|
||||||
req.result.ondownloadapplied = function() {
|
|
||||||
is(req.result.installState, 'installed', 'app downloaded');
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
req.onerror = reject;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function pushPermission() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
SpecialPowers.pushPermissions([
|
|
||||||
{'type': 'browser', 'allow': 1, 'context': {manifestURL: appManifestURL}}], resolve);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkSwRegistration() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let registrations = gServiceWorkerManager.getAllRegistrations();
|
|
||||||
is(registrations.length, 0, "All registrations should be removed.");
|
|
||||||
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function launchApp() {
|
|
||||||
if (!gApp) {
|
|
||||||
ok(false, 'No test application to launch');
|
|
||||||
return Promise.reject();
|
|
||||||
}
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
let iframe = document.createElement('iframe');
|
|
||||||
iframe.setAttribute('mozbrowser', 'true');
|
|
||||||
iframe.setAttribute('mozapp', gApp.manifestURL);
|
|
||||||
iframe.addEventListener('mozbrowsershowmodalprompt', function listener(e) {
|
|
||||||
let message = e.detail.message;
|
|
||||||
if (/OK/.exec(message)) {
|
|
||||||
ok(true, "Message from app: " + message);
|
|
||||||
} else if (/READY/.exec(message)) {
|
|
||||||
ok(true, 'Message from app: ' + message);
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
}, false);
|
|
||||||
let domParent = document.getElementById('container');
|
|
||||||
domParent.appendChild(iframe);
|
|
||||||
SpecialPowers.wrap(iframe.contentWindow).location =
|
|
||||||
gOrigin + gApp.manifest.launch_path;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function uninstallApp() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (!gApp) {
|
|
||||||
return reject();
|
|
||||||
}
|
|
||||||
let req = navigator.mozApps.mgmt.uninstall(gApp);
|
|
||||||
req.onsuccess = resolve;
|
|
||||||
req.onerror = reject;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function go() {
|
|
||||||
setup()
|
|
||||||
.then(installApp)
|
|
||||||
.then(pushPermission)
|
|
||||||
.then(launchApp)
|
|
||||||
.then(uninstallApp)
|
|
||||||
.then(checkSwRegistration)
|
|
||||||
.then(SimpleTest.finish)
|
|
||||||
.catch((e) => {
|
|
||||||
ok(false, 'Unexpected error ' + e);
|
|
||||||
SimpleTest.finish();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</pre>
|
|
||||||
<div id="container"></div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,166 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim:set expandtab ts=2 sw=2 sts=2 cin: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "InterceptedJARChannel.h"
|
|
||||||
#include "nsIPipe.h"
|
|
||||||
#include "mozilla/dom/ChannelInfo.h"
|
|
||||||
|
|
||||||
using namespace mozilla::net;
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(InterceptedJARChannel, nsIInterceptedChannel)
|
|
||||||
|
|
||||||
InterceptedJARChannel::InterceptedJARChannel(nsJARChannel* aChannel,
|
|
||||||
nsINetworkInterceptController* aController)
|
|
||||||
: mController(aController)
|
|
||||||
, mChannel(aChannel)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
InterceptedJARChannel::GetResponseBody(nsIOutputStream** aStream)
|
|
||||||
{
|
|
||||||
NS_IF_ADDREF(*aStream = mResponseBody);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
InterceptedJARChannel::GetInternalContentPolicyType(nsContentPolicyType* aPolicyType)
|
|
||||||
{
|
|
||||||
NS_ENSURE_ARG(aPolicyType);
|
|
||||||
nsCOMPtr<nsILoadInfo> loadInfo;
|
|
||||||
nsresult rv = mChannel->GetLoadInfo(getter_AddRefs(loadInfo));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
*aPolicyType = loadInfo->InternalContentPolicyType();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
InterceptedJARChannel::GetChannel(nsIChannel** aChannel)
|
|
||||||
{
|
|
||||||
NS_IF_ADDREF(*aChannel = mChannel);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
InterceptedJARChannel::GetSecureUpgradedChannelURI(nsIURI** aURI)
|
|
||||||
{
|
|
||||||
return mChannel->GetURI(aURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
InterceptedJARChannel::ResetInterception()
|
|
||||||
{
|
|
||||||
if (!mChannel) {
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
mResponseBody = nullptr;
|
|
||||||
mSynthesizedInput = nullptr;
|
|
||||||
|
|
||||||
mChannel->ResetInterception();
|
|
||||||
mReleaseHandle = nullptr;
|
|
||||||
mChannel = nullptr;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
InterceptedJARChannel::SynthesizeStatus(uint16_t aStatus,
|
|
||||||
const nsACString& aReason)
|
|
||||||
{
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
InterceptedJARChannel::SynthesizeHeader(const nsACString& aName,
|
|
||||||
const nsACString& aValue)
|
|
||||||
{
|
|
||||||
if (aName.LowerCaseEqualsLiteral("content-type")) {
|
|
||||||
mContentType = aValue;
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
InterceptedJARChannel::FinishSynthesizedResponse(const nsACString& aFinalURLSpec)
|
|
||||||
{
|
|
||||||
if (NS_WARN_IF(!mChannel)) {
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!aFinalURLSpec.IsEmpty()) {
|
|
||||||
// We don't support rewriting responses for JAR channels where the principal
|
|
||||||
// needs to be modified.
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
mChannel->OverrideWithSynthesizedResponse(mSynthesizedInput, mContentType);
|
|
||||||
|
|
||||||
mResponseBody = nullptr;
|
|
||||||
mReleaseHandle = nullptr;
|
|
||||||
mChannel = nullptr;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
InterceptedJARChannel::Cancel(nsresult aStatus)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_FAILED(aStatus));
|
|
||||||
|
|
||||||
if (!mChannel) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult rv = mChannel->Cancel(aStatus);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
mResponseBody = nullptr;
|
|
||||||
mReleaseHandle = nullptr;
|
|
||||||
mChannel = nullptr;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
InterceptedJARChannel::SetChannelInfo(mozilla::dom::ChannelInfo* aChannelInfo)
|
|
||||||
{
|
|
||||||
if (!mChannel) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return aChannelInfo->ResurrectInfoOnChannel(mChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
InterceptedJARChannel::GetConsoleReportCollector(nsIConsoleReportCollector**)
|
|
||||||
{
|
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
InterceptedJARChannel::SetReleaseHandle(nsISupports* aHandle)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
MOZ_ASSERT(!mReleaseHandle);
|
|
||||||
MOZ_ASSERT(aHandle);
|
|
||||||
mReleaseHandle = aHandle;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
InterceptedJARChannel::NotifyController()
|
|
||||||
{
|
|
||||||
nsresult rv = NS_NewPipe(getter_AddRefs(mSynthesizedInput),
|
|
||||||
getter_AddRefs(mResponseBody),
|
|
||||||
0, UINT32_MAX, true, true);
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
|
||||||
|
|
||||||
rv = mController->ChannelIntercepted(this);
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
rv = ResetInterception();
|
|
||||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
|
|
||||||
"Failed to resume intercepted network request");
|
|
||||||
}
|
|
||||||
mController = nullptr;
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim:set expandtab ts=2 sw=2 sts=2 cin: */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef InterceptedJARChannel_h
|
|
||||||
#define InterceptedJARChannel_h
|
|
||||||
|
|
||||||
#include "nsJAR.h"
|
|
||||||
#include "nsJARChannel.h"
|
|
||||||
#include "nsIInputStream.h"
|
|
||||||
#include "nsIInputStreamPump.h"
|
|
||||||
#include "nsINetworkInterceptController.h"
|
|
||||||
#include "nsIOutputStream.h"
|
|
||||||
#include "mozilla/RefPtr.h"
|
|
||||||
|
|
||||||
#include "mozilla/Maybe.h"
|
|
||||||
|
|
||||||
class nsIStreamListener;
|
|
||||||
class nsJARChannel;
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace net {
|
|
||||||
|
|
||||||
// An object representing a channel that has been intercepted. This avoids
|
|
||||||
// complicating the actual channel implementation with the details of
|
|
||||||
// synthesizing responses.
|
|
||||||
class InterceptedJARChannel : public nsIInterceptedChannel
|
|
||||||
{
|
|
||||||
// The interception controller to notify about the successful channel
|
|
||||||
// interception.
|
|
||||||
nsCOMPtr<nsINetworkInterceptController> mController;
|
|
||||||
|
|
||||||
// The actual channel being intercepted.
|
|
||||||
RefPtr<nsJARChannel> mChannel;
|
|
||||||
|
|
||||||
// Reader-side of the synthesized response body.
|
|
||||||
nsCOMPtr<nsIInputStream> mSynthesizedInput;
|
|
||||||
|
|
||||||
// The stream to write the body of the synthesized response.
|
|
||||||
nsCOMPtr<nsIOutputStream> mResponseBody;
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> mReleaseHandle;
|
|
||||||
|
|
||||||
// The content type of the synthesized response.
|
|
||||||
nsCString mContentType;
|
|
||||||
|
|
||||||
virtual ~InterceptedJARChannel() {};
|
|
||||||
public:
|
|
||||||
InterceptedJARChannel(nsJARChannel* aChannel,
|
|
||||||
nsINetworkInterceptController* aController);
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
NS_DECL_NSIINTERCEPTEDCHANNEL
|
|
||||||
|
|
||||||
void NotifyController();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace net
|
|
||||||
} // namespace mozilla
|
|
||||||
|
|
||||||
#endif // InterceptedJARChannel_h
|
|
@ -23,14 +23,12 @@ XPIDL_SOURCES += [
|
|||||||
XPIDL_MODULE = 'jar'
|
XPIDL_MODULE = 'jar'
|
||||||
|
|
||||||
EXPORTS += [
|
EXPORTS += [
|
||||||
'InterceptedJARChannel.h',
|
|
||||||
'nsJARURI.h',
|
'nsJARURI.h',
|
||||||
'nsZipArchive.h',
|
'nsZipArchive.h',
|
||||||
'zipstruct.h',
|
'zipstruct.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
'InterceptedJARChannel.cpp',
|
|
||||||
'nsJARProtocolHandler.cpp',
|
'nsJARProtocolHandler.cpp',
|
||||||
'nsJARURI.cpp',
|
'nsJARURI.cpp',
|
||||||
]
|
]
|
||||||
|
@ -25,8 +25,6 @@
|
|||||||
#include "mozilla/net/RemoteOpenFileChild.h"
|
#include "mozilla/net/RemoteOpenFileChild.h"
|
||||||
#include "nsITabChild.h"
|
#include "nsITabChild.h"
|
||||||
#include "private/pprio.h"
|
#include "private/pprio.h"
|
||||||
#include "nsINetworkInterceptController.h"
|
|
||||||
#include "InterceptedJARChannel.h"
|
|
||||||
#include "nsInputStreamPump.h"
|
#include "nsInputStreamPump.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
@ -203,7 +201,6 @@ nsJARChannel::nsJARChannel()
|
|||||||
, mIsPending(false)
|
, mIsPending(false)
|
||||||
, mIsUnsafe(true)
|
, mIsUnsafe(true)
|
||||||
, mOpeningRemote(false)
|
, mOpeningRemote(false)
|
||||||
, mSynthesizedStreamLength(0)
|
|
||||||
, mBlockRemoteFiles(false)
|
, mBlockRemoteFiles(false)
|
||||||
{
|
{
|
||||||
if (!gJarProtocolLog)
|
if (!gJarProtocolLog)
|
||||||
@ -521,8 +518,6 @@ nsJARChannel::GetStatus(nsresult *status)
|
|||||||
{
|
{
|
||||||
if (mPump && NS_SUCCEEDED(mStatus))
|
if (mPump && NS_SUCCEEDED(mStatus))
|
||||||
mPump->GetStatus(status);
|
mPump->GetStatus(status);
|
||||||
else if (mSynthesizedResponsePump && NS_SUCCEEDED(mStatus))
|
|
||||||
mSynthesizedResponsePump->GetStatus(status);
|
|
||||||
else
|
else
|
||||||
*status = mStatus;
|
*status = mStatus;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -534,8 +529,6 @@ nsJARChannel::Cancel(nsresult status)
|
|||||||
mStatus = status;
|
mStatus = status;
|
||||||
if (mPump)
|
if (mPump)
|
||||||
return mPump->Cancel(status);
|
return mPump->Cancel(status);
|
||||||
if (mSynthesizedResponsePump)
|
|
||||||
return mSynthesizedResponsePump->Cancel(status);
|
|
||||||
|
|
||||||
NS_ASSERTION(!mIsPending, "need to implement cancel when downloading");
|
NS_ASSERTION(!mIsPending, "need to implement cancel when downloading");
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -546,8 +539,6 @@ nsJARChannel::Suspend()
|
|||||||
{
|
{
|
||||||
if (mPump)
|
if (mPump)
|
||||||
return mPump->Suspend();
|
return mPump->Suspend();
|
||||||
if (mSynthesizedResponsePump)
|
|
||||||
return mSynthesizedResponsePump->Suspend();
|
|
||||||
|
|
||||||
NS_ASSERTION(!mIsPending, "need to implement suspend when downloading");
|
NS_ASSERTION(!mIsPending, "need to implement suspend when downloading");
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -558,8 +549,6 @@ nsJARChannel::Resume()
|
|||||||
{
|
{
|
||||||
if (mPump)
|
if (mPump)
|
||||||
return mPump->Resume();
|
return mPump->Resume();
|
||||||
if (mSynthesizedResponsePump)
|
|
||||||
return mSynthesizedResponsePump->Resume();
|
|
||||||
|
|
||||||
NS_ASSERTION(!mIsPending, "need to implement resume when downloading");
|
NS_ASSERTION(!mIsPending, "need to implement resume when downloading");
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -863,78 +852,6 @@ nsJARChannel::Open2(nsIInputStream** aStream)
|
|||||||
return Open(aStream);
|
return Open(aStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
nsJARChannel::BypassServiceWorker() const
|
|
||||||
{
|
|
||||||
return mLoadFlags & LOAD_BYPASS_SERVICE_WORKER;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
nsJARChannel::ShouldIntercept()
|
|
||||||
{
|
|
||||||
LOG(("nsJARChannel::ShouldIntercept [this=%x]\n", this));
|
|
||||||
// We only intercept app:// requests
|
|
||||||
if (!mAppURI) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsINetworkInterceptController> controller;
|
|
||||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
|
|
||||||
NS_GET_IID(nsINetworkInterceptController),
|
|
||||||
getter_AddRefs(controller));
|
|
||||||
bool shouldIntercept = false;
|
|
||||||
if (controller && !BypassServiceWorker() && mLoadInfo) {
|
|
||||||
nsresult rv = controller->ShouldPrepareForIntercept(mAppURI,
|
|
||||||
nsContentUtils::IsNonSubresourceRequest(this),
|
|
||||||
&shouldIntercept);
|
|
||||||
NS_ENSURE_SUCCESS(rv, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return shouldIntercept;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsJARChannel::ResetInterception()
|
|
||||||
{
|
|
||||||
LOG(("nsJARChannel::ResetInterception [this=%x]\n", this));
|
|
||||||
|
|
||||||
// Continue with the original request.
|
|
||||||
nsresult rv = ContinueAsyncOpen();
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsJARChannel::OverrideWithSynthesizedResponse(nsIInputStream* aSynthesizedInput,
|
|
||||||
const nsACString& aContentType)
|
|
||||||
{
|
|
||||||
// In our current implementation, the FetchEvent handler will copy the
|
|
||||||
// response stream completely into the pipe backing the input stream so we
|
|
||||||
// can treat the available as the length of the stream.
|
|
||||||
uint64_t available;
|
|
||||||
nsresult rv = aSynthesizedInput->Available(&available);
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
mSynthesizedStreamLength = -1;
|
|
||||||
} else {
|
|
||||||
mSynthesizedStreamLength = int64_t(available);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = nsInputStreamPump::Create(getter_AddRefs(mSynthesizedResponsePump),
|
|
||||||
aSynthesizedInput,
|
|
||||||
int64_t(-1), int64_t(-1), 0, 0, true);
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
aSynthesizedInput->Close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetContentType(aContentType);
|
|
||||||
|
|
||||||
mIsUnsafe = false;
|
|
||||||
|
|
||||||
FinishAsyncOpen();
|
|
||||||
|
|
||||||
rv = mSynthesizedResponsePump->AsyncRead(this, nullptr);
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsJARChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx)
|
nsJARChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx)
|
||||||
{
|
{
|
||||||
@ -961,48 +878,6 @@ nsJARChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx)
|
|||||||
mListenerContext = ctx;
|
mListenerContext = ctx;
|
||||||
mIsPending = true;
|
mIsPending = true;
|
||||||
|
|
||||||
// Bug 1171651 - Disable the interception of app:// URIs in service workers
|
|
||||||
// on release builds
|
|
||||||
#ifndef RELEASE_BUILD
|
|
||||||
// Check if this channel should intercept the network request and prepare
|
|
||||||
// for a possible synthesized response instead.
|
|
||||||
if (ShouldIntercept()) {
|
|
||||||
nsCOMPtr<nsINetworkInterceptController> controller;
|
|
||||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
|
|
||||||
NS_GET_IID(nsINetworkInterceptController),
|
|
||||||
getter_AddRefs(controller));
|
|
||||||
|
|
||||||
RefPtr<InterceptedJARChannel> intercepted =
|
|
||||||
new InterceptedJARChannel(this, controller);
|
|
||||||
intercepted->NotifyController();
|
|
||||||
|
|
||||||
// We get the JAREntry so we can infer the content type later in case
|
|
||||||
// that it isn't provided along with the synthesized response.
|
|
||||||
nsresult rv = mJarURI->GetJAREntry(mJarEntry);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ContinueAsyncOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsJARChannel::AsyncOpen2(nsIStreamListener *aListener)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIStreamListener> listener = aListener;
|
|
||||||
nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
return AsyncOpen(listener, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsJARChannel::ContinueAsyncOpen()
|
|
||||||
{
|
|
||||||
LOG(("nsJARChannel::ContinueAsyncOpen [this=%x]\n", this));
|
|
||||||
nsresult rv = LookupFile(true);
|
nsresult rv = LookupFile(true);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
mIsPending = false;
|
mIsPending = false;
|
||||||
@ -1057,19 +932,21 @@ nsJARChannel::ContinueAsyncOpen()
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FinishAsyncOpen();
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsJARChannel::FinishAsyncOpen()
|
|
||||||
{
|
|
||||||
if (mLoadGroup)
|
if (mLoadGroup)
|
||||||
mLoadGroup->AddRequest(this, nullptr);
|
mLoadGroup->AddRequest(this, nullptr);
|
||||||
|
|
||||||
mOpened = true;
|
mOpened = true;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsJARChannel::AsyncOpen2(nsIStreamListener *aListener)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIStreamListener> listener = aListener;
|
||||||
|
nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
return AsyncOpen(listener, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include "nsIJARChannel.h"
|
#include "nsIJARChannel.h"
|
||||||
#include "nsIJARURI.h"
|
#include "nsIJARURI.h"
|
||||||
#include "nsIInputStreamPump.h"
|
#include "nsIInputStreamPump.h"
|
||||||
#include "InterceptedJARChannel.h"
|
|
||||||
#include "nsIInterfaceRequestor.h"
|
#include "nsIInterfaceRequestor.h"
|
||||||
#include "nsIProgressEventSink.h"
|
#include "nsIProgressEventSink.h"
|
||||||
#include "nsIStreamListener.h"
|
#include "nsIStreamListener.h"
|
||||||
@ -30,12 +29,6 @@
|
|||||||
class nsJARInputThunk;
|
class nsJARInputThunk;
|
||||||
class nsInputStreamPump;
|
class nsInputStreamPump;
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace net {
|
|
||||||
class InterceptedJARChannel;
|
|
||||||
} // namespace net
|
|
||||||
} // namespace mozilla
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
class nsJARChannel final : public nsIJARChannel
|
class nsJARChannel final : public nsIJARChannel
|
||||||
@ -80,23 +73,6 @@ private:
|
|||||||
mozilla::net::MemoryDownloader::Data aData)
|
mozilla::net::MemoryDownloader::Data aData)
|
||||||
override;
|
override;
|
||||||
|
|
||||||
bool BypassServiceWorker() const;
|
|
||||||
|
|
||||||
// Returns true if this channel should intercept the network request and
|
|
||||||
// prepare for a possible synthesized response instead.
|
|
||||||
bool ShouldIntercept();
|
|
||||||
|
|
||||||
nsresult ContinueAsyncOpen();
|
|
||||||
void FinishAsyncOpen();
|
|
||||||
|
|
||||||
// Discard the prior interception and continue with the original network
|
|
||||||
// request.
|
|
||||||
void ResetInterception();
|
|
||||||
// Override this channel's pending response with a synthesized one. The
|
|
||||||
// content will be asynchronously read from the pump.
|
|
||||||
void OverrideWithSynthesizedResponse(nsIInputStream* aSynthesizedInput,
|
|
||||||
const nsACString& aContentType);
|
|
||||||
|
|
||||||
nsCString mSpec;
|
nsCString mSpec;
|
||||||
|
|
||||||
bool mOpened;
|
bool mOpened;
|
||||||
@ -135,12 +111,8 @@ private:
|
|||||||
nsCString mJarEntry;
|
nsCString mJarEntry;
|
||||||
nsCString mInnerJarEntry;
|
nsCString mInnerJarEntry;
|
||||||
|
|
||||||
RefPtr<nsInputStreamPump> mSynthesizedResponsePump;
|
|
||||||
int64_t mSynthesizedStreamLength;
|
|
||||||
|
|
||||||
// True if this channel should not download any remote files.
|
// True if this channel should not download any remote files.
|
||||||
bool mBlockRemoteFiles;
|
bool mBlockRemoteFiles;
|
||||||
friend class mozilla::net::InterceptedJARChannel;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // nsJARChannel_h__
|
#endif // nsJARChannel_h__
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "nsXULAppAPI.h"
|
#include "nsXULAppAPI.h"
|
||||||
#include "nsPrincipal.h"
|
#include "nsPrincipal.h"
|
||||||
#include "nsContentSecurityManager.h"
|
#include "nsContentSecurityManager.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
|
||||||
#include "mozilla/dom/ScriptSettings.h"
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user