WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-175482-20170814183757.patch (text/plain), 83.05 KB, created by
Chris Dumez
on 2017-08-14 18:37:58 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Chris Dumez
Created:
2017-08-14 18:37:58 PDT
Size:
83.05 KB
patch
obsolete
>Subversion Revision: 220731 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index c46f1463708feb003f7b41347300aa60143fff6f..52580f88a676a4c5891e08631f49c177c8372d59 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,5 +1,78 @@ > 2017-08-14 Chris Dumez <cdumez@apple.com> > >+ Implement quota limitation for keepalive Fetch requests >+ https://bugs.webkit.org/show_bug.cgi?id=175482 >+ >+ Reviewed by Sam Weinig and Youenn Fablet. >+ >+ Implement quota limitation for keepalive Fetch requests as per: >+ - https://fetch.spec.whatwg.org/#http-network-or-cache-fetch (Step 9) >+ >+ This partly works for Beacon as well, meaning that no Beacon with a body >+ over 64Kb can be sent. However, we don't keep track about wether or not >+ beacon loads are inflight or not. >+ >+ Also update CachedResourceLoader::requestResource() so that the caller >+ can get a ResourceError when it returns null. This is useful for both >+ Fetch and Beacon to return better error messages. >+ >+ Test: http/wpt/beacon/beacon-quota.html >+ >+ * CMakeLists.txt: >+ * Modules/beacon/NavigatorBeacon.cpp: >+ (WebCore::NavigatorBeacon::sendBeacon): >+ * Modules/fetch/FetchBodyOwner.cpp: >+ (WebCore::FetchBodyOwner::BlobLoader::didReceiveResponse): >+ (WebCore::FetchBodyOwner::BlobLoader::didFail): >+ * Modules/fetch/FetchBodyOwner.h: >+ * Modules/fetch/FetchLoader.cpp: >+ (WebCore::FetchLoader::start): >+ (WebCore::FetchLoader::didFail): >+ * Modules/fetch/FetchLoaderClient.h: >+ * Modules/fetch/FetchResponse.cpp: >+ (WebCore::FetchResponse::BodyLoader::didFail): >+ * Modules/fetch/FetchResponse.h: >+ * WebCore.xcodeproj/project.pbxproj: >+ * loader/DocumentThreadableLoader.cpp: >+ (WebCore::DocumentThreadableLoader::loadRequest): >+ * loader/cache/CachedResource.cpp: >+ (WebCore::CachedResource::load): >+ * loader/cache/CachedResource.h: >+ (WebCore::CachedResource::isMainOrMediaOrIconOrRawResource const): >+ * loader/cache/CachedResourceLoader.cpp: >+ (WebCore::createResource): >+ (WebCore::CachedResourceLoader::requestImage): >+ (WebCore::CachedResourceLoader::requestFont): >+ (WebCore::CachedResourceLoader::requestTextTrack): >+ (WebCore::CachedResourceLoader::requestCSSStyleSheet): >+ (WebCore::CachedResourceLoader::requestUserCSSStyleSheet): >+ (WebCore::CachedResourceLoader::requestScript): >+ (WebCore::CachedResourceLoader::requestXSLStyleSheet): >+ (WebCore::CachedResourceLoader::requestSVGDocument): >+ (WebCore::CachedResourceLoader::requestLinkResource): >+ (WebCore::CachedResourceLoader::requestMedia): >+ (WebCore::CachedResourceLoader::requestIcon): >+ (WebCore::CachedResourceLoader::requestRawResource): >+ (WebCore::CachedResourceLoader::requestBeaconResource): >+ (WebCore::CachedResourceLoader::requestMainResource): >+ (WebCore::CachedResourceLoader::requestResource): >+ (WebCore::CachedResourceLoader::preload): >+ * loader/cache/CachedResourceLoader.h: >+ * loader/cache/KeepaliveRequestTracker.cpp: Added. >+ (WebCore::KeepaliveRequestTracker::~KeepaliveRequestTracker): >+ (WebCore::KeepaliveRequestTracker::canLoadRequest): >+ (WebCore::KeepaliveRequestTracker::registerRequest): >+ (WebCore::KeepaliveRequestTracker::responseReceived): >+ (WebCore::KeepaliveRequestTracker::notifyFinished): >+ (WebCore::KeepaliveRequestTracker::unregisterRequest): >+ * loader/cache/KeepaliveRequestTracker.h: Added. >+ * platform/network/FormData.cpp: >+ (WebCore::FormDataElement::lengthInBytes const): >+ (WebCore::FormData::lengthInBytes const): >+ * platform/network/FormData.h: >+ >+2017-08-14 Chris Dumez <cdumez@apple.com> >+ > XHR should only fire an abort event if the cancellation was requested by the client > https://bugs.webkit.org/show_bug.cgi?id=175546 > >diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt >index e3f4c92b6988c89e279186ce2fa347304206e7b2..b9a4a98c1420c4ffb31efc34a1f8fe50553c0f87 100644 >--- a/Source/WebCore/CMakeLists.txt >+++ b/Source/WebCore/CMakeLists.txt >@@ -2077,6 +2077,7 @@ set(WebCore_SOURCES > loader/cache/CachedSVGFont.cpp > loader/cache/CachedScript.cpp > loader/cache/CachedXSLStyleSheet.cpp >+ loader/cache/KeepaliveRequestTracker.cpp > loader/cache/MemoryCache.cpp > > loader/icon/IconLoader.cpp >diff --git a/Source/WebCore/Modules/beacon/NavigatorBeacon.cpp b/Source/WebCore/Modules/beacon/NavigatorBeacon.cpp >index 2c1991bf7f56b68afa6d2419219cf2911ccf9119..8b2f5a7802a5099aa543214d4e871fca7883a08a 100644 >--- a/Source/WebCore/Modules/beacon/NavigatorBeacon.cpp >+++ b/Source/WebCore/Modules/beacon/NavigatorBeacon.cpp >@@ -73,7 +73,12 @@ ExceptionOr<bool> NavigatorBeacon::sendBeacon(Navigator&, Document& document, co > options.mode = FetchOptions::Mode::NoCors; > } > } >- document.cachedResourceLoader().requestBeaconResource({ WTFMove(request), options }); >+ ResourceError error; >+ if (!document.cachedResourceLoader().requestBeaconResource({ WTFMove(request), options }, &error)) { >+ if (!error.isNull()) >+ document.addConsoleMessage(MessageSource::Network, MessageLevel::Error, error.localizedDescription()); >+ return false; >+ } > return true; > } > >diff --git a/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp b/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp >index 37d30f8c577dc0b1157f0421fd3e634006178247..6bc1d9ab2609ee87c7b5ad545b0b46f2448849b1 100644 >--- a/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp >+++ b/Source/WebCore/Modules/fetch/FetchBodyOwner.cpp >@@ -32,6 +32,7 @@ > #include "FetchLoader.h" > #include "HTTPParsers.h" > #include "JSBlob.h" >+#include "ResourceError.h" > #include "ResourceResponse.h" > > namespace WebCore { >@@ -277,10 +278,10 @@ FetchBodyOwner::BlobLoader::BlobLoader(FetchBodyOwner& owner) > void FetchBodyOwner::BlobLoader::didReceiveResponse(const ResourceResponse& response) > { > if (response.httpStatusCode() != 200) >- didFail(); >+ didFail({ }); > } > >-void FetchBodyOwner::BlobLoader::didFail() >+void FetchBodyOwner::BlobLoader::didFail(const ResourceError&) > { > // didFail might be called within FetchLoader::start call. > if (loader->isStarted()) >diff --git a/Source/WebCore/Modules/fetch/FetchBodyOwner.h b/Source/WebCore/Modules/fetch/FetchBodyOwner.h >index c3213e972139300d4a51854c0559ab55014a955b..5b83d2671f0cf49f8135f7019d1bfcaec511c52f 100644 >--- a/Source/WebCore/Modules/fetch/FetchBodyOwner.h >+++ b/Source/WebCore/Modules/fetch/FetchBodyOwner.h >@@ -88,7 +88,7 @@ private: > // FetchLoaderClient API > void didReceiveResponse(const ResourceResponse&) final; > void didReceiveData(const char* data, size_t size) final { owner.blobChunk(data, size); } >- void didFail() final; >+ void didFail(const ResourceError&) final; > void didSucceed() final { owner.blobLoadingSucceeded(); } > > FetchBodyOwner& owner; >diff --git a/Source/WebCore/Modules/fetch/FetchLoader.cpp b/Source/WebCore/Modules/fetch/FetchLoader.cpp >index e3a51f1ae84392bf30fc8b5d33531a09db85ccac..4c2bf83c433dd90647036f3cd3de2f82bec888d9 100644 >--- a/Source/WebCore/Modules/fetch/FetchLoader.cpp >+++ b/Source/WebCore/Modules/fetch/FetchLoader.cpp >@@ -35,6 +35,7 @@ > #include "FetchBody.h" > #include "FetchLoaderClient.h" > #include "FetchRequest.h" >+#include "ResourceError.h" > #include "ResourceRequest.h" > #include "ScriptExecutionContext.h" > #include "SecurityOrigin.h" >@@ -48,7 +49,7 @@ void FetchLoader::start(ScriptExecutionContext& context, const Blob& blob) > { > auto urlForReading = BlobURL::createPublicURL(context.securityOrigin()); > if (urlForReading.isEmpty()) { >- m_client.didFail(); >+ m_client.didFail({ errorDomainWebKitInternal, 0, URL(), ASCIILiteral("Could not create URL for Blob") }); > return; > } > >@@ -88,7 +89,7 @@ void FetchLoader::start(ScriptExecutionContext& context, const FetchRequest& req > contentSecurityPolicy.upgradeInsecureRequestIfNeeded(fetchRequest, ContentSecurityPolicy::InsecureRequestType::Load); > > if (!context.shouldBypassMainWorldContentSecurityPolicy() && !contentSecurityPolicy.allowConnectToSource(fetchRequest.url())) { >- m_client.didFail(); >+ m_client.didFail({ errorDomainWebKitInternal, 0, fetchRequest.url(), ASCIILiteral("Not allowed by ContentSecurityPolicy"), ResourceError::Type::AccessControl }); > return; > } > >@@ -144,9 +145,9 @@ void FetchLoader::didFinishLoading(unsigned long) > m_client.didSucceed(); > } > >-void FetchLoader::didFail(const ResourceError&) >+void FetchLoader::didFail(const ResourceError& error) > { >- m_client.didFail(); >+ m_client.didFail(error); > } > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/fetch/FetchLoaderClient.h b/Source/WebCore/Modules/fetch/FetchLoaderClient.h >index 195f1ef204f601f9f407fe8ef6ccdf878335ea77..cbff9bd91fcc8f3f14aa5680058603bc13637cb7 100644 >--- a/Source/WebCore/Modules/fetch/FetchLoaderClient.h >+++ b/Source/WebCore/Modules/fetch/FetchLoaderClient.h >@@ -32,6 +32,7 @@ > > namespace WebCore { > >+class ResourceError; > class ResourceResponse; > > class FetchLoaderClient { >@@ -43,7 +44,7 @@ public: > virtual void didReceiveData(const char*, size_t) { } > > virtual void didSucceed() = 0; >- virtual void didFail() = 0; >+ virtual void didFail(const ResourceError&) = 0; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/fetch/FetchResponse.cpp b/Source/WebCore/Modules/fetch/FetchResponse.cpp >index 68adb559fe9530f7456dc96f9884b7ffdd6a81be..22532c44050857141a89f193072ee07ff3deaa4f 100644 >--- a/Source/WebCore/Modules/fetch/FetchResponse.cpp >+++ b/Source/WebCore/Modules/fetch/FetchResponse.cpp >@@ -33,6 +33,7 @@ > #include "HTTPParsers.h" > #include "JSBlob.h" > #include "JSFetchResponse.h" >+#include "ResourceError.h" > #include "ScriptExecutionContext.h" > > namespace WebCore { >@@ -138,11 +139,11 @@ void FetchResponse::BodyLoader::didSucceed() > } > } > >-void FetchResponse::BodyLoader::didFail() >+void FetchResponse::BodyLoader::didFail(const ResourceError& error) > { > ASSERT(m_response.hasPendingActivity()); > if (m_promise) >- std::exchange(m_promise, std::nullopt)->reject(TypeError); >+ std::exchange(m_promise, std::nullopt)->reject(Exception { TypeError, String(error.localizedDescription()) }); > > #if ENABLE(STREAMS_API) > if (m_response.m_readableStreamSource) { >diff --git a/Source/WebCore/Modules/fetch/FetchResponse.h b/Source/WebCore/Modules/fetch/FetchResponse.h >index f9b02fb0e587ab4eb3d559794b391f79f5a1dc66..540e67b39ccd3adbd810b4bb763707621defcca9 100644 >--- a/Source/WebCore/Modules/fetch/FetchResponse.h >+++ b/Source/WebCore/Modules/fetch/FetchResponse.h >@@ -118,7 +118,7 @@ private: > private: > // FetchLoaderClient API > void didSucceed() final; >- void didFail() final; >+ void didFail(const ResourceError&) final; > void didReceiveResponse(const ResourceResponse&) final; > void didReceiveData(const char*, size_t) final; > >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 30b4839818487573a8840eaa43b8259d39cfea97..6743db1b1233b1ff9889fe010526046b04ff39b4 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -3475,6 +3475,8 @@ > 839AAFED1A0C0C8D00605F99 /* HTMLWBRElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 839AAFEB1A0C0C8D00605F99 /* HTMLWBRElement.h */; }; > 83A4A9F91CE7FD8100709B00 /* JSXMLDocumentCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83A4A9F81CE7FD7E00709B00 /* JSXMLDocumentCustom.cpp */; }; > 83B2D1751B8BCD6A00A02E47 /* NativeNodeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 83E959E11B8BC22B004D9385 /* NativeNodeFilter.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 83B74EF51F3E0BF200996BC7 /* KeepaliveRequestTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B74EF21F3E0BD700996BC7 /* KeepaliveRequestTracker.cpp */; }; >+ 83B74EF61F3E0BF200996BC7 /* KeepaliveRequestTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B74EF31F3E0BD700996BC7 /* KeepaliveRequestTracker.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 83B9687B19F8AB83004EF7AF /* StyleBuilderConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B9687919F8AB83004EF7AF /* StyleBuilderConverter.h */; }; > 83BB5C881D5D6F45005A71F4 /* AllDescendantsCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 83BB5C871D5D6F3A005A71F4 /* AllDescendantsCollection.h */; }; > 83C05A5A1A686212007E5DEA /* StylePropertyShorthandFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83C05A581A686212007E5DEA /* StylePropertyShorthandFunctions.cpp */; }; >@@ -11604,6 +11606,8 @@ > 839AAFEA1A0C0C8D00605F99 /* HTMLWBRElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLWBRElement.cpp; sourceTree = "<group>"; }; > 839AAFEB1A0C0C8D00605F99 /* HTMLWBRElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTMLWBRElement.h; sourceTree = "<group>"; }; > 83A4A9F81CE7FD7E00709B00 /* JSXMLDocumentCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSXMLDocumentCustom.cpp; sourceTree = "<group>"; }; >+ 83B74EF21F3E0BD700996BC7 /* KeepaliveRequestTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeepaliveRequestTracker.cpp; sourceTree = "<group>"; }; >+ 83B74EF31F3E0BD700996BC7 /* KeepaliveRequestTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeepaliveRequestTracker.h; sourceTree = "<group>"; }; > 83B9687919F8AB83004EF7AF /* StyleBuilderConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleBuilderConverter.h; sourceTree = "<group>"; }; > 83BB5C871D5D6F3A005A71F4 /* AllDescendantsCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AllDescendantsCollection.h; sourceTree = "<group>"; }; > 83C05A581A686212007E5DEA /* StylePropertyShorthandFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StylePropertyShorthandFunctions.cpp; sourceTree = "<group>"; }; >@@ -22392,6 +22396,8 @@ > BCB16C0E0979C3BD00467741 /* CachedXSLStyleSheet.cpp */, > BCB16C0F0979C3BD00467741 /* CachedXSLStyleSheet.h */, > F587864902DE3A9A01EA4122 /* CachePolicy.h */, >+ 83B74EF21F3E0BD700996BC7 /* KeepaliveRequestTracker.cpp */, >+ 83B74EF31F3E0BD700996BC7 /* KeepaliveRequestTracker.h */, > BCB16BFE0979C3BD00467741 /* MemoryCache.cpp */, > BCB16BFF0979C3BD00467741 /* MemoryCache.h */, > ); >@@ -28597,6 +28603,7 @@ > 1A762C780A074F2600989F5B /* JSXPathNSResolver.h in Headers */, > 1A762C7A0A074F2600989F5B /* JSXPathResult.h in Headers */, > BCEFE1EB0DCA5F6400739219 /* JSXSLTProcessor.h in Headers */, >+ 83B74EF61F3E0BF200996BC7 /* KeepaliveRequestTracker.h in Headers */, > 85031B440A44EFC700F992E0 /* KeyboardEvent.h in Headers */, > 1AE00D59182DAC8D00087DD7 /* KeyedCoding.h in Headers */, > 517A63C51B74318F00E7DCDC /* KeyedDecoderCF.h in Headers */, >@@ -32639,6 +32646,7 @@ > 1A762C790A074F2600989F5B /* JSXPathResult.cpp in Sources */, > A1C7FAA2133A5D3500D6732D /* JSXPathResultCustom.cpp in Sources */, > BCEFE1EA0DCA5F6400739219 /* JSXSLTProcessor.cpp in Sources */, >+ 83B74EF51F3E0BF200996BC7 /* KeepaliveRequestTracker.cpp in Sources */, > 85031B430A44EFC700F992E0 /* KeyboardEvent.cpp in Sources */, > 517A63C31B74318700E7DCDC /* KeyedDecoderCF.cpp in Sources */, > 517A63C41B74318B00E7DCDC /* KeyedEncoderCF.cpp in Sources */, >diff --git a/Source/WebCore/loader/DocumentThreadableLoader.cpp b/Source/WebCore/loader/DocumentThreadableLoader.cpp >index 7ee60beafdc250638282a7c87eba4cc73acc882b..548b163fdce954033cba2b45ba00846e9f9868ad 100644 >--- a/Source/WebCore/loader/DocumentThreadableLoader.cpp >+++ b/Source/WebCore/loader/DocumentThreadableLoader.cpp >@@ -451,12 +451,16 @@ void DocumentThreadableLoader::loadRequest(ResourceRequest&& request, SecurityCh > > // We create an URL here as the request will be moved in requestRawResource > URL requestUrl = newRequest.resourceRequest().url(); >- m_resource = m_document.cachedResourceLoader().requestRawResource(WTFMove(newRequest)); >+ ResourceError error; >+ m_resource = m_document.cachedResourceLoader().requestRawResource(WTFMove(newRequest), &error); > if (m_resource) > m_resource->addClient(*this); > else { >- // FIXME: Since we receive a synchronous error, this is probably due to some AccessControl checks. We should try to retrieve the actual error. >- logErrorAndFail(ResourceError(String(), 0, requestUrl, String(), ResourceError::Type::AccessControl)); >+ if (error.isNull()) { >+ // FIXME: Since we receive a synchronous error, this is probably due to some AccessControl checks. We should try to retrieve the actual error. >+ logErrorAndFail(ResourceError(String(), 0, requestUrl, String(), ResourceError::Type::AccessControl)); >+ } else >+ logErrorAndFail(error); > } > return; > } >diff --git a/Source/WebCore/loader/cache/CachedRawResource.cpp b/Source/WebCore/loader/cache/CachedRawResource.cpp >index 29b8d871c0cf661e6f370c4062075ce31ab925f5..d2d316d84aa9f1e9cb9474ade880809b58083313 100644 >--- a/Source/WebCore/loader/cache/CachedRawResource.cpp >+++ b/Source/WebCore/loader/cache/CachedRawResource.cpp >@@ -93,7 +93,7 @@ void CachedRawResource::finishLoading(SharedBuffer* data) > } > > #if USE(QUICK_LOOK) >- m_allowEncodedDataReplacement = !m_loader->isQuickLookResource(); >+ m_allowEncodedDataReplacement = m_loader && !m_loader->isQuickLookResource(); > #endif > > CachedResource::finishLoading(data); >diff --git a/Source/WebCore/loader/cache/CachedResource.cpp b/Source/WebCore/loader/cache/CachedResource.cpp >index e27e8136ece678a17f24d1382020d972c9b96648..e5eec25feee4d7b096eed6dc580fb21376af9782 100644 >--- a/Source/WebCore/loader/cache/CachedResource.cpp >+++ b/Source/WebCore/loader/cache/CachedResource.cpp >@@ -260,14 +260,23 @@ void CachedResource::load(CachedResourceLoader& cachedResourceLoader) > m_fragmentIdentifierForRequest = String(); > } > >- // FIXME: We should not special-case Beacon here. >- if (m_options.keepAlive && type() == CachedResource::Beacon) { >+ if (m_options.keepAlive) { >+ if (!cachedResourceLoader.keepaliveRequestTracker().tryRegisterRequest(*this)) { >+ setResourceError({ errorDomainWebKitInternal, 0, request.url(), ASCIILiteral("Reached maximum amount of queued data of 64Kb for keepalive requests") }); >+ failBeforeStarting(); >+ return; >+ } >+ // FIXME: We should not special-case Beacon here. >+ if (type() == CachedResource::Beacon) { > ASSERT(m_origin); >- // Beacon is not exposed to workers so it is safe to rely on the document here. >- auto* document = cachedResourceLoader.document(); >- auto* contentSecurityPolicy = document && !document->shouldBypassMainWorldContentSecurityPolicy() ? document->contentSecurityPolicy() : nullptr; >- platformStrategies()->loaderStrategy()->createPingHandle(frame.loader().networkingContext(), request, *m_origin, contentSecurityPolicy, m_options); >- return; >+ // Beacon is not exposed to workers so it is safe to rely on the document here. >+ auto* document = cachedResourceLoader.document(); >+ auto* contentSecurityPolicy = document && !document->shouldBypassMainWorldContentSecurityPolicy() ? document->contentSecurityPolicy() : nullptr; >+ platformStrategies()->loaderStrategy()->createPingHandle(frame.loader().networkingContext(), request, *m_origin, contentSecurityPolicy, m_options); >+ // FIXME: We currently do not get notified when ping loads finish so we treat them as finishing right away. >+ finishLoading(nullptr); >+ return; >+ } > } > > m_loader = platformStrategies()->loaderStrategy()->loadResource(frame, *this, request, m_options); >diff --git a/Source/WebCore/loader/cache/CachedResource.h b/Source/WebCore/loader/cache/CachedResource.h >index 6acbc9a6073e965e6fb7132d2399e2a199acb463..6996bba27520894818469a01028c0eded0c0047f 100644 >--- a/Source/WebCore/loader/cache/CachedResource.h >+++ b/Source/WebCore/loader/cache/CachedResource.h >@@ -162,7 +162,7 @@ public: > > bool isImage() const { return type() == ImageResource; } > // FIXME: CachedRawResource could be a main resource, an audio/video resource, or a raw XHR/icon resource. >- bool isMainOrMediaOrIconOrRawResource() const { return type() == MainResource || type() == MediaResource || type() == Icon || type() == RawResource; } >+ bool isMainOrMediaOrIconOrRawResource() const { return type() == MainResource || type() == MediaResource || type() == Icon || type() == RawResource || type() == Beacon; } > > // Whether this request should impact request counting and delay window.onload. > bool ignoreForRequestCount() const >diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp >index 94ec7a22d5f9e0ed8f4a4626d51fc4a74ff7142d..bd1d97f0b56fb2771516425abd0c1ae5bb030aa6 100644 >--- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp >+++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp >@@ -103,13 +103,12 @@ static CachedResource* createResource(CachedResource::Type type, CachedResourceR > #endif > case CachedResource::FontResource: > return new CachedFont(WTFMove(request), sessionID); >+ case CachedResource::Beacon: > case CachedResource::MediaResource: > case CachedResource::RawResource: > case CachedResource::Icon: > case CachedResource::MainResource: > return new CachedRawResource(WTFMove(request), type, sessionID); >- case CachedResource::Beacon: >- return new CachedResource(WTFMove(request), CachedResource::Beacon, sessionID); > #if ENABLE(XSLT) > case CachedResource::XSLStyleSheet: > return new CachedXSLStyleSheet(WTFMove(request), sessionID); >@@ -182,7 +181,7 @@ SessionID CachedResourceLoader::sessionID() const > return sessionID; > } > >-CachedResourceHandle<CachedImage> CachedResourceLoader::requestImage(CachedResourceRequest&& request) >+CachedResourceHandle<CachedImage> CachedResourceLoader::requestImage(CachedResourceRequest&& request, ResourceError* error) > { > if (Frame* frame = this->frame()) { > if (frame->loader().pageDismissalEventBeingDispatched() != FrameLoader::PageDismissalType::None) { >@@ -196,33 +195,33 @@ CachedResourceHandle<CachedImage> CachedResourceLoader::requestImage(CachedResou > } > > auto defer = clientDefersImage(request.resourceRequest().url()) ? DeferOption::DeferredByClient : DeferOption::NoDefer; >- return downcast<CachedImage>(requestResource(CachedResource::ImageResource, WTFMove(request), ForPreload::No, defer).get()); >+ return downcast<CachedImage>(requestResource(CachedResource::ImageResource, WTFMove(request), error, ForPreload::No, defer).get()); > } > >-CachedResourceHandle<CachedFont> CachedResourceLoader::requestFont(CachedResourceRequest&& request, bool isSVG) >+CachedResourceHandle<CachedFont> CachedResourceLoader::requestFont(CachedResourceRequest&& request, bool isSVG, ResourceError* error) > { > #if ENABLE(SVG_FONTS) > if (isSVG) >- return downcast<CachedSVGFont>(requestResource(CachedResource::SVGFontResource, WTFMove(request)).get()); >+ return downcast<CachedSVGFont>(requestResource(CachedResource::SVGFontResource, WTFMove(request), error).get()); > #else > UNUSED_PARAM(isSVG); > #endif >- return downcast<CachedFont>(requestResource(CachedResource::FontResource, WTFMove(request)).get()); >+ return downcast<CachedFont>(requestResource(CachedResource::FontResource, WTFMove(request), error).get()); > } > > #if ENABLE(VIDEO_TRACK) >-CachedResourceHandle<CachedTextTrack> CachedResourceLoader::requestTextTrack(CachedResourceRequest&& request) >+CachedResourceHandle<CachedTextTrack> CachedResourceLoader::requestTextTrack(CachedResourceRequest&& request, ResourceError* error) > { >- return downcast<CachedTextTrack>(requestResource(CachedResource::TextTrackResource, WTFMove(request)).get()); >+ return downcast<CachedTextTrack>(requestResource(CachedResource::TextTrackResource, WTFMove(request), error).get()); > } > #endif > >-CachedResourceHandle<CachedCSSStyleSheet> CachedResourceLoader::requestCSSStyleSheet(CachedResourceRequest&& request) >+CachedResourceHandle<CachedCSSStyleSheet> CachedResourceLoader::requestCSSStyleSheet(CachedResourceRequest&& request, ResourceError* error) > { >- return downcast<CachedCSSStyleSheet>(requestResource(CachedResource::CSSStyleSheet, WTFMove(request)).get()); >+ return downcast<CachedCSSStyleSheet>(requestResource(CachedResource::CSSStyleSheet, WTFMove(request), error).get()); > } > >-CachedResourceHandle<CachedCSSStyleSheet> CachedResourceLoader::requestUserCSSStyleSheet(CachedResourceRequest&& request) >+CachedResourceHandle<CachedCSSStyleSheet> CachedResourceLoader::requestUserCSSStyleSheet(CachedResourceRequest&& request, ResourceError*) > { > ASSERT(document()); > request.setDomainForCachePartition(*document()); >@@ -248,55 +247,55 @@ CachedResourceHandle<CachedCSSStyleSheet> CachedResourceLoader::requestUserCSSSt > return userSheet; > } > >-CachedResourceHandle<CachedScript> CachedResourceLoader::requestScript(CachedResourceRequest&& request) >+CachedResourceHandle<CachedScript> CachedResourceLoader::requestScript(CachedResourceRequest&& request, ResourceError* error) > { >- return downcast<CachedScript>(requestResource(CachedResource::Script, WTFMove(request)).get()); >+ return downcast<CachedScript>(requestResource(CachedResource::Script, WTFMove(request), error).get()); > } > > #if ENABLE(XSLT) >-CachedResourceHandle<CachedXSLStyleSheet> CachedResourceLoader::requestXSLStyleSheet(CachedResourceRequest&& request) >+CachedResourceHandle<CachedXSLStyleSheet> CachedResourceLoader::requestXSLStyleSheet(CachedResourceRequest&& request, ResourceError* error) > { >- return downcast<CachedXSLStyleSheet>(requestResource(CachedResource::XSLStyleSheet, WTFMove(request)).get()); >+ return downcast<CachedXSLStyleSheet>(requestResource(CachedResource::XSLStyleSheet, WTFMove(request), error).get()); > } > #endif > >-CachedResourceHandle<CachedSVGDocument> CachedResourceLoader::requestSVGDocument(CachedResourceRequest&& request) >+CachedResourceHandle<CachedSVGDocument> CachedResourceLoader::requestSVGDocument(CachedResourceRequest&& request, ResourceError* error) > { >- return downcast<CachedSVGDocument>(requestResource(CachedResource::SVGDocumentResource, WTFMove(request)).get()); >+ return downcast<CachedSVGDocument>(requestResource(CachedResource::SVGDocumentResource, WTFMove(request), error).get()); > } > > #if ENABLE(LINK_PREFETCH) >-CachedResourceHandle<CachedResource> CachedResourceLoader::requestLinkResource(CachedResource::Type type, CachedResourceRequest&& request) >+CachedResourceHandle<CachedResource> CachedResourceLoader::requestLinkResource(CachedResource::Type type, CachedResourceRequest&& request, ResourceError* error) > { > ASSERT(frame()); > ASSERT(type == CachedResource::LinkPrefetch || type == CachedResource::LinkSubresource); >- return requestResource(type, WTFMove(request)); >+ return requestResource(type, WTFMove(request), error); > } > #endif > >-CachedResourceHandle<CachedRawResource> CachedResourceLoader::requestMedia(CachedResourceRequest&& request) >+CachedResourceHandle<CachedRawResource> CachedResourceLoader::requestMedia(CachedResourceRequest&& request, ResourceError* error) > { >- return downcast<CachedRawResource>(requestResource(CachedResource::MediaResource, WTFMove(request)).get()); >+ return downcast<CachedRawResource>(requestResource(CachedResource::MediaResource, WTFMove(request), error).get()); > } > >-CachedResourceHandle<CachedRawResource> CachedResourceLoader::requestIcon(CachedResourceRequest&& request) >+CachedResourceHandle<CachedRawResource> CachedResourceLoader::requestIcon(CachedResourceRequest&& request, ResourceError* error) > { >- return downcast<CachedRawResource>(requestResource(CachedResource::Icon, WTFMove(request)).get()); >+ return downcast<CachedRawResource>(requestResource(CachedResource::Icon, WTFMove(request), error).get()); > } > >-CachedResourceHandle<CachedRawResource> CachedResourceLoader::requestRawResource(CachedResourceRequest&& request) >+CachedResourceHandle<CachedRawResource> CachedResourceLoader::requestRawResource(CachedResourceRequest&& request, ResourceError* error) > { >- return downcast<CachedRawResource>(requestResource(CachedResource::RawResource, WTFMove(request)).get()); >+ return downcast<CachedRawResource>(requestResource(CachedResource::RawResource, WTFMove(request), error).get()); > } > >-CachedResourceHandle<CachedResource> CachedResourceLoader::requestBeaconResource(CachedResourceRequest&& request) >+CachedResourceHandle<CachedResource> CachedResourceLoader::requestBeaconResource(CachedResourceRequest&& request, ResourceError* error) > { >- return requestResource(CachedResource::Beacon, WTFMove(request)).get(); >+ return requestResource(CachedResource::Beacon, WTFMove(request), error).get(); > } > >-CachedResourceHandle<CachedRawResource> CachedResourceLoader::requestMainResource(CachedResourceRequest&& request) >+CachedResourceHandle<CachedRawResource> CachedResourceLoader::requestMainResource(CachedResourceRequest&& request, ResourceError* error) > { >- return downcast<CachedRawResource>(requestResource(CachedResource::MainResource, WTFMove(request)).get()); >+ return downcast<CachedRawResource>(requestResource(CachedResource::MainResource, WTFMove(request), error).get()); > } > > static MixedContentChecker::ContentType contentTypeFromResourceType(CachedResource::Type type) >@@ -689,7 +688,7 @@ void CachedResourceLoader::updateHTTPRequestHeaders(CachedResource::Type type, C > request.updateAccordingCacheMode(); > } > >-CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(CachedResource::Type type, CachedResourceRequest&& request, ForPreload forPreload, DeferOption defer) >+CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(CachedResource::Type type, CachedResourceRequest&& request, ResourceError* error, ForPreload forPreload, DeferOption defer) > { > if (Document* document = this->document()) > request.upgradeInsecureRequestIfNeeded(*document); >@@ -700,6 +699,8 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(Cache > > if (!url.isValid()) { > RELEASE_LOG_IF_ALLOWED("requestResource: URL is invalid (frame = %p)", frame()); >+ if (error) >+ *error = { errorDomainWebKitInternal, 0, url, ASCIILiteral("URL is invalid") }; > return nullptr; > } > >@@ -708,6 +709,8 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(Cache > // We are passing url as well as request, as request url may contain a fragment identifier. > if (!canRequest(type, url, request, forPreload)) { > RELEASE_LOG_IF_ALLOWED("requestResource: Not allowed to request resource (frame = %p)", frame()); >+ if (error) >+ *error = { errorDomainWebKitInternal, 0, url, ASCIILiteral("Not allowed to request resource"), ResourceError::Type::AccessControl }; > return nullptr; > } > >@@ -725,6 +728,8 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(Cache > resource->setResourceError(ResourceError(ContentExtensions::WebKitContentBlockerDomain, 0, resourceRequest.url(), WEB_UI_STRING("The URL was blocked by a content blocker", "WebKitErrorBlockedByContentBlocker description"))); > return resource; > } >+ if (error) >+ *error = { errorDomainWebKitInternal, 0, url, ASCIILiteral("Resource blocked by content blocker"), ResourceError::Type::AccessControl }; > return nullptr; > } > if (blockedStatus.madeHTTPS >@@ -829,6 +834,8 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::requestResource(Cache > if (resource->errorOccurred()) { > if (resource->allowsCaching() && resource->inCache()) > memoryCache.remove(*resource); >+ if (error) >+ *error = resource->resourceError(); > return nullptr; > } > } >@@ -1245,7 +1252,7 @@ CachedResourceHandle<CachedResource> CachedResourceLoader::preload(CachedResourc > if (request.charset().isEmpty() && (type == CachedResource::Script || type == CachedResource::CSSStyleSheet)) > request.setCharset(m_document->charset()); > >- CachedResourceHandle<CachedResource> resource = requestResource(type, WTFMove(request), ForPreload::Yes); >+ CachedResourceHandle<CachedResource> resource = requestResource(type, WTFMove(request), nullptr, ForPreload::Yes); > if (resource && (!m_preloads || !m_preloads->contains(resource.get()))) { > // Fonts need special treatment since just creating the resource doesn't trigger a load. > if (type == CachedResource::FontResource) >diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.h b/Source/WebCore/loader/cache/CachedResourceLoader.h >index 71a5b88b7e0037a545e50ccce94e8cde7af7342f..38a9c0981b1a42edaed17bb899ff934a4ed52758 100644 >--- a/Source/WebCore/loader/cache/CachedResourceLoader.h >+++ b/Source/WebCore/loader/cache/CachedResourceLoader.h >@@ -30,6 +30,7 @@ > #include "CachedResourceHandle.h" > #include "CachedResourceRequest.h" > #include "ContentSecurityPolicy.h" >+#include "KeepaliveRequestTracker.h" > #include "ResourceTimingInformation.h" > #include "Timer.h" > #include <wtf/HashMap.h> >@@ -71,25 +72,25 @@ public: > static Ref<CachedResourceLoader> create(DocumentLoader* documentLoader) { return adoptRef(*new CachedResourceLoader(documentLoader)); } > ~CachedResourceLoader(); > >- CachedResourceHandle<CachedImage> requestImage(CachedResourceRequest&&); >- CachedResourceHandle<CachedCSSStyleSheet> requestCSSStyleSheet(CachedResourceRequest&&); >- CachedResourceHandle<CachedCSSStyleSheet> requestUserCSSStyleSheet(CachedResourceRequest&&); >- CachedResourceHandle<CachedScript> requestScript(CachedResourceRequest&&); >- CachedResourceHandle<CachedFont> requestFont(CachedResourceRequest&&, bool isSVG); >- CachedResourceHandle<CachedRawResource> requestMedia(CachedResourceRequest&&); >- CachedResourceHandle<CachedRawResource> requestIcon(CachedResourceRequest&&); >- CachedResourceHandle<CachedResource> requestBeaconResource(CachedResourceRequest&&); >- CachedResourceHandle<CachedRawResource> requestRawResource(CachedResourceRequest&&); >- CachedResourceHandle<CachedRawResource> requestMainResource(CachedResourceRequest&&); >- CachedResourceHandle<CachedSVGDocument> requestSVGDocument(CachedResourceRequest&&); >+ CachedResourceHandle<CachedImage> requestImage(CachedResourceRequest&&, ResourceError* = nullptr); >+ CachedResourceHandle<CachedCSSStyleSheet> requestCSSStyleSheet(CachedResourceRequest&&, ResourceError* = nullptr); >+ CachedResourceHandle<CachedCSSStyleSheet> requestUserCSSStyleSheet(CachedResourceRequest&&, ResourceError* = nullptr); >+ CachedResourceHandle<CachedScript> requestScript(CachedResourceRequest&&, ResourceError* = nullptr); >+ CachedResourceHandle<CachedFont> requestFont(CachedResourceRequest&&, bool isSVG, ResourceError* = nullptr); >+ CachedResourceHandle<CachedRawResource> requestMedia(CachedResourceRequest&&, ResourceError* = nullptr); >+ CachedResourceHandle<CachedRawResource> requestIcon(CachedResourceRequest&&, ResourceError* = nullptr); >+ CachedResourceHandle<CachedResource> requestBeaconResource(CachedResourceRequest&&, ResourceError* = nullptr); >+ CachedResourceHandle<CachedRawResource> requestRawResource(CachedResourceRequest&&, ResourceError* = nullptr); >+ CachedResourceHandle<CachedRawResource> requestMainResource(CachedResourceRequest&&, ResourceError* = nullptr); >+ CachedResourceHandle<CachedSVGDocument> requestSVGDocument(CachedResourceRequest&&, ResourceError* = nullptr); > #if ENABLE(XSLT) >- CachedResourceHandle<CachedXSLStyleSheet> requestXSLStyleSheet(CachedResourceRequest&&); >+ CachedResourceHandle<CachedXSLStyleSheet> requestXSLStyleSheet(CachedResourceRequest&&, ResourceError* = nullptr); > #endif > #if ENABLE(LINK_PREFETCH) >- CachedResourceHandle<CachedResource> requestLinkResource(CachedResource::Type, CachedResourceRequest&&); >+ CachedResourceHandle<CachedResource> requestLinkResource(CachedResource::Type, CachedResourceRequest&&, ResourceError* = nullptr); > #endif > #if ENABLE(VIDEO_TRACK) >- CachedResourceHandle<CachedTextTrack> requestTextTrack(CachedResourceRequest&&); >+ CachedResourceHandle<CachedTextTrack> requestTextTrack(CachedResourceRequest&&, ResourceError* = nullptr); > #endif > > // Logs an access denied message to the console for the specified URL. >@@ -146,13 +147,15 @@ public: > > bool isAlwaysOnLoggingAllowed() const; > >+ KeepaliveRequestTracker& keepaliveRequestTracker() { return m_keepaliveRequestTracker; } >+ > private: > explicit CachedResourceLoader(DocumentLoader*); > > enum class ForPreload { Yes, No }; > enum class DeferOption { NoDefer, DeferredByClient }; > >- CachedResourceHandle<CachedResource> requestResource(CachedResource::Type, CachedResourceRequest&&, ForPreload = ForPreload::No, DeferOption = DeferOption::NoDefer); >+ CachedResourceHandle<CachedResource> requestResource(CachedResource::Type, CachedResourceRequest&&, ResourceError* = nullptr, ForPreload = ForPreload::No, DeferOption = DeferOption::NoDefer); > CachedResourceHandle<CachedResource> revalidateResource(CachedResourceRequest&&, CachedResource&); > CachedResourceHandle<CachedResource> loadResource(CachedResource::Type, CachedResourceRequest&&); > >@@ -193,6 +196,7 @@ private: > Timer m_garbageCollectDocumentResourcesTimer; > > ResourceTimingInformation m_resourceTimingInfo; >+ KeepaliveRequestTracker m_keepaliveRequestTracker; > > // 29 bits left > bool m_autoLoadImages : 1; >diff --git a/Source/WebCore/loader/cache/KeepaliveRequestTracker.cpp b/Source/WebCore/loader/cache/KeepaliveRequestTracker.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..55beb7ec39e73df83f366926dcfb8843a8eedbbb >--- /dev/null >+++ b/Source/WebCore/loader/cache/KeepaliveRequestTracker.cpp >@@ -0,0 +1,91 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "KeepaliveRequestTracker.h" >+ >+namespace WebCore { >+ >+const uint64_t maxInflightKeepaliveBytes { 65536 }; // 64 kibibytes as per Fetch specification. >+ >+KeepaliveRequestTracker::~KeepaliveRequestTracker() >+{ >+ auto inflightRequests = WTFMove(m_inflightKeepaliveRequests); >+ for (auto& resource : inflightRequests) >+ resource->removeClient(*this); >+} >+ >+bool KeepaliveRequestTracker::tryRegisterRequest(CachedResource& resource) >+{ >+ ASSERT(resource.options().keepAlive); >+ auto* body = resource.resourceRequest().httpBody(); >+ if (!body) >+ return true; >+ >+ uint64_t bodySize = body->lengthInBytes(); >+ if (m_inflightKeepaliveBytes + bodySize > maxInflightKeepaliveBytes) >+ return false; >+ >+ registerRequest(resource); >+ return true; >+} >+ >+void KeepaliveRequestTracker::registerRequest(CachedResource& resource) >+{ >+ ASSERT(resource.options().keepAlive); >+ auto* body = resource.resourceRequest().httpBody(); >+ if (!body) >+ return; >+ ASSERT(!m_inflightKeepaliveRequests.contains(&resource)); >+ m_inflightKeepaliveRequests.append(&resource); >+ m_inflightKeepaliveBytes += body->lengthInBytes(); >+ ASSERT(m_inflightKeepaliveBytes <= maxInflightKeepaliveBytes); >+ >+ resource.addClient(*this); >+} >+ >+void KeepaliveRequestTracker::responseReceived(CachedResource& resource, const ResourceResponse&) >+{ >+ // Per Fetch specification, allocated quota should be returned before the promise is resolved, >+ // which is when the response is received. >+ unregisterRequest(resource); >+} >+ >+void KeepaliveRequestTracker::notifyFinished(CachedResource& resource) >+{ >+ unregisterRequest(resource); >+} >+ >+void KeepaliveRequestTracker::unregisterRequest(CachedResource& resource) >+{ >+ ASSERT(resource.options().keepAlive); >+ resource.removeClient(*this); >+ bool wasRemoved = m_inflightKeepaliveRequests.removeFirst(&resource); >+ ASSERT_UNUSED(wasRemoved, wasRemoved); >+ m_inflightKeepaliveBytes -= resource.resourceRequest().httpBody()->lengthInBytes(); >+ ASSERT(m_inflightKeepaliveBytes <= maxInflightKeepaliveBytes); >+} >+ >+} >diff --git a/Source/WebCore/loader/cache/KeepaliveRequestTracker.h b/Source/WebCore/loader/cache/KeepaliveRequestTracker.h >new file mode 100644 >index 0000000000000000000000000000000000000000..47da4ede7cc8959120bd7b2073ed9432216b1926 >--- /dev/null >+++ b/Source/WebCore/loader/cache/KeepaliveRequestTracker.h >@@ -0,0 +1,52 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "CachedRawResourceClient.h" >+#include "CachedResource.h" >+#include "CachedResourceHandle.h" >+#include <wtf/Forward.h> >+ >+namespace WebCore { >+ >+class KeepaliveRequestTracker final : public CachedRawResourceClient { >+public: >+ ~KeepaliveRequestTracker(); >+ bool tryRegisterRequest(CachedResource&); >+ >+ // CachedRawResourceClient. >+ void responseReceived(CachedResource&, const ResourceResponse&) final; >+ void notifyFinished(CachedResource&) final; >+ >+private: >+ void registerRequest(CachedResource&); >+ void unregisterRequest(CachedResource&); >+ >+ Vector<CachedResourceHandle<CachedResource>> m_inflightKeepaliveRequests; >+ uint64_t m_inflightKeepaliveBytes { 0 }; >+}; >+ >+} >diff --git a/Source/WebCore/platform/network/FormData.cpp b/Source/WebCore/platform/network/FormData.cpp >index 564a05379f59a914791985a8524b21094abab2b4..4d1801f9001fe6d85ea3dc4baa91ed7b371e3ad4 100644 >--- a/Source/WebCore/platform/network/FormData.cpp >+++ b/Source/WebCore/platform/network/FormData.cpp >@@ -33,6 +33,7 @@ > #include "FormDataList.h" > #include "Page.h" > #include "TextEncoding.h" >+#include "ThreadableBlobRegistry.h" > > namespace WebCore { > >@@ -124,6 +125,26 @@ Ref<FormData> FormData::isolatedCopy() const > return formData; > } > >+uint64_t FormDataElement::lengthInBytes() const >+{ >+ switch (m_type) { >+ case Type::Data: >+ return m_data.size(); >+ case Type::EncodedFile: { >+ if (m_fileLength != BlobDataItem::toEndOfFile) >+ return m_fileLength; >+ long long fileSize; >+ if (getFileSize(m_shouldGenerateFile ? m_generatedFilename : m_filename, fileSize)) >+ return fileSize; >+ return 0; >+ } >+ case Type::EncodedBlob: >+ return blobRegistry().blobSize(m_url); >+ } >+ ASSERT_NOT_REACHED(); >+ return 0; >+} >+ > FormDataElement FormDataElement::isolatedCopy() const > { > switch (m_type) { >@@ -146,16 +167,19 @@ void FormData::appendData(const void* data, size_t size) > void FormData::appendFile(const String& filename, bool shouldGenerateFile) > { > m_elements.append(FormDataElement(filename, 0, BlobDataItem::toEndOfFile, invalidFileTime(), shouldGenerateFile)); >+ m_lengthInBytes = std::nullopt; > } > > void FormData::appendFileRange(const String& filename, long long start, long long length, double expectedModificationTime, bool shouldGenerateFile) > { > m_elements.append(FormDataElement(filename, start, length, expectedModificationTime, shouldGenerateFile)); >+ m_lengthInBytes = std::nullopt; > } > > void FormData::appendBlob(const URL& blobURL) > { > m_elements.append(FormDataElement(blobURL)); >+ m_lengthInBytes = std::nullopt; > } > > void FormData::appendKeyValuePairItems(const FormDataList& list, const TextEncoding& encoding, bool isMultiPartForm, Document* document, EncodingType encodingType) >@@ -244,6 +268,7 @@ void FormData::appendKeyValuePairItems(const FormDataList& list, const TextEncod > > char* FormData::expandDataStore(size_t size) > { >+ m_lengthInBytes = std::nullopt; > if (m_elements.isEmpty() || m_elements.last().m_type != FormDataElement::Type::Data) > m_elements.append(FormDataElement()); > FormDataElement& e = m_elements.last(); >@@ -386,4 +411,15 @@ void FormData::removeGeneratedFilesIfNeeded() > } > } > >+uint64_t FormData::lengthInBytes() const >+{ >+ if (!m_lengthInBytes) { >+ uint64_t length = 0; >+ for (auto& element : m_elements) >+ length += element.lengthInBytes(); >+ m_lengthInBytes = length; >+ } >+ return *m_lengthInBytes; >+} >+ > } // namespace WebCore >diff --git a/Source/WebCore/platform/network/FormData.h b/Source/WebCore/platform/network/FormData.h >index 7e44dcaf959f8194675618073920565e4dc52324..bcb8813d228c4e79142b36586edd3cb26da105ad 100644 >--- a/Source/WebCore/platform/network/FormData.h >+++ b/Source/WebCore/platform/network/FormData.h >@@ -69,6 +69,8 @@ public: > { > } > >+ uint64_t lengthInBytes() const; >+ > FormDataElement isolatedCopy() const; > > template<typename Encoder> >@@ -254,6 +256,8 @@ public: > return FormURLEncoded; > } > >+ uint64_t lengthInBytes() const; >+ > private: > FormData(); > FormData(const FormData&); >@@ -269,6 +273,7 @@ private: > bool m_alwaysStream { false }; > Vector<char> m_boundary; > bool m_containsPasswordData { false }; >+ mutable std::optional<uint64_t> m_lengthInBytes; > }; > > inline bool operator==(const FormData& a, const FormData& b) >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 162090fa949039fa49adae40546ad885050545a8..4e3f37ed88dca3ee07c54d5a9737dafb21578ce1 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,5 +1,25 @@ > 2017-08-14 Chris Dumez <cdumez@apple.com> > >+ Implement quota limitation for keepalive Fetch requests >+ https://bugs.webkit.org/show_bug.cgi?id=175482 >+ >+ Reviewed by Sam Weinig and Youenn Fablet. >+ >+ * fast/xmlhttprequest/xmlhttprequest-nonexistent-file-expected.txt: >+ * http/tests/contentextensions/async-xhr-onerror-expected.txt: >+ * http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-xhr-asynchronous-in-iframe-expected.txt: >+ * http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-xhr-asynchronous-in-main-frame-expected.txt: >+ * http/tests/security/mixedContent/insecure-xhr-in-main-frame-expected.txt: >+ Rebaseline a few tests now that we provide a more helpful error message when an XHR is failing synchronously. >+ >+ * http/wpt/beacon/beacon-quota-expected.txt: Added. >+ * http/wpt/beacon/beacon-quota.html: Added. >+ Add layout test coverage for keepalive Fetch requests quota in the context of sendBeacon(). >+ The second part of the test is still failing because WebCore does not currently know when >+ ping loads (e.g. beacon loads) complete. This will be addressed via Bug 175443. >+ >+2017-08-14 Chris Dumez <cdumez@apple.com> >+ > XHR should only fire an abort event if the cancellation was requested by the client > https://bugs.webkit.org/show_bug.cgi?id=175546 > >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index 4b189aaa625c48d05a670b369897b6ff4c5018ef..26f1243cf7cc42d47a7cc60b58c312fc3fe47192 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,5 +1,25 @@ > 2017-08-14 Chris Dumez <cdumez@apple.com> > >+ Implement quota limitation for keepalive Fetch requests >+ https://bugs.webkit.org/show_bug.cgi?id=175482 >+ >+ Reviewed by Sam Weinig and Youenn Fablet. >+ >+ * web-platform-tests/fetch/api/basic/scheme-about.any-expected.txt: >+ * web-platform-tests/fetch/api/basic/scheme-about.any.worker-expected.txt: >+ * web-platform-tests/fetch/api/cors/cors-multiple-origins-expected.txt: >+ * web-platform-tests/fetch/api/cors/cors-multiple-origins-worker-expected.txt: >+ * web-platform-tests/fetch/api/cors/cors-preflight-star.any-expected.txt: >+ * web-platform-tests/fetch/api/cors/cors-preflight-star.any.worker-expected.txt: >+ * web-platform-tests/fetch/http-cache/cc-request-expected.txt: >+ Rebaseline tests now that we provide a more helpful error message when rejecting >+ the fetch() promise. >+ >+ * web-platform-tests/fetch/api/request/request-keepalive-quota-expected.txt: >+ Rebaseline test for keepalive Fetch requests quota which is now passing. >+ >+2017-08-14 Chris Dumez <cdumez@apple.com> >+ > XHR should only fire an abort event if the cancellation was requested by the client > https://bugs.webkit.org/show_bug.cgi?id=175546 > >diff --git a/LayoutTests/fast/xmlhttprequest/xmlhttprequest-nonexistent-file-expected.txt b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-nonexistent-file-expected.txt >index f9eee904ae59579f77c8668059aae95edfacb2e2..ec7ecfb69a71f043b00b905024c91fb5f7b447fc 100644 >--- a/LayoutTests/fast/xmlhttprequest/xmlhttprequest-nonexistent-file-expected.txt >+++ b/LayoutTests/fast/xmlhttprequest/xmlhttprequest-nonexistent-file-expected.txt >@@ -1,5 +1,5 @@ > CONSOLE MESSAGE: line 64: Not allowed to load local resource: nonexistent.html >-CONSOLE MESSAGE: line 64: XMLHttpRequest cannot load nonexistent.html due to access control checks. >+CONSOLE MESSAGE: line 64: XMLHttpRequest cannot load nonexistent.html. Not allowed to request resource > > Bug 22475: REGRESSION: Async XMLHttpRequest never finishes on nonexistent files anymore > >diff --git a/LayoutTests/http/tests/contentextensions/async-xhr-onerror-expected.txt b/LayoutTests/http/tests/contentextensions/async-xhr-onerror-expected.txt >index 3f2aa09775ec5168cadb1f356a82a54a9a3c58e3..d40b123a2532153ebaf823851831b0cc1c17a9c1 100644 >--- a/LayoutTests/http/tests/contentextensions/async-xhr-onerror-expected.txt >+++ b/LayoutTests/http/tests/contentextensions/async-xhr-onerror-expected.txt >@@ -1,7 +1,7 @@ > CONSOLE MESSAGE: line 30: Content blocker prevented frame displaying http://127.0.0.1:8000/contentextensions/async-xhr-onerror.html from loading a resource from http://127.0.0.1:8000/contentextensions/resources/url-blocking-test.js >-CONSOLE MESSAGE: line 30: XMLHttpRequest cannot load http://127.0.0.1:8000/contentextensions/resources/url-blocking-test.js due to access control checks. >+CONSOLE MESSAGE: line 30: XMLHttpRequest cannot load http://127.0.0.1:8000/contentextensions/resources/url-blocking-test.js. Resource blocked by content blocker > CONSOLE MESSAGE: line 30: Content blocker prevented frame displaying http://127.0.0.1:8000/contentextensions/async-xhr-onerror.html from loading a resource from http://127.0.0.1:8000/contentextensions/resources/url-blocking-test.js >-CONSOLE MESSAGE: line 30: XMLHttpRequest cannot load http://127.0.0.1:8000/contentextensions/resources/url-blocking-test.js due to access control checks. >+CONSOLE MESSAGE: line 30: XMLHttpRequest cannot load http://127.0.0.1:8000/contentextensions/resources/url-blocking-test.js. Resource blocked by content blocker > Asynchronous onreadystatechange status: 0, readyState:1, responseText: > Finished runTest. Waiting for callbacks > Asynchronous onreadystatechange status: 0, readyState:1, responseText: >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-xhr-asynchronous-in-iframe-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-xhr-asynchronous-in-iframe-expected.txt >index 5d3fbb75cac45548d8cebc665cda23b5faf4a3bb..89516e33917c59e16886e6aa64da91a8c14e4cde 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-xhr-asynchronous-in-iframe-expected.txt >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-xhr-asynchronous-in-iframe-expected.txt >@@ -2,7 +2,7 @@ frame "<!--framePath //<!--frame0-->-->" - didStartProvisionalLoadForFrame > main frame - didFinishDocumentLoadForFrame > frame "<!--framePath //<!--frame0-->-->" - didCommitLoadForFrame > CONSOLE MESSAGE: Blocked mixed content http://127.0.0.1:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi because 'block-all-mixed-content' appears in the Content Security Policy. >-CONSOLE MESSAGE: line 30: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi due to access control checks. >+CONSOLE MESSAGE: line 30: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi. Not allowed to request resource > frame "<!--framePath //<!--frame0-->-->" - didFinishDocumentLoadForFrame > frame "<!--framePath //<!--frame0-->-->" - didHandleOnloadEventsForFrame > main frame - didHandleOnloadEventsForFrame >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-xhr-asynchronous-in-main-frame-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-xhr-asynchronous-in-main-frame-expected.txt >index c8e65e2dae98932c668e9799ddc935dd098d5de7..3f6476f0b9c224f81ca55ac1698df0a002bf0f43 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-xhr-asynchronous-in-main-frame-expected.txt >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-xhr-asynchronous-in-main-frame-expected.txt >@@ -4,7 +4,7 @@ main frame - didHandleOnloadEventsForFrame > main frame - didFinishLoadForFrame > main frame - didCommitLoadForFrame > CONSOLE MESSAGE: Blocked mixed content http://127.0.0.1:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi because 'block-all-mixed-content' appears in the Content Security Policy. >-CONSOLE MESSAGE: line 30: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi due to access control checks. >+CONSOLE MESSAGE: line 30: XMLHttpRequest cannot load http://127.0.0.1:8000/xmlhttprequest/resources/access-control-basic-allow-star.cgi. Not allowed to request resource > main frame - didFinishDocumentLoadForFrame > main frame - didHandleOnloadEventsForFrame > main frame - didFinishLoadForFrame >diff --git a/LayoutTests/http/tests/security/mixedContent/insecure-xhr-in-main-frame-expected.txt b/LayoutTests/http/tests/security/mixedContent/insecure-xhr-in-main-frame-expected.txt >index 7fcfdd1dd1595d4dd62bc144499d7d3002c94cbe..c42e555e343f8c1bc60d13edbb383f4ce6ba86fa 100644 >--- a/LayoutTests/http/tests/security/mixedContent/insecure-xhr-in-main-frame-expected.txt >+++ b/LayoutTests/http/tests/security/mixedContent/insecure-xhr-in-main-frame-expected.txt >@@ -1,4 +1,4 @@ > CONSOLE MESSAGE: line 28: [blocked] The page at https://127.0.0.1:8443/security/mixedContent/resources/insecure-xhr-in-main-frame-window.html was not allowed to display insecure content from http://127.0.0.1:8000/. > >-CONSOLE MESSAGE: line 28: XMLHttpRequest cannot load http://127.0.0.1:8000/ due to access control checks. >+CONSOLE MESSAGE: line 28: XMLHttpRequest cannot load http://127.0.0.1:8000/. Not allowed to request resource > This test opens a HTTPS window that loads insecure data via XHR. We should trigger a mixed content callback because the main frame in the window is HTTPS but now has insecure data. >diff --git a/LayoutTests/http/wpt/beacon/beacon-quota-expected.txt b/LayoutTests/http/wpt/beacon/beacon-quota-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b78c982473bae413de21cc8eb4509a4402f74327 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/beacon-quota-expected.txt >@@ -0,0 +1,5 @@ >+CONSOLE MESSAGE: line 14: Reached maximum amount of queued data of 64Kb for keepalive requests >+ >+PASS Beacon with a body above the Quota Limit should fail. >+FAIL Multiple Beacons Quota Limit assert_false: Second beacon should not be sent because we reached the quota expected false got true >+ >diff --git a/LayoutTests/http/wpt/beacon/beacon-quota.html b/LayoutTests/http/wpt/beacon/beacon-quota.html >new file mode 100644 >index 0000000000000000000000000000000000000000..18e58f83549832d238366fe37123e4335cc62a55 >--- /dev/null >+++ b/LayoutTests/http/wpt/beacon/beacon-quota.html >@@ -0,0 +1,21 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script> >+ // We should expect 64KiB of rolling quota for any type of keep-alive request sent. >+ var expectedQuota = 65536; >+ >+ function createPayload(payloadSize) >+ { >+ return new Blob(["*".repeat(payloadSize)]); >+ } >+ >+ test(function() { >+ assert_false(navigator.sendBeacon("/", createPayload(expectedQuota + 1))); >+ }, "Beacon with a body above the Quota Limit should fail."); >+ >+ test(function() { >+ assert_true(navigator.sendBeacon("/", createPayload(expectedQuota)), "Beacon with a body at the Quota Limit should succeed."); >+ assert_false(navigator.sendBeacon("/", createPayload(1)), "Second beacon should not be sent because we reached the quota"); >+ }, "Multiple Beacons Quota Limit"); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-about.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-about.any-expected.txt >index b608de7367052604421a4f7c08c525679f61429f..c12cfa71ad3c69d757bd102ab2422732cfbde2fa 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-about.any-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-about.any-expected.txt >@@ -5,9 +5,9 @@ CONSOLE MESSAGE: line 27: Fetch API cannot load about:invalid.com. Cross origin > CONSOLE MESSAGE: line 27: Fetch API cannot load about:config. Cross origin requests are only supported for HTTP. > CONSOLE MESSAGE: line 27: Fetch API cannot load about:unicorn. Cross origin requests are only supported for HTTP. > >-FAIL Fetching about:blank (GET) is OK promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL Fetching about:blank (PUT) is OK promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL Fetching about:blank (POST) is OK promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL Fetching about:blank (GET) is OK promise_test: Unhandled rejection with value: object "TypeError: Cross origin requests are only supported for HTTP." >+FAIL Fetching about:blank (PUT) is OK promise_test: Unhandled rejection with value: object "TypeError: Preflight response is not successful" >+FAIL Fetching about:blank (POST) is OK promise_test: Unhandled rejection with value: object "TypeError: Cross origin requests are only supported for HTTP." > PASS Fetching about:invalid.com is KO > PASS Fetching about:config is KO > PASS Fetching about:unicorn is KO >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-about.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-about.any.worker-expected.txt >index 93992602d358f8cf658e1bd144f35cfc5c69ed92..6304a83beba553674372bf2ae8b414b14eab9849 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-about.any.worker-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/basic/scheme-about.any.worker-expected.txt >@@ -1,7 +1,7 @@ > >-FAIL Fetching about:blank (GET) is OK promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL Fetching about:blank (PUT) is OK promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL Fetching about:blank (POST) is OK promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL Fetching about:blank (GET) is OK promise_test: Unhandled rejection with value: object "TypeError: Cross origin requests are only supported for HTTP." >+FAIL Fetching about:blank (PUT) is OK promise_test: Unhandled rejection with value: object "TypeError: Preflight response is not successful" >+FAIL Fetching about:blank (POST) is OK promise_test: Unhandled rejection with value: object "TypeError: Cross origin requests are only supported for HTTP." > PASS Fetching about:invalid.com is KO > PASS Fetching about:config is KO > PASS Fetching about:unicorn is KO >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-multiple-origins-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-multiple-origins-expected.txt >index 49f3ce5e35283454e99e734d39e3917e55324837..8da7aa6959545e34e6472537f8993151048789b5 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-multiple-origins-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-multiple-origins-expected.txt >@@ -11,10 +11,10 @@ CONSOLE MESSAGE: Fetch API cannot load http://localhost:8801/fetch/api/resources > CONSOLE MESSAGE: Access-Control-Allow-Origin cannot contain more than one origin. > CONSOLE MESSAGE: Fetch API cannot load http://localhost:8801/fetch/api/resources/preflight.py?origin=%2C%20http%3A%2F%2Fexample.com%2C%20https%3A%2F%2Fexample2.com. Access-Control-Allow-Origin cannot contain more than one origin. > >-FAIL 3 origins allowed, match the 3rd (http://localhost:8800) promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL 3 origins allowed, match the 3rd ("*") promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL 3 origins allowed, match twice (http://localhost:8800) promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL 3 origins allowed, match twice ("*") promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL 3 origins allowed, match twice ("*" and http://localhost:8800) promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL 3 origins allowed, match the 3rd (http://localhost:8800) promise_test: Unhandled rejection with value: object "TypeError: Access-Control-Allow-Origin cannot contain more than one origin." >+FAIL 3 origins allowed, match the 3rd ("*") promise_test: Unhandled rejection with value: object "TypeError: Access-Control-Allow-Origin cannot contain more than one origin." >+FAIL 3 origins allowed, match twice (http://localhost:8800) promise_test: Unhandled rejection with value: object "TypeError: Access-Control-Allow-Origin cannot contain more than one origin." >+FAIL 3 origins allowed, match twice ("*") promise_test: Unhandled rejection with value: object "TypeError: Access-Control-Allow-Origin cannot contain more than one origin." >+FAIL 3 origins allowed, match twice ("*" and http://localhost:8800) promise_test: Unhandled rejection with value: object "TypeError: Access-Control-Allow-Origin cannot contain more than one origin." > PASS 3 origins allowed, no match > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-multiple-origins-worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-multiple-origins-worker-expected.txt >index 909cc92d31406c38983d4172150deb2b42eb4b26..81037f7a1007fde0f76c9af552304a5bb25f0255 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-multiple-origins-worker-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-multiple-origins-worker-expected.txt >@@ -5,10 +5,10 @@ CONSOLE MESSAGE: Access-Control-Allow-Origin cannot contain more than one origin > CONSOLE MESSAGE: Access-Control-Allow-Origin cannot contain more than one origin. > CONSOLE MESSAGE: Access-Control-Allow-Origin cannot contain more than one origin. > >-FAIL 3 origins allowed, match the 3rd (http://localhost:8800) promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL 3 origins allowed, match the 3rd ("*") promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL 3 origins allowed, match twice (http://localhost:8800) promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL 3 origins allowed, match twice ("*") promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL 3 origins allowed, match twice ("*" and http://localhost:8800) promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL 3 origins allowed, match the 3rd (http://localhost:8800) promise_test: Unhandled rejection with value: object "TypeError: Access-Control-Allow-Origin cannot contain more than one origin." >+FAIL 3 origins allowed, match the 3rd ("*") promise_test: Unhandled rejection with value: object "TypeError: Access-Control-Allow-Origin cannot contain more than one origin." >+FAIL 3 origins allowed, match twice (http://localhost:8800) promise_test: Unhandled rejection with value: object "TypeError: Access-Control-Allow-Origin cannot contain more than one origin." >+FAIL 3 origins allowed, match twice ("*") promise_test: Unhandled rejection with value: object "TypeError: Access-Control-Allow-Origin cannot contain more than one origin." >+FAIL 3 origins allowed, match twice ("*" and http://localhost:8800) promise_test: Unhandled rejection with value: object "TypeError: Access-Control-Allow-Origin cannot contain more than one origin." > PASS 3 origins allowed, no match > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-star.any-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-star.any-expected.txt >index 07a66db2606c19f06dba7f7551898819246e0158..918ef8d07a5ec2cd2dce002c13108f7ae8ccc583 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-star.any-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-star.any-expected.txt >@@ -7,8 +7,8 @@ CONSOLE MESSAGE: Fetch API cannot load http://127.0.0.1:8800/fetch/api/resources > CONSOLE MESSAGE: Fetch API cannot load http://127.0.0.1:8800/fetch/api/resources/preflight.py?origin=http://localhost:8800&credentials&allow_methods=*&allow_headers=*&. Request header field X-Test is not allowed by Access-Control-Allow-Headers. > > PASS CORS that succeeds with credentials: false; method: GET (allowed: get); header: X-Test,1 (allowed: x-test) >-FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Method SUPER is not allowed by Access-Control-Allow-Methods." >+FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Method OK is not allowed by Access-Control-Allow-Methods." > PASS CORS that fails with credentials: true; method: OK (allowed: *); header: X-Test,1 (allowed: *) > PASS CORS that fails with credentials: true; method: PUT (allowed: *); header: undefined (allowed: ) > PASS CORS that fails with credentials: true; method: PUT (allowed: put); header: undefined (allowed: *) >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-star.any.worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-star.any.worker-expected.txt >index ae4cf83e342dfc65f89a53eb3022836cd8a1446a..82cf622f39a78e8f8983ed51907c958339430b60 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-star.any.worker-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/cors/cors-preflight-star.any.worker-expected.txt >@@ -1,7 +1,7 @@ > > PASS CORS that succeeds with credentials: false; method: GET (allowed: get); header: X-Test,1 (allowed: x-test) >-FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL CORS that succeeds with credentials: false; method: SUPER (allowed: *); header: X-Test,1 (allowed: x-test) promise_test: Unhandled rejection with value: object "TypeError: Method SUPER is not allowed by Access-Control-Allow-Methods." >+FAIL CORS that succeeds with credentials: false; method: OK (allowed: *); header: X-Test,1 (allowed: *) promise_test: Unhandled rejection with value: object "TypeError: Method OK is not allowed by Access-Control-Allow-Methods." > PASS CORS that fails with credentials: true; method: OK (allowed: *); header: X-Test,1 (allowed: *) > PASS CORS that fails with credentials: true; method: PUT (allowed: *); header: undefined (allowed: ) > PASS CORS that fails with credentials: true; method: PUT (allowed: put); header: undefined (allowed: *) >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-count-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-count-expected.txt >index 1edddcebb194bb7bff057b7cd09774f40fc9c9ae..8a3ce19440d23f516f1684c0ea613ce8e3054c45 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-count-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-count-expected.txt >@@ -1,12 +1,12 @@ > >-FAIL Redirect 301 20 times promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL Redirect 301 20 times promise_test: Unhandled rejection with value: object "TypeError: too many HTTP redirects" > PASS Redirect 301 21 times >-FAIL Redirect 302 20 times promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL Redirect 302 20 times promise_test: Unhandled rejection with value: object "TypeError: too many HTTP redirects" > PASS Redirect 302 21 times >-FAIL Redirect 303 20 times promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL Redirect 303 20 times promise_test: Unhandled rejection with value: object "TypeError: too many HTTP redirects" > PASS Redirect 303 21 times >-FAIL Redirect 307 20 times promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL Redirect 307 20 times promise_test: Unhandled rejection with value: object "TypeError: too many HTTP redirects" > PASS Redirect 307 21 times >-FAIL Redirect 308 20 times promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL Redirect 308 20 times promise_test: Unhandled rejection with value: object "TypeError: too many HTTP redirects" > PASS Redirect 308 21 times > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-count-worker-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-count-worker-expected.txt >index 1edddcebb194bb7bff057b7cd09774f40fc9c9ae..8a3ce19440d23f516f1684c0ea613ce8e3054c45 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-count-worker-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/redirect/redirect-count-worker-expected.txt >@@ -1,12 +1,12 @@ > >-FAIL Redirect 301 20 times promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL Redirect 301 20 times promise_test: Unhandled rejection with value: object "TypeError: too many HTTP redirects" > PASS Redirect 301 21 times >-FAIL Redirect 302 20 times promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL Redirect 302 20 times promise_test: Unhandled rejection with value: object "TypeError: too many HTTP redirects" > PASS Redirect 302 21 times >-FAIL Redirect 303 20 times promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL Redirect 303 20 times promise_test: Unhandled rejection with value: object "TypeError: too many HTTP redirects" > PASS Redirect 303 21 times >-FAIL Redirect 307 20 times promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL Redirect 307 20 times promise_test: Unhandled rejection with value: object "TypeError: too many HTTP redirects" > PASS Redirect 307 21 times >-FAIL Redirect 308 20 times promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL Redirect 308 20 times promise_test: Unhandled rejection with value: object "TypeError: too many HTTP redirects" > PASS Redirect 308 21 times > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-keepalive-quota-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-keepalive-quota-expected.txt >index 6b52eb7a46c0c276638c3796033f455463927d1d..f5e5efdb20c9cf55124f4ce4f5c0a386d3df34d2 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-keepalive-quota-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/api/request/request-keepalive-quota-expected.txt >@@ -1,8 +1,14 @@ >+CONSOLE MESSAGE: line 44: Fetch API cannot load http://localhost:8800/fetch/api/resources/trickle.py?count=1&ms=0. Reached maximum amount of queued data of 64Kb for keepalive requests >+CONSOLE MESSAGE: line 71: Fetch API cannot load http://localhost:8800/fetch/api/resources/trickle.py?count=1&ms=0. Reached maximum amount of queued data of 64Kb for keepalive requests >+CONSOLE MESSAGE: Unhandled Promise Rejection: TypeError: Reached maximum amount of queued data of 64Kb for keepalive requests >+CONSOLE MESSAGE: line 88: Fetch API cannot load http://localhost:8800/fetch/api/resources/trickle.py?count=1&ms=0. Reached maximum amount of queued data of 64Kb for keepalive requests >+ >+Harness Error (FAIL), message = Reached maximum amount of queued data of 64Kb for keepalive requests > > PASS A Keep-Alive fetch() with a small body should succeed. > PASS A Keep-Alive fetch() with a body at the Quota Limit should succeed. >-FAIL A Keep-Alive fetch() with a body over the Quota Limit should reject. assert_unreached: Should have rejected: undefined Reached unreachable code >+PASS A Keep-Alive fetch() with a body over the Quota Limit should reject. > PASS A Keep-Alive fetch() should return it's allocated Quota upon promise resolution. > PASS A Keep-Alive fetch() should return only it's allocated Quota upon promise resolution. >-FAIL A Keep-Alive fetch() should not be allowed if the Quota is used up. assert_unreached: Should have rejected: undefined Reached unreachable code >+PASS A Keep-Alive fetch() should not be allowed if the Quota is used up. > >diff --git a/LayoutTests/imported/w3c/web-platform-tests/fetch/http-cache/cc-request-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/fetch/http-cache/cc-request-expected.txt >index d5f23f91581efe5966b833be13fb7ea41597e9ec..9c1ea17235eeebc77a8efca1731a51201de3f98d 100644 >--- a/LayoutTests/imported/w3c/web-platform-tests/fetch/http-cache/cc-request-expected.txt >+++ b/LayoutTests/imported/w3c/web-platform-tests/fetch/http-cache/cc-request-expected.txt >@@ -10,5 +10,5 @@ PASS HTTP cache doesn't reuse fresh response when request contains Cache-Control > PASS HTTP cache validates fresh response with Last-Modified when request contains Cache-Control: no-cache. > PASS HTTP cache validates fresh response with ETag when request contains Cache-Control: no-cache. > FAIL HTTP cache doesn't reuse fresh response when request contains Cache-Control: no-store. assert_equals: Response used expected 2 but got 1 >-FAIL HTTP cache generates 504 status code when nothing is in cache and request contains Cache-Control: only-if-cached. promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL HTTP cache generates 504 status code when nothing is in cache and request contains Cache-Control: only-if-cached. promise_test: Unhandled rejection with value: object "TypeError: canât load from network" > >diff --git a/LayoutTests/inspector/worker/resources-in-worker-expected.txt b/LayoutTests/inspector/worker/resources-in-worker-expected.txt >index d143763760a28019ce50e2b332d731a96803aea2..d4207d173378dff5841a9cf86191759032ff904d 100644 >--- a/LayoutTests/inspector/worker/resources-in-worker-expected.txt >+++ b/LayoutTests/inspector/worker/resources-in-worker-expected.txt >@@ -1,4 +1,4 @@ >-CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: Type error >+CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: The requested URL was not found on this server. > Test for Resources in a Worker. > > >diff --git a/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/fetch/api/request/request-cache-only-if-cached-expected.txt b/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/fetch/api/request/request-cache-only-if-cached-expected.txt >index 86f646b0104edaab49310a592b2be330f70eb408..56ae0db573dc2e0175a7ba04928677b22cf3c511 100644 >--- a/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/fetch/api/request/request-cache-only-if-cached-expected.txt >+++ b/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/fetch/api/request/request-cache-only-if-cached-expected.txt >@@ -5,10 +5,10 @@ PASS RequestCache "only-if-cached" mode checks the cache for previously cached c > PASS RequestCache "only-if-cached" mode checks the cache for previously cached content and avoids revalidation for fresh responses with Last-Modified and fresh response > PASS RequestCache "only-if-cached" mode checks the cache for previously cached content and does not go to the network if a cached response is not found with Etag and fresh response > PASS RequestCache "only-if-cached" mode checks the cache for previously cached content and does not go to the network if a cached response is not found with Last-Modified and fresh response >-FAIL RequestCache "only-if-cached" (with "same-origin") uses cached same-origin redirects to same-origin content with Etag and fresh response promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL RequestCache "only-if-cached" (with "same-origin") uses cached same-origin redirects to same-origin content with Last-Modified and fresh response promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL RequestCache "only-if-cached" (with "same-origin") uses cached same-origin redirects to same-origin content with Etag and stale response promise_test: Unhandled rejection with value: object "TypeError: Type error" >-FAIL RequestCache "only-if-cached" (with "same-origin") uses cached same-origin redirects to same-origin content with Last-Modified and stale response promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL RequestCache "only-if-cached" (with "same-origin") uses cached same-origin redirects to same-origin content with Etag and fresh response promise_test: Unhandled rejection with value: object "TypeError: resource unavailable" >+FAIL RequestCache "only-if-cached" (with "same-origin") uses cached same-origin redirects to same-origin content with Last-Modified and fresh response promise_test: Unhandled rejection with value: object "TypeError: resource unavailable" >+FAIL RequestCache "only-if-cached" (with "same-origin") uses cached same-origin redirects to same-origin content with Etag and stale response promise_test: Unhandled rejection with value: object "TypeError: resource unavailable" >+FAIL RequestCache "only-if-cached" (with "same-origin") uses cached same-origin redirects to same-origin content with Last-Modified and stale response promise_test: Unhandled rejection with value: object "TypeError: resource unavailable" > PASS RequestCache "only-if-cached" (with "same-origin") does not follow redirects across origins and rejects with Etag and fresh response > PASS RequestCache "only-if-cached" (with "same-origin") does not follow redirects across origins and rejects with Last-Modified and fresh response > PASS RequestCache "only-if-cached" (with "same-origin") does not follow redirects across origins and rejects with Etag and stale response >diff --git a/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/fetch/http-cache/cc-request-expected.txt b/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/fetch/http-cache/cc-request-expected.txt >index 74534ee25fc8ed1c9961fbdf582b9bba1f14121d..6db5c3d09b548cce57536adc1e41c279b1fcc3ca 100644 >--- a/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/fetch/http-cache/cc-request-expected.txt >+++ b/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/fetch/http-cache/cc-request-expected.txt >@@ -10,5 +10,5 @@ PASS HTTP cache doesn't reuse fresh response when request contains Cache-Control > PASS HTTP cache validates fresh response with Last-Modified when request contains Cache-Control: no-cache. > PASS HTTP cache validates fresh response with ETag when request contains Cache-Control: no-cache. > PASS HTTP cache doesn't reuse fresh response when request contains Cache-Control: no-store. >-FAIL HTTP cache generates 504 status code when nothing is in cache and request contains Cache-Control: only-if-cached. promise_test: Unhandled rejection with value: object "TypeError: Type error" >+FAIL HTTP cache generates 504 status code when nothing is in cache and request contains Cache-Control: only-if-cached. promise_test: Unhandled rejection with value: object "TypeError: canât load from network" >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 175482
:
317939
|
317941
|
317951
|
317955
|
317961
|
317965
|
317968
|
317971
|
317976
|
317984
|
317985
|
318048
|
318051
|
318058
|
318065
|
318068
|
318073
|
318097
|
318110
|
318131