Diff
Modified: trunk/Source/WebCore/ChangeLog (239131 => 239132)
--- trunk/Source/WebCore/ChangeLog 2018-12-12 23:42:24 UTC (rev 239131)
+++ trunk/Source/WebCore/ChangeLog 2018-12-12 23:57:10 UTC (rev 239132)
@@ -1,3 +1,19 @@
+2018-12-12 Vivek Seth <[email protected]>
+
+ HTTPS Upgrade: Figure out if/how to tell clients that the HTTPS upgrade happened
+ https://bugs.webkit.org/show_bug.cgi?id=192375
+ <rdar://problem/45851159>
+
+ Reviewed by Chris Dumez.
+
+ Use simulated redirect to tell clients that HTTPS Upgrade happened.
+
+ * platform/network/ResourceResponseBase.cpp:
+ (WebCore::ResourceResponseBase::syntheticRedirectResponse):
+ * platform/network/ResourceResponseBase.h:
+ * platform/network/mac/WebCoreURLResponse.mm:
+ (WebCore::synthesizeRedirectResponseIfNecessary):
+
2018-12-12 Chris Dumez <[email protected]>
Add a preference to enable / disable devicemotion and deviceorientation events
Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp (239131 => 239132)
--- trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp 2018-12-12 23:42:24 UTC (rev 239131)
+++ trunk/Source/WebCore/platform/network/ResourceResponseBase.cpp 2018-12-12 23:57:10 UTC (rev 239132)
@@ -120,6 +120,18 @@
return response;
}
+ResourceResponse ResourceResponseBase::syntheticRedirectResponse(const URL& fromURL, const URL& toURL)
+{
+ ResourceResponse redirectResponse;
+ redirectResponse.setURL(fromURL);
+ redirectResponse.setHTTPStatusCode(302);
+ redirectResponse.setHTTPVersion("HTTP/1.1"_s);
+ redirectResponse.setHTTPHeaderField(HTTPHeaderName::Location, toURL.string());
+ redirectResponse.setHTTPHeaderField(HTTPHeaderName::CacheControl, "no-store"_s);
+
+ return redirectResponse;
+}
+
ResourceResponse ResourceResponseBase::filter(const ResourceResponse& response)
{
if (response.tainting() == Tainting::Opaque) {
Modified: trunk/Source/WebCore/platform/network/ResourceResponseBase.h (239131 => 239132)
--- trunk/Source/WebCore/platform/network/ResourceResponseBase.h 2018-12-12 23:42:24 UTC (rev 239131)
+++ trunk/Source/WebCore/platform/network/ResourceResponseBase.h 2018-12-12 23:57:10 UTC (rev 239132)
@@ -173,6 +173,8 @@
static ResourceResponse filter(const ResourceResponse&);
+ WEBCORE_EXPORT static ResourceResponse syntheticRedirectResponse(const URL& fromURL, const URL& toURL);
+
static bool compare(const ResourceResponse&, const ResourceResponse&);
template<class Encoder> void encode(Encoder&) const;
Modified: trunk/Source/WebCore/platform/network/mac/WebCoreURLResponse.mm (239131 => 239132)
--- trunk/Source/WebCore/platform/network/mac/WebCoreURLResponse.mm 2018-12-12 23:42:24 UTC (rev 239131)
+++ trunk/Source/WebCore/platform/network/mac/WebCoreURLResponse.mm 2018-12-12 23:57:10 UTC (rev 239132)
@@ -347,10 +347,7 @@
if ([[[newRequest URL] scheme] isEqualToString:[[currentRequest URL] scheme]] && !schemeWasUpgradedDueToDynamicHSTS(newRequest))
return nil;
- // If the new request is a different protocol than the current request, synthesize a redirect response.
- // This is critical for HSTS (<rdar://problem/14241270>).
- NSDictionary *synthesizedResponseHeaderFields = @{ @"Location": [[newRequest URL] absoluteString], @"Cache-Control": @"no-store" };
- return [[[NSHTTPURLResponse alloc] initWithURL:[currentRequest URL] statusCode:302 HTTPVersion:(NSString *)kCFHTTPVersion1_1 headerFields:synthesizedResponseHeaderFields] autorelease];
+ return [[ResourceResponse::syntheticRedirectResponse(URL([currentRequest URL]), URL([newRequest URL])).nsURLResponse() retain] autorelease];
}
}
Modified: trunk/Source/WebKit/ChangeLog (239131 => 239132)
--- trunk/Source/WebKit/ChangeLog 2018-12-12 23:42:24 UTC (rev 239131)
+++ trunk/Source/WebKit/ChangeLog 2018-12-12 23:57:10 UTC (rev 239132)
@@ -1,3 +1,27 @@
+2018-12-12 Vivek Seth <[email protected]>
+
+ HTTPS Upgrade: Figure out if/how to tell clients that the HTTPS upgrade happened
+ https://bugs.webkit.org/show_bug.cgi?id=192375
+ <rdar://problem/45851159>
+
+ Reviewed by Chris Dumez.
+
+ Use simulated redirect to tell clients that HTTPS Upgrade happened.
+
+ * NetworkProcess/NetworkLoadChecker.cpp:
+ (WebKit::NetworkLoadChecker::NetworkLoadChecker):
+ (WebKit::NetworkLoadChecker::checkRedirection):
+ (WebKit::NetworkLoadChecker::accessControlErrorForValidationHandler):
+ (WebKit::NetworkLoadChecker::applyHTTPSUpgradeIfNeeded const):
+ (WebKit::NetworkLoadChecker::checkRequest):
+ (WebKit::NetworkLoadChecker::continueCheckingRequestOrDoSyntheticRedirect):
+ (WebKit::NetworkLoadChecker::checkCORSRequestWithPreflight):
+ (WebKit::NetworkLoadChecker::applyHTTPSUpgradeIfNeeded): Deleted.
+ * NetworkProcess/NetworkLoadChecker.h:
+ * NetworkProcess/NetworkResourceLoader.cpp:
+ (WebKit::NetworkResourceLoader::start):
+ * NetworkProcess/PingLoad.cpp:
+
2018-12-12 Ross Kirsling <[email protected]>
Unreviewed fix for Cocoa Debug test instability following r239129.
Modified: trunk/Source/WebKit/NetworkProcess/NetworkLoadChecker.cpp (239131 => 239132)
--- trunk/Source/WebKit/NetworkProcess/NetworkLoadChecker.cpp 2018-12-12 23:42:24 UTC (rev 239131)
+++ trunk/Source/WebKit/NetworkProcess/NetworkLoadChecker.cpp 2018-12-12 23:57:10 UTC (rev 239132)
@@ -45,7 +45,7 @@
return url.protocolIsData() || url.protocolIsBlob() || !origin || origin->canRequest(url);
}
-NetworkLoadChecker::NetworkLoadChecker(FetchOptions&& options, PAL::SessionID sessionID, uint64_t pageID, uint64_t frameID, HTTPHeaderMap&& originalRequestHeaders, URL&& url, RefPtr<SecurityOrigin>&& sourceOrigin, PreflightPolicy preflightPolicy, String&& referrer, bool shouldCaptureExtraNetworkLoadMetrics)
+NetworkLoadChecker::NetworkLoadChecker(FetchOptions&& options, PAL::SessionID sessionID, uint64_t pageID, uint64_t frameID, HTTPHeaderMap&& originalRequestHeaders, URL&& url, RefPtr<SecurityOrigin>&& sourceOrigin, PreflightPolicy preflightPolicy, String&& referrer, bool shouldCaptureExtraNetworkLoadMetrics, LoadType requestLoadType)
: m_options(WTFMove(options))
, m_sessionID(sessionID)
, m_pageID(pageID)
@@ -56,6 +56,7 @@
, m_preflightPolicy(preflightPolicy)
, m_referrer(WTFMove(referrer))
, m_shouldCaptureExtraNetworkLoadMetrics(shouldCaptureExtraNetworkLoadMetrics)
+ , m_requestLoadType(requestLoadType)
{
m_isSameOriginRequest = isSameOrigin(m_url, m_origin.get());
switch (options.credentials) {
@@ -132,11 +133,18 @@
m_url = redirectRequest.url();
checkRequest(WTFMove(redirectRequest), client, [handler = WTFMove(handler), request = WTFMove(request), redirectResponse = WTFMove(redirectResponse)](auto&& result) mutable {
- if (!result.has_value()) {
- handler(makeUnexpected(WTFMove(result.error())));
- return;
- }
- handler(RedirectionTriplet { WTFMove(request), WTFMove(result.value()), WTFMove(redirectResponse) });
+ WTF::switchOn(result,
+ [&handler] (ResourceError& error) mutable {
+ handler(makeUnexpected(WTFMove(error)));
+ },
+ [&handler, &request, &redirectResponse] (RedirectionTriplet& triplet) mutable {
+ // FIXME: if checkRequest returns a RedirectionTriplet, it means the requested URL has changed and we should update the redirectResponse to match.
+ handler(RedirectionTriplet { WTFMove(request), WTFMove(triplet.redirectRequest), WTFMove(redirectResponse) });
+ },
+ [&handler, &request, &redirectResponse] (ResourceRequest& redirectRequest) mutable {
+ handler(RedirectionTriplet { WTFMove(request), WTFMove(redirectRequest), WTFMove(redirectResponse) });
+ }
+ );
});
}
@@ -177,14 +185,17 @@
return { };
}
-auto NetworkLoadChecker::accessControlErrorForValidationHandler(String&& message) -> RequestOrError
+auto NetworkLoadChecker::accessControlErrorForValidationHandler(String&& message) -> RequestOrRedirectionTripletOrError
{
- return makeUnexpected(ResourceError { String { }, 0, m_url, WTFMove(message), ResourceError::Type::AccessControl });
+ return ResourceError { String { }, 0, m_url, WTFMove(message), ResourceError::Type::AccessControl };
}
#if ENABLE(HTTPS_UPGRADE)
-bool NetworkLoadChecker::applyHTTPSUpgradeIfNeeded(ResourceRequest& request)
+void NetworkLoadChecker::applyHTTPSUpgradeIfNeeded(ResourceRequest& request) const
{
+ if (m_requestLoadType != LoadType::MainFrame)
+ return;
+
// Use dummy list for now.
static NeverDestroyed<HashSet<String>> upgradableHosts = std::initializer_list<String> {
"www.bbc.com"_s, // (source: https://whynohttps.com)
@@ -196,29 +207,25 @@
// Only upgrade http urls.
if (!url.protocolIs("http"))
- return false;
+ return;
if (!upgradableHosts.get().contains(url.host().toString()))
- return false;
+ return;
auto newURL = url;
newURL.setProtocol("https"_s);
request.setURL(newURL);
- return true;
- return false;
+ RELEASE_LOG_IF_ALLOWED("applyHTTPSUpgradeIfNeeded - Upgrade URL from HTTP to HTTPS");
}
#endif // ENABLE(HTTPS_UPGRADE)
void NetworkLoadChecker::checkRequest(ResourceRequest&& request, ContentSecurityPolicyClient* client, ValidationHandler&& handler)
{
+ ResourceRequest originalRequest = request;
#if ENABLE(HTTPS_UPGRADE)
- if (request.requester() == ResourceRequest::Requester::Main) {
- if (applyHTTPSUpgradeIfNeeded(request))
- ASSERT(request.url().protocolIs("https"));
- }
-
+ applyHTTPSUpgradeIfNeeded(request);
#endif // ENABLE(HTTPS_UPGRADE)
if (auto* contentSecurityPolicy = this->contentSecurityPolicy()) {
@@ -233,10 +240,10 @@
}
#if ENABLE(CONTENT_EXTENSIONS)
- processContentExtensionRulesForLoad(WTFMove(request), [this, handler = WTFMove(handler)](auto result) mutable {
+ processContentExtensionRulesForLoad(WTFMove(request), [this, handler = WTFMove(handler), originalRequest = WTFMove(originalRequest)](auto result) mutable {
if (!result.has_value()) {
ASSERT(result.error().isCancellation());
- handler(makeUnexpected(WTFMove(result.error())));
+ handler(WTFMove(result.error()));
return;
}
if (result.value().status.blockedLoad) {
@@ -243,13 +250,25 @@
handler(this->accessControlErrorForValidationHandler("Blocked by content extension"_s));
return;
}
- this->continueCheckingRequest(WTFMove(result.value().request), WTFMove(handler));
+
+ continueCheckingRequestOrDoSyntheticRedirect(WTFMove(originalRequest), WTFMove(result.value().request), WTFMove(handler));
});
#else
- continueCheckingRequest(WTFMove(request), WTFMove(handler));
+ continueCheckingRequestOrDoSyntheticRedirect(WTFMove(originalRequest), WTFMove(request), WTFMove(handler));
#endif
}
+void NetworkLoadChecker::continueCheckingRequestOrDoSyntheticRedirect(ResourceRequest&& originalRequest, ResourceRequest&& currentRequest, ValidationHandler&& handler)
+{
+ // If main frame load and request has been modified, trigger a synthetic redirect.
+ if (m_requestLoadType == LoadType::MainFrame && currentRequest.url() != originalRequest.url()) {
+ ResourceResponse redirectResponse = ResourceResponse::syntheticRedirectResponse(originalRequest.url(), currentRequest.url());
+ handler(RedirectionTriplet { WTFMove(originalRequest), WTFMove(currentRequest), WTFMove(redirectResponse) });
+ return;
+ }
+ this->continueCheckingRequest(WTFMove(currentRequest), WTFMove(handler));
+}
+
bool NetworkLoadChecker::isAllowedByContentSecurityPolicy(const ResourceRequest& request, WebCore::ContentSecurityPolicyClient* client)
{
auto* contentSecurityPolicy = this->contentSecurityPolicy();
@@ -394,7 +413,7 @@
RELEASE_LOG_IF_ALLOWED("checkCORSRequestWithPreflight - makeCrossOriginAccessRequestWithPreflight preflight complete, success: %d forRedirect? %d", error.isNull(), isRedirected);
if (!error.isNull()) {
- handler(makeUnexpected(WTFMove(error)));
+ handler(WTFMove(error));
return;
}
Modified: trunk/Source/WebKit/NetworkProcess/NetworkLoadChecker.h (239131 => 239132)
--- trunk/Source/WebKit/NetworkProcess/NetworkLoadChecker.h 2018-12-12 23:42:24 UTC (rev 239131)
+++ trunk/Source/WebKit/NetworkProcess/NetworkLoadChecker.h 2018-12-12 23:57:10 UTC (rev 239132)
@@ -30,6 +30,7 @@
#include <WebCore/ResourceError.h>
#include <wtf/CompletionHandler.h>
#include <wtf/Expected.h>
+#include <wtf/Variant.h>
namespace WebCore {
class ContentSecurityPolicy;
@@ -42,18 +43,21 @@
class NetworkLoadChecker : public CanMakeWeakPtr<NetworkLoadChecker> {
public:
- NetworkLoadChecker(WebCore::FetchOptions&&, PAL::SessionID, uint64_t pageID, uint64_t frameID, WebCore::HTTPHeaderMap&&, URL&&, RefPtr<WebCore::SecurityOrigin>&&, WebCore::PreflightPolicy, String&& referrer, bool shouldCaptureExtraNetworkLoadMetrics = false);
+ enum class LoadType : bool { MainFrame, Other };
+
+ NetworkLoadChecker(WebCore::FetchOptions&&, PAL::SessionID, uint64_t pageID, uint64_t frameID, WebCore::HTTPHeaderMap&&, URL&&, RefPtr<WebCore::SecurityOrigin>&&, WebCore::PreflightPolicy, String&& referrer, bool shouldCaptureExtraNetworkLoadMetrics = false, LoadType requestLoadType = LoadType::Other);
~NetworkLoadChecker();
- using RequestOrError = Expected<WebCore::ResourceRequest, WebCore::ResourceError>;
- using ValidationHandler = CompletionHandler<void(RequestOrError&&)>;
- void check(WebCore::ResourceRequest&&, WebCore::ContentSecurityPolicyClient*, ValidationHandler&&);
-
struct RedirectionTriplet {
WebCore::ResourceRequest request;
WebCore::ResourceRequest redirectRequest;
WebCore::ResourceResponse redirectResponse;
};
+
+ using RequestOrRedirectionTripletOrError = Variant<WebCore::ResourceRequest, RedirectionTriplet, WebCore::ResourceError>;
+ using ValidationHandler = CompletionHandler<void(RequestOrRedirectionTripletOrError&&)>;
+ void check(WebCore::ResourceRequest&&, WebCore::ContentSecurityPolicyClient*, ValidationHandler&&);
+
using RedirectionRequestOrError = Expected<RedirectionTriplet, WebCore::ResourceError>;
using RedirectionValidationHandler = CompletionHandler<void(RedirectionRequestOrError&&)>;
void checkRedirection(WebCore::ResourceRequest&& request, WebCore::ResourceRequest&& redirectRequest, WebCore::ResourceResponse&& redirectResponse, WebCore::ContentSecurityPolicyClient*, RedirectionValidationHandler&&);
@@ -89,6 +93,7 @@
bool isAllowedByContentSecurityPolicy(const WebCore::ResourceRequest&, WebCore::ContentSecurityPolicyClient*);
void continueCheckingRequest(WebCore::ResourceRequest&&, ValidationHandler&&);
+ void continueCheckingRequestOrDoSyntheticRedirect(WebCore::ResourceRequest&& originalRequest, WebCore::ResourceRequest&& currentRequest, ValidationHandler&&);
bool doesNotNeedCORSCheck(const URL&) const;
void checkCORSRequest(WebCore::ResourceRequest&&, ValidationHandler&&);
@@ -95,7 +100,7 @@
void checkCORSRedirectedRequest(WebCore::ResourceRequest&&, ValidationHandler&&);
void checkCORSRequestWithPreflight(WebCore::ResourceRequest&&, ValidationHandler&&);
- RequestOrError accessControlErrorForValidationHandler(String&&);
+ RequestOrRedirectionTripletOrError accessControlErrorForValidationHandler(String&&);
#if ENABLE(CONTENT_EXTENSIONS)
struct ContentExtensionResult {
@@ -106,6 +111,11 @@
using ContentExtensionCallback = CompletionHandler<void(ContentExtensionResultOrError)>;
void processContentExtensionRulesForLoad(WebCore::ResourceRequest&&, ContentExtensionCallback&&);
#endif
+
+#if ENABLE(HTTPS_UPGRADE)
+ void applyHTTPSUpgradeIfNeeded(WebCore::ResourceRequest&) const;
+#endif // ENABLE(HTTPS_UPGRADE)
+
WebCore::FetchOptions m_options;
WebCore::StoredCredentialsPolicy m_storedCredentialsPolicy;
PAL::SessionID m_sessionID;
@@ -134,10 +144,7 @@
bool m_shouldCaptureExtraNetworkLoadMetrics { false };
WebCore::NetworkLoadInformation m_loadInformation;
-#if ENABLE(HTTPS_UPGRADE)
- static bool applyHTTPSUpgradeIfNeeded(WebCore::ResourceRequest&);
-#endif // ENABLE(HTTPS_UPGRADE)
-
+ LoadType m_requestLoadType;
};
}
Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp (239131 => 239132)
--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp 2018-12-12 23:42:24 UTC (rev 239131)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp 2018-12-12 23:57:10 UTC (rev 239132)
@@ -111,7 +111,8 @@
}
if (synchronousReply || parameters.shouldRestrictHTTPResponseAccess) {
- m_networkLoadChecker = std::make_unique<NetworkLoadChecker>(FetchOptions { m_parameters.options }, m_parameters.sessionID, m_parameters.webPageID, m_parameters.webFrameID, HTTPHeaderMap { m_parameters.originalRequestHeaders }, URL { m_parameters.request.url() }, m_parameters.sourceOrigin.copyRef(), m_parameters.preflightPolicy, originalRequest().httpReferrer(), shouldCaptureExtraNetworkLoadMetrics());
+ NetworkLoadChecker::LoadType requestLoadType = isMainFrameLoad() ? NetworkLoadChecker::LoadType::MainFrame : NetworkLoadChecker::LoadType::Other;
+ m_networkLoadChecker = std::make_unique<NetworkLoadChecker>(FetchOptions { m_parameters.options }, m_parameters.sessionID, m_parameters.webPageID, m_parameters.webFrameID, HTTPHeaderMap { m_parameters.originalRequestHeaders }, URL { m_parameters.request.url() }, m_parameters.sourceOrigin.copyRef(), m_parameters.preflightPolicy, originalRequest().httpReferrer(), shouldCaptureExtraNetworkLoadMetrics(), requestLoadType);
if (m_parameters.cspResponseHeaders)
m_networkLoadChecker->setCSPResponseHeaders(ContentSecurityPolicyResponseHeaders { m_parameters.cspResponseHeaders.value() });
#if ENABLE(CONTENT_EXTENSIONS)
@@ -179,20 +180,26 @@
if (m_networkLoadChecker) {
m_networkLoadChecker->check(ResourceRequest { originalRequest() }, this, [this] (auto&& result) {
- if (!result.has_value()) {
- if (!result.error().isCancellation())
- this->didFailLoading(result.error());
- return;
- }
+ WTF::switchOn(result,
+ [this] (ResourceError& error) {
+ if (!error.isCancellation())
+ this->didFailLoading(error);
+ },
+ [this] (NetworkLoadChecker::RedirectionTriplet& triplet) {
+ this->m_isWaitingContinueWillSendRequestForCachedRedirect = true;
+ this->willSendRedirectedRequest(WTFMove(triplet.request), WTFMove(triplet.redirectRequest), WTFMove(triplet.redirectResponse));
+ RELEASE_LOG_IF_ALLOWED("NetworkResourceLoader: synthetic redirect sent because request URL was modified.");
+ },
+ [this] (ResourceRequest& request) {
+ if (this->canUseCache(request)) {
+ RELEASE_LOG_IF_ALLOWED("start: Checking cache for resource (pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ", isMainResource = %d, isSynchronous = %d)", m_parameters.webPageID, m_parameters.webFrameID, m_parameters.identifier, this->isMainResource(), this->isSynchronous());
+ this->retrieveCacheEntry(request);
+ return;
+ }
- auto currentRequest = result.value();
- if (this->canUseCache(currentRequest)) {
- RELEASE_LOG_IF_ALLOWED("start: Checking cache for resource (pageID = %" PRIu64 ", frameID = %" PRIu64 ", resourceID = %" PRIu64 ", isMainResource = %d, isSynchronous = %d)", m_parameters.webPageID, m_parameters.webFrameID, m_parameters.identifier, this->isMainResource(), this->isSynchronous());
- this->retrieveCacheEntry(currentRequest);
- return;
- }
-
- this->startNetworkLoad(WTFMove(result.value()), FirstLoad::Yes);
+ this->startNetworkLoad(WTFMove(request), FirstLoad::Yes);
+ }
+ );
});
return;
}
Modified: trunk/Source/WebKit/NetworkProcess/PingLoad.cpp (239131 => 239132)
--- trunk/Source/WebKit/NetworkProcess/PingLoad.cpp 2018-12-12 23:42:24 UTC (rev 239131)
+++ trunk/Source/WebKit/NetworkProcess/PingLoad.cpp 2018-12-12 23:57:10 UTC (rev 239132)
@@ -57,11 +57,18 @@
m_timeoutTimer.startOneShot(60000_s);
m_networkLoadChecker->check(ResourceRequest { m_parameters.request }, nullptr, [this] (auto&& result) {
- if (!result.has_value()) {
- this->didFinish(result.error());
- return;
- }
- this->loadRequest(WTFMove(result.value()));
+ WTF::switchOn(result,
+ [this] (ResourceError& error) {
+ this->didFinish(error);
+ },
+ [] (NetworkLoadChecker::RedirectionTriplet& triplet) {
+ // We should never send a synthetic redirect for PingLoads.
+ ASSERT_NOT_REACHED();
+ },
+ [this] (ResourceRequest& request) {
+ this->loadRequest(WTFMove(request));
+ }
+ );
});
}