Diff
Modified: trunk/LayoutTests/ChangeLog (227338 => 227339)
--- trunk/LayoutTests/ChangeLog 2018-01-22 18:24:15 UTC (rev 227338)
+++ trunk/LayoutTests/ChangeLog 2018-01-22 18:33:30 UTC (rev 227339)
@@ -1,3 +1,13 @@
+2018-01-22 Youenn Fablet <you...@apple.com>
+
+ Fetch Headers from an Opaque response should be filtered out
+ https://bugs.webkit.org/show_bug.cgi?id=181926
+
+ Reviewed by Chris Dumez.
+
+ * http/wpt/fetch/response-opaque-clone-expected.txt:
+ * http/wpt/fetch/response-opaque-clone.html:
+
2018-01-22 Andy Estes <aes...@apple.com>
LayoutTest http/tests/paymentrequest/payment-request-abort-method.https.html is a flaky failure
Modified: trunk/LayoutTests/http/wpt/fetch/response-opaque-clone-expected.txt (227338 => 227339)
--- trunk/LayoutTests/http/wpt/fetch/response-opaque-clone-expected.txt 2018-01-22 18:24:15 UTC (rev 227338)
+++ trunk/LayoutTests/http/wpt/fetch/response-opaque-clone-expected.txt 2018-01-22 18:33:30 UTC (rev 227339)
@@ -1,3 +1,3 @@
-PASS Check opaque response can be cloned
+PASS Check opaque response can be cloned and cached correctly
Modified: trunk/LayoutTests/http/wpt/fetch/response-opaque-clone.html (227338 => 227339)
--- trunk/LayoutTests/http/wpt/fetch/response-opaque-clone.html 2018-01-22 18:24:15 UTC (rev 227338)
+++ trunk/LayoutTests/http/wpt/fetch/response-opaque-clone.html 2018-01-22 18:33:30 UTC (rev 227339)
@@ -10,16 +10,42 @@
<body>
<script src=""
<script>
-promise_test(function(test) {
- return fetch(get_host_info().HTTP_REMOTE_ORIGIN, { mode: "no-cors" }).then((response) => {
- var clone = response.clone();
- assert_equals(response.body, null, "opaque response body should be null");
- assert_equals(clone.body, null, "clone body should be null");
- return clone.arrayBuffer();
- }).then((buffer) => {
- assert_equals(buffer.byteLength, 0, "cloned opaque response buffer should be null");
- });
-}, "Check opaque response can be cloned");
+
+function testResponseOpacity(response, test, testName)
+{
+ assert_equals(response.type, "opaque", testName + " type");
+ assert_equals(response.status, 0, testName + " status");
+ assert_equals(response.statusText, "", testName + " statusText");
+ assert_false(response.redirected, testName + " redirected");
+ assert_true(response.headers.values().next().done, testName + " headers");
+ assert_equals(response.body, null, testName + " opaque response body should be null");
+}
+promise_test(async function(test) {
+ var request = new Request(get_host_info().HTTP_REMOTE_ORIGIN, { mode: "no-cors" });
+ var response = await fetch(request);
+
+ testResponseOpacity(response, test, "fetched response");
+
+ var clone = response.clone();
+
+ testResponseOpacity(clone, test, "cloned response");
+ var buffer = await clone.arrayBuffer();
+ assert_equals(buffer.byteLength, 0, "cloned opaque response buffer should be null");
+
+ // WK1 does not support Cache API yet.
+ if (!self.caches)
+ return;
+
+ var cache = await self.caches.open("test");
+ await cache.put(request, response);
+ var cached = await cache.match(request.url);
+
+ testResponseOpacity(cached, test, "cached response")
+ buffer = await cached.arrayBuffer();
+ assert_equals(buffer.byteLength, 0, "cached opaque response buffer should be null");
+
+ await self.caches.delete("test");
+}, "Check opaque response can be cloned and cached correctly");
</script>
</body>
</html>
Modified: trunk/Source/WebCore/ChangeLog (227338 => 227339)
--- trunk/Source/WebCore/ChangeLog 2018-01-22 18:24:15 UTC (rev 227338)
+++ trunk/Source/WebCore/ChangeLog 2018-01-22 18:33:30 UTC (rev 227339)
@@ -1,3 +1,31 @@
+2018-01-22 Youenn Fablet <you...@apple.com>
+
+ Fetch Headers from an Opaque response should be filtered out
+ https://bugs.webkit.org/show_bug.cgi?id=181926
+
+ Reviewed by Chris Dumez.
+
+ Covered by updated test.
+
+ Refactor to use the same FetchResponse::create for Cache API and cloning.
+ In this method, ensure that response and headers are filtered correctly according response tainting.
+ Make also sure that synthetic responses do not get filtered (not needed since created by _javascript_).
+
+ Introduce helper routine to set the header map of a resource response.
+ Use this routine when cloning a synthetic response as in that case, m_internalResponse has no header at all.
+
+ * Modules/cache/DOMCache.cpp:
+ (WebCore::DOMCache::updateRecords):
+ * Modules/fetch/FetchResponse.cpp:
+ (WebCore::FetchResponse::create):
+ (WebCore::FetchResponse::clone):
+ * Modules/fetch/FetchResponse.h:
+ * platform/network/ResourceResponseBase.cpp:
+ (WebCore::ResourceResponseBase::setHTTPHeaderFields):
+ * platform/network/ResourceResponseBase.h:
+ * testing/ServiceWorkerInternals.cpp:
+ (WebCore::ServiceWorkerInternals::createOpaqueWithBlobBodyResponse):
+
2018-01-22 Javier Fernandez <jfernan...@igalia.com>
[css-align] 'overflow' keyword must precede the self-position and content-position value
Modified: trunk/Source/WebCore/Modules/cache/DOMCache.cpp (227338 => 227339)
--- trunk/Source/WebCore/Modules/cache/DOMCache.cpp 2018-01-22 18:24:15 UTC (rev 227338)
+++ trunk/Source/WebCore/Modules/cache/DOMCache.cpp 2018-01-22 18:33:30 UTC (rev 227339)
@@ -531,8 +531,7 @@
if (index != notFound) {
auto& current = m_records[index];
if (current.updateResponseCounter != record.updateResponseCounter) {
- auto responseHeaders = FetchHeaders::create(record.responseHeadersGuard, HTTPHeaderMap { record.response.httpHeaderFields() });
- auto response = FetchResponse::create(*scriptExecutionContext(), std::nullopt, WTFMove(responseHeaders), WTFMove(record.response));
+ auto response = FetchResponse::create(*scriptExecutionContext(), std::nullopt, record.responseHeadersGuard, WTFMove(record.response));
response->setBodyData(WTFMove(record.responseBody), record.responseBodySize);
current.response = WTFMove(response);
@@ -543,8 +542,7 @@
auto requestHeaders = FetchHeaders::create(record.requestHeadersGuard, HTTPHeaderMap { record.request.httpHeaderFields() });
auto request = FetchRequest::create(*scriptExecutionContext(), std::nullopt, WTFMove(requestHeaders), WTFMove(record.request), WTFMove(record.options), WTFMove(record.referrer));
- auto responseHeaders = FetchHeaders::create(record.responseHeadersGuard, HTTPHeaderMap { record.response.httpHeaderFields() });
- auto response = FetchResponse::create(*scriptExecutionContext(), std::nullopt, WTFMove(responseHeaders), WTFMove(record.response));
+ auto response = FetchResponse::create(*scriptExecutionContext(), std::nullopt, record.responseHeadersGuard, WTFMove(record.response));
response->setBodyData(WTFMove(record.responseBody), record.responseBodySize);
newRecords.append(CacheStorageRecord { record.identifier, record.updateResponseCounter, WTFMove(request), WTFMove(response) });
Modified: trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp (227338 => 227339)
--- trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp 2018-01-22 18:24:15 UTC (rev 227338)
+++ trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp 2018-01-22 18:33:30 UTC (rev 227339)
@@ -44,10 +44,17 @@
return status == 101 || status == 204 || status == 205 || status == 304;
}
-Ref<FetchResponse> FetchResponse::create(ScriptExecutionContext& context, std::optional<FetchBody>&& body, Ref<FetchHeaders>&& headers, ResourceResponse&& response)
+Ref<FetchResponse> FetchResponse::create(ScriptExecutionContext& context, std::optional<FetchBody>&& body, FetchHeaders::Guard guard, ResourceResponse&& response)
{
+ bool isSynthetic = response.type() == ResourceResponse::Type::Default || response.type() == ResourceResponse::Type::Error;
+ bool isOpaque = response.tainting() == ResourceResponse::Tainting::Opaque;
+ auto headers = isOpaque ? FetchHeaders::create(guard) : FetchHeaders::create(guard, HTTPHeaderMap { response.httpHeaderFields() });
+
auto fetchResponse = adoptRef(*new FetchResponse(context, WTFMove(body), WTFMove(headers), WTFMove(response)));
- fetchResponse->m_filteredResponse = ResourceResponseBase::filter(fetchResponse->m_internalResponse);
+ if (!isSynthetic)
+ fetchResponse->m_filteredResponse = ResourceResponseBase::filter(fetchResponse->m_internalResponse);
+ if (isOpaque)
+ fetchResponse->setBodyAsOpaque();
return fetchResponse;
}
@@ -163,10 +170,12 @@
if (isLoading())
readableStream(*context.execState());
- auto clone = adoptRef(*new FetchResponse(context, std::nullopt, FetchHeaders::create(headers()), ResourceResponse(m_internalResponse)));
+ // Synthetic responses do not store headers in m_internalResponse.
+ if (m_internalResponse.type() == ResourceResponse::Type::Default)
+ m_internalResponse.setHTTPHeaderFields(HTTPHeaderMap { headers().internalHeaders() });
+
+ auto clone = FetchResponse::create(context, std::nullopt, headers().guard(), ResourceResponse { m_internalResponse });
clone->cloneBody(*this);
- if (isBodyOpaque())
- clone->setBodyAsOpaque();
clone->m_opaqueLoadIdentifier = m_opaqueLoadIdentifier;
clone->m_bodySizeWithPadding = m_bodySizeWithPadding;
return WTFMove(clone);
Modified: trunk/Source/WebCore/Modules/fetch/FetchResponse.h (227338 => 227339)
--- trunk/Source/WebCore/Modules/fetch/FetchResponse.h 2018-01-22 18:24:15 UTC (rev 227338)
+++ trunk/Source/WebCore/Modules/fetch/FetchResponse.h 2018-01-22 18:33:30 UTC (rev 227339)
@@ -53,7 +53,7 @@
std::optional<FetchHeaders::Init> headers;
};
- WEBCORE_EXPORT static Ref<FetchResponse> create(ScriptExecutionContext&, std::optional<FetchBody>&&, Ref<FetchHeaders>&&, ResourceResponse&&);
+ WEBCORE_EXPORT static Ref<FetchResponse> create(ScriptExecutionContext&, std::optional<FetchBody>&&, FetchHeaders::Guard, ResourceResponse&&);
static ExceptionOr<Ref<FetchResponse>> create(ScriptExecutionContext&, std::optional<FetchBody::Init>&&, Init&&);
static Ref<FetchResponse> error(ScriptExecutionContext&);
Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp (227338 => 227339)
--- trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp 2018-01-22 18:24:15 UTC (rev 227338)
+++ trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp 2018-01-22 18:33:30 UTC (rev 227339)
@@ -399,6 +399,13 @@
// FIXME: Should invalidate or update platform response if present.
}
+void ResourceResponseBase::setHTTPHeaderFields(HTTPHeaderMap&& headerFields)
+{
+ lazyInit(AllFields);
+
+ m_httpHeaderFields = WTFMove(headerFields);
+}
+
void ResourceResponseBase::setHTTPHeaderField(HTTPHeaderName name, const String& value)
{
lazyInit(AllFields);
Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.h (227338 => 227339)
--- trunk/Source/WebCore/platform/network/ResourceResponseBase.h 2018-01-22 18:24:15 UTC (rev 227338)
+++ trunk/Source/WebCore/platform/network/ResourceResponseBase.h 2018-01-22 18:33:30 UTC (rev 227339)
@@ -101,6 +101,7 @@
WEBCORE_EXPORT bool isHTTP09() const;
WEBCORE_EXPORT const HTTPHeaderMap& httpHeaderFields() const;
+ void setHTTPHeaderFields(HTTPHeaderMap&&);
String httpHeaderField(const String& name) const;
WEBCORE_EXPORT String httpHeaderField(HTTPHeaderName) const;
Modified: trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp (227338 => 227339)
--- trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp 2018-01-22 18:24:15 UTC (rev 227338)
+++ trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp 2018-01-22 18:33:30 UTC (rev 227339)
@@ -75,7 +75,7 @@
ResourceResponse response;
response.setType(ResourceResponse::Type::Cors);
response.setTainting(ResourceResponse::Tainting::Opaque);
- auto fetchResponse = FetchResponse::create(context, FetchBody::fromFormData(formData), FetchHeaders::create(), WTFMove(response));
+ auto fetchResponse = FetchResponse::create(context, FetchBody::fromFormData(formData), FetchHeaders::Guard::Response, WTFMove(response));
fetchResponse->initializeOpaqueLoadIdentifierForTesting();
return fetchResponse;
}