Changeset 201924 in webkit
- Timestamp:
- Jun 10, 2016 6:26:30 AM (8 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/CMakeLists.txt
r201898 r201924 1901 1901 loader/CookieJar.cpp 1902 1902 loader/CrossOriginAccessControl.cpp 1903 loader/CrossOriginPreflightChecker.cpp 1903 1904 loader/CrossOriginPreflightResultCache.cpp 1904 1905 loader/DocumentLoadTiming.cpp -
trunk/Source/WebCore/ChangeLog
r201920 r201924 1 2016-06-10 Youenn Fablet <youenn.fablet@crf.canon.fr> 2 3 Move preflight check code outside of DocumentThreadableLoader 4 https://bugs.webkit.org/show_bug.cgi?id=158425 5 6 Reviewed by Darin Adler. 7 8 Moving preflight check code in its own class. 9 This allows code to be easier to read, use/reuse and update. 10 11 Behavior should be the same as before except in the case of a preflight response 12 being a 3XX redirect response. 13 Before this patch, the 3XX response was directly passed to the code processing regular responses. 14 To keep compatibility with existing tests, a didFailRedirectCheck callback is called. 15 This should be change to a preflight failure. 16 17 Covered by existing tests. 18 19 * CMakeLists.txt: 20 * WebCore.xcodeproj/project.pbxproj: 21 * loader/CrossOriginPreflightChecker.cpp: Added. 22 (WebCore::CrossOriginPreflightChecker::CrossOriginPreflightChecker): 23 (WebCore::CrossOriginPreflightChecker::~CrossOriginPreflightChecker): 24 (WebCore::CrossOriginPreflightChecker::handleLoadingFailure): 25 (WebCore::CrossOriginPreflightChecker::validatePreflightResponse): 26 (WebCore::CrossOriginPreflightChecker::notifyFinished): 27 (WebCore::CrossOriginPreflightChecker::startPreflight): 28 (WebCore::CrossOriginPreflightChecker::doPreflight): 29 (WebCore::CrossOriginPreflightChecker::redirectReceived): 30 (WebCore::CrossOriginPreflightChecker::setDefersLoading): 31 (WebCore::CrossOriginPreflightChecker::isXMLHttpRequest): 32 * loader/CrossOriginPreflightChecker.h: Added. 33 * loader/DocumentThreadableLoader.cpp: 34 (WebCore::DocumentThreadableLoader::create): 35 (WebCore::DocumentThreadableLoader::makeCrossOriginAccessRequest): 36 (WebCore::DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight): 37 (WebCore::DocumentThreadableLoader::setDefersLoading): 38 (WebCore::DocumentThreadableLoader::clearResource): 39 (WebCore::DocumentThreadableLoader::didReceiveResponse): 40 (WebCore::DocumentThreadableLoader::didReceiveData): 41 (WebCore::DocumentThreadableLoader::notifyFinished): 42 (WebCore::DocumentThreadableLoader::didFinishLoading): 43 (WebCore::DocumentThreadableLoader::didFail): 44 (WebCore::DocumentThreadableLoader::preflightSuccess): 45 (WebCore::DocumentThreadableLoader::preflightFailure): 46 (WebCore::DocumentThreadableLoader::loadRequest): 47 (WebCore::DocumentThreadableLoader::responseReceived): Deleted. 48 (WebCore::DocumentThreadableLoader::dataReceived): Deleted. 49 (WebCore::DocumentThreadableLoader::isAllowedByContentSecurityPolicy): Deleted. 50 * loader/DocumentThreadableLoader.h: 51 (WebCore::DocumentThreadableLoader::options): 52 (WebCore::DocumentThreadableLoader::isLoading): 53 (WebCore::DocumentThreadableLoader::document): 54 1 55 2016-06-10 Adam Bergkvist <adam.bergkvist@ericsson.com> 2 56 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r201898 r201924 1570 1570 41A3D58E101C152D00316D07 /* DedicatedWorkerThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41A3D58C101C152D00316D07 /* DedicatedWorkerThread.cpp */; }; 1571 1571 41A3D58F101C152D00316D07 /* DedicatedWorkerThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 41A3D58D101C152D00316D07 /* DedicatedWorkerThread.h */; }; 1572 41ABE67B1D0580DB006D862D /* CrossOriginPreflightChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 41ABE67A1D0580D5006D862D /* CrossOriginPreflightChecker.h */; }; 1573 41ABE67C1D0580E0006D862D /* CrossOriginPreflightChecker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41ABE6791D0580D5006D862D /* CrossOriginPreflightChecker.cpp */; }; 1572 1574 41AD753A1CEF6BD100A31486 /* FetchOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 41AD75391CEF6BCE00A31486 /* FetchOptions.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1573 1575 41BF700C0FE86F49005E8DEC /* MessagePortChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 41BF700A0FE86F49005E8DEC /* MessagePortChannel.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 9084 9086 41A3D58C101C152D00316D07 /* DedicatedWorkerThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DedicatedWorkerThread.cpp; sourceTree = "<group>"; }; 9085 9087 41A3D58D101C152D00316D07 /* DedicatedWorkerThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DedicatedWorkerThread.h; sourceTree = "<group>"; }; 9088 41ABE6791D0580D5006D862D /* CrossOriginPreflightChecker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CrossOriginPreflightChecker.cpp; sourceTree = "<group>"; }; 9089 41ABE67A1D0580D5006D862D /* CrossOriginPreflightChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossOriginPreflightChecker.h; sourceTree = "<group>"; }; 9086 9090 41AD75391CEF6BCE00A31486 /* FetchOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FetchOptions.h; sourceTree = "<group>"; }; 9087 9091 41BF700A0FE86F49005E8DEC /* MessagePortChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessagePortChannel.h; sourceTree = "<group>"; }; … … 22761 22765 E1C416160F6563180092D2FB /* CrossOriginAccessControl.cpp */, 22762 22766 E1C416110F6562FD0092D2FB /* CrossOriginAccessControl.h */, 22767 41ABE6791D0580D5006D862D /* CrossOriginPreflightChecker.cpp */, 22768 41ABE67A1D0580D5006D862D /* CrossOriginPreflightChecker.h */, 22763 22769 E1C415DD0F655D7C0092D2FB /* CrossOriginPreflightResultCache.cpp */, 22764 22770 E1C415D90F655D6F0092D2FB /* CrossOriginPreflightResultCache.h */, … … 25599 25605 26A807851B18F97700E219BE /* DFACombiner.h in Headers */, 25600 25606 26A517FE1AB92238006335DF /* DFAMinimizer.h in Headers */, 25607 41ABE67B1D0580DB006D862D /* CrossOriginPreflightChecker.h in Headers */, 25601 25608 267725FF1A5B3AD9003C24DD /* DFANode.h in Headers */, 25602 25609 CD19A2681A13E700008D650E /* DiagnosticLoggingClient.h in Headers */, … … 29703 29710 BC1A37BF097C715F0019F3D8 /* DOMUtility.mm in Sources */, 29704 29711 15C770A5100D41CD005BA267 /* DOMValidityState.mm in Sources */, 29712 41ABE67C1D0580E0006D862D /* CrossOriginPreflightChecker.cpp in Sources */, 29705 29713 31C0FF4A0E4CEFDD007D6FE5 /* DOMWebKitAnimationEvent.mm in Sources */, 29706 29714 3106037A143281CD00ABF4BA /* DOMWebKitCSSFilterValue.mm in Sources */, -
trunk/Source/WebCore/loader/DocumentThreadableLoader.cpp
r201856 r201924 38 38 #include "ContentSecurityPolicy.h" 39 39 #include "CrossOriginAccessControl.h" 40 #include "CrossOriginPreflightChecker.h" 40 41 #include "CrossOriginPreflightResultCache.h" 41 42 #include "Document.h" … … 71 72 { 72 73 RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, client, LoadAsynchronously, request, options, WTFMove(contentSecurityPolicy))); 73 if (!loader-> m_resource)74 if (!loader->isLoading()) 74 75 loader = nullptr; 75 76 return loader; … … 112 113 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); 113 114 114 auto crossOriginRequest = std::make_unique<ResourceRequest>(request);115 updateRequestForAccessControl( *crossOriginRequest, securityOrigin(), m_options.allowCredentials());116 117 if ((m_options.preflightPolicy == ConsiderPreflight && isSimpleCrossOriginAccessRequest(crossOriginRequest ->httpMethod(), crossOriginRequest->httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight)118 makeSimpleCrossOriginAccessRequest( *crossOriginRequest);115 auto crossOriginRequest = request; 116 updateRequestForAccessControl(crossOriginRequest, securityOrigin(), m_options.allowCredentials()); 117 118 if ((m_options.preflightPolicy == ConsiderPreflight && isSimpleCrossOriginAccessRequest(crossOriginRequest.httpMethod(), crossOriginRequest.httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight) 119 makeSimpleCrossOriginAccessRequest(crossOriginRequest); 119 120 else { 120 121 m_simpleRequest = false; 121 m_actualRequest = WTFMove(crossOriginRequest); 122 123 if (CrossOriginPreflightResultCache::singleton().canSkipPreflight(securityOrigin()->toString(), m_actualRequest->url(), m_options.allowCredentials(), m_actualRequest->httpMethod(), m_actualRequest->httpHeaderFields())) 124 preflightSuccess(); 122 if (CrossOriginPreflightResultCache::singleton().canSkipPreflight(securityOrigin()->toString(), crossOriginRequest.url(), m_options.allowCredentials(), crossOriginRequest.httpMethod(), crossOriginRequest.httpHeaderFields())) 123 preflightSuccess(WTFMove(crossOriginRequest)); 125 124 else 126 makeCrossOriginAccessRequestWithPreflight( *m_actualRequest);125 makeCrossOriginAccessRequestWithPreflight(WTFMove(crossOriginRequest)); 127 126 } 128 127 } … … 142 141 } 143 142 144 void DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight(const ResourceRequest& request) 145 { 146 ResourceRequest preflightRequest = createAccessControlPreflightRequest(request, securityOrigin()); 147 loadRequest(preflightRequest, DoSecurityCheck); 143 void DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight(ResourceRequest&& request) 144 { 145 if (m_async) { 146 m_preflightChecker = CrossOriginPreflightChecker(*this, WTFMove(request)); 147 m_preflightChecker->startPreflight(); 148 return; 149 } 150 CrossOriginPreflightChecker::doPreflight(*this, WTFMove(request)); 148 151 } 149 152 … … 172 175 if (m_resource) 173 176 m_resource->setDefersLoading(value); 177 if (m_preflightChecker) 178 m_preflightChecker->setDefersLoading(value); 174 179 } 175 180 … … 184 189 resource->removeClient(this); 185 190 } 191 if (m_preflightChecker) 192 m_preflightChecker = Nullopt; 186 193 } 187 194 … … 261 268 262 269 String accessControlErrorDescription; 263 if (m_actualRequest) { 264 DocumentLoader* loader = m_document.frame()->loader().documentLoader(); 265 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceResponse(m_document.frame()); 266 InspectorInstrumentation::didReceiveResourceResponse(cookie, identifier, loader, response, 0); 267 270 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == UseAccessControl) { 268 271 if (!passesAccessControlCheck(response, m_options.allowCredentials(), securityOrigin(), accessControlErrorDescription)) { 269 preflightFailure(identifier, response.url(), accessControlErrorDescription);272 m_client->didFailAccessControlCheck(ResourceError(errorDomainWebKitInternal, 0, response.url(), accessControlErrorDescription)); 270 273 return; 271 274 } 272 273 StoredCredentials allowCredentials = m_options.allowCredentials(); 274 auto preflightResult = std::make_unique<CrossOriginPreflightResultCacheItem>(allowCredentials); 275 if (!preflightResult->parse(response, accessControlErrorDescription) 276 || !preflightResult->allowsCrossOriginMethod(m_actualRequest->httpMethod(), accessControlErrorDescription) 277 || !preflightResult->allowsCrossOriginHeaders(m_actualRequest->httpHeaderFields(), accessControlErrorDescription)) { 278 preflightFailure(identifier, response.url(), accessControlErrorDescription); 279 return; 280 } 281 282 CrossOriginPreflightResultCache::singleton().appendEntry(securityOrigin()->toString(), m_actualRequest->url(), WTFMove(preflightResult)); 283 } else { 284 if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == UseAccessControl) { 285 if (!passesAccessControlCheck(response, m_options.allowCredentials(), securityOrigin(), accessControlErrorDescription)) { 286 m_client->didFailAccessControlCheck(ResourceError(errorDomainWebKitInternal, 0, response.url(), accessControlErrorDescription)); 287 return; 288 } 289 } 290 291 m_client->didReceiveResponse(identifier, response); 292 } 275 } 276 277 m_client->didReceiveResponse(identifier, response); 293 278 } 294 279 … … 299 284 } 300 285 301 void DocumentThreadableLoader::didReceiveData(unsigned long identifier, const char* data, int dataLength) 302 { 303 ASSERT(m_client); 304 305 // Preflight data should be invisible to clients. 306 if (m_actualRequest) { 307 InspectorInstrumentation::didReceiveData(m_document.frame(), identifier, 0, 0, dataLength); 308 return; 309 } 286 void DocumentThreadableLoader::didReceiveData(unsigned long, const char* data, int dataLength) 287 { 288 ASSERT(m_client); 310 289 311 290 m_client->didReceiveData(data, dataLength); … … 316 295 ASSERT(m_client); 317 296 ASSERT_UNUSED(resource, resource == m_resource); 318 297 319 298 if (m_resource->errorOccurred()) 320 299 didFail(m_resource->identifier(), m_resource->resourceError()); … … 325 304 void DocumentThreadableLoader::didFinishLoading(unsigned long identifier, double finishTime) 326 305 { 327 if (m_actualRequest) { 328 InspectorInstrumentation::didFinishLoading(m_document.frame(), m_document.frame()->loader().documentLoader(), identifier, finishTime); 329 330 ASSERT(!m_sameOriginRequest); 331 ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); 332 preflightSuccess(); 333 } else 334 m_client->didFinishLoading(identifier, finishTime); 335 } 336 337 void DocumentThreadableLoader::didFail(unsigned long identifier, const ResourceError& error) 338 { 339 if (m_actualRequest) 340 InspectorInstrumentation::didFailLoading(m_document.frame(), m_document.frame()->loader().documentLoader(), identifier, error); 341 306 ASSERT(m_client); 307 m_client->didFinishLoading(identifier, finishTime); 308 } 309 310 void DocumentThreadableLoader::didFail(unsigned long, const ResourceError& error) 311 { 312 ASSERT(m_client); 342 313 m_client->didFail(error); 343 314 } 344 315 345 void DocumentThreadableLoader::preflightSuccess() 346 { 347 std::unique_ptr<ResourceRequest> actualRequest; 348 actualRequest.swap(m_actualRequest); 349 350 actualRequest->setHTTPOrigin(securityOrigin()->toString()); 351 352 clearResource(); 316 void DocumentThreadableLoader::preflightSuccess(ResourceRequest&& request) 317 { 318 ResourceRequest actualRequest(WTFMove(request)); 319 actualRequest.setHTTPOrigin(securityOrigin()->toString()); 320 321 m_preflightChecker = Nullopt; 353 322 354 323 // It should be ok to skip the security check since we already asked about the preflight request. 355 loadRequest( *actualRequest, SkipSecurityCheck);356 } 357 358 void DocumentThreadableLoader::preflightFailure(unsigned long identifier, const URL& url, const String& errorDescription)359 { 360 ResourceError error(errorDomainWebKitInternal, 0, url, errorDescription);361 if (m_actualRequest) 362 363 364 m_actualRequest = nullptr; // Prevent didFinishLoading() from bypassing access check.324 loadRequest(actualRequest, SkipSecurityCheck); 325 } 326 327 void DocumentThreadableLoader::preflightFailure(unsigned long identifier, const ResourceError& error) 328 { 329 m_preflightChecker = Nullopt; 330 331 InspectorInstrumentation::didFailLoading(m_document.frame(), m_document.frame()->loader().documentLoader(), identifier, error); 332 333 ASSERT(m_client); 365 334 m_client->didFailAccessControlCheck(error); 366 335 } … … 377 346 ThreadableLoaderOptions options = m_options; 378 347 options.setClientCredentialPolicy(DoNotAskClientForCrossOriginCredentials); 379 if (m_actualRequest) {380 // Don't sniff content or send load callbacks for the preflight request.381 options.setSendLoadCallbacks(DoNotSendCallbacks);382 options.setSniffContent(DoNotSniffContent);383 // Keep buffering the data for the preflight request.384 options.setDataBufferingPolicy(BufferData);385 }386 348 387 349 CachedResourceRequest newRequest(request, options); … … 395 357 return; 396 358 } 397 359 398 360 // FIXME: ThreadableLoaderOptions.sniffContent is not supported for synchronous requests. 399 361 RefPtr<SharedBuffer> data; -
trunk/Source/WebCore/loader/DocumentThreadableLoader.h
r201414 r201924 32 32 #define DocumentThreadableLoader_h 33 33 34 #include "CachedRawResourceClient.h" 35 #include "CachedResourceHandle.h" 34 #include "CrossOriginPreflightChecker.h" 36 35 #include "ThreadableLoader.h" 37 36 … … 40 39 class ContentSecurityPolicy; 41 40 class Document; 42 class URL;43 class ResourceRequest;44 41 class SecurityOrigin; 45 42 class ThreadableLoaderClient; … … 58 55 void cancel() override; 59 56 virtual void setDefersLoading(bool); 57 58 friend CrossOriginPreflightChecker; 60 59 61 60 using RefCounted<DocumentThreadableLoader>::ref; … … 88 87 void didFail(unsigned long identifier, const ResourceError&); 89 88 void makeCrossOriginAccessRequest(const ResourceRequest&); 90 void makeSimpleCrossOriginAccessRequest(const ResourceRequest& request);91 void makeCrossOriginAccessRequestWithPreflight( const ResourceRequest& request);92 void preflightSuccess( );93 void preflightFailure(unsigned long identifier, const URL&, const String& errorDescription);89 void makeSimpleCrossOriginAccessRequest(const ResourceRequest&); 90 void makeCrossOriginAccessRequestWithPreflight(ResourceRequest&&); 91 void preflightSuccess(ResourceRequest&&); 92 void preflightFailure(unsigned long identifier, const ResourceError&); 94 93 95 94 void loadRequest(const ResourceRequest&, SecurityCheckPolicy); … … 102 101 const ContentSecurityPolicy& contentSecurityPolicy() const; 103 102 103 Document& document() { return m_document; } 104 const ThreadableLoaderOptions& options() const { return m_options; } 105 bool isLoading() { return m_resource || m_preflightChecker; } 106 104 107 CachedResourceHandle<CachedRawResource> m_resource; 105 108 ThreadableLoaderClient* m_client; … … 109 112 bool m_simpleRequest; 110 113 bool m_async; 111 std::unique_ptr<ResourceRequest> m_actualRequest; // non-null during Access Control preflight checks112 114 std::unique_ptr<ContentSecurityPolicy> m_contentSecurityPolicy; 115 Optional<CrossOriginPreflightChecker> m_preflightChecker; 113 116 }; 114 117
Note: See TracChangeset
for help on using the changeset viewer.