| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "modules/fetch/FetchManager.h" | 5 #include "modules/fetch/FetchManager.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ExceptionState.h" | 7 #include "bindings/core/v8/ExceptionState.h" |
| 8 #include "bindings/core/v8/ScriptPromiseResolver.h" | 8 #include "bindings/core/v8/ScriptPromiseResolver.h" |
| 9 #include "bindings/core/v8/ScriptState.h" | 9 #include "bindings/core/v8/ScriptState.h" |
| 10 #include "bindings/core/v8/V8ThrowException.h" | 10 #include "bindings/core/v8/V8ThrowException.h" |
| 11 #include "core/dom/DOMArrayBuffer.h" | 11 #include "core/dom/DOMArrayBuffer.h" |
| 12 #include "core/dom/Document.h" | 12 #include "core/dom/Document.h" |
| 13 #include "core/fetch/FetchUtils.h" | 13 #include "core/fetch/FetchUtils.h" |
| 14 #include "core/fileapi/Blob.h" | 14 #include "core/fileapi/Blob.h" |
| 15 #include "core/frame/Frame.h" | 15 #include "core/frame/Frame.h" |
| 16 #include "core/frame/SubresourceIntegrity.h" | 16 #include "core/frame/SubresourceIntegrity.h" |
| 17 #include "core/frame/csp/ContentSecurityPolicy.h" | 17 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 18 #include "core/inspector/ConsoleMessage.h" | 18 #include "core/inspector/ConsoleMessage.h" |
| 19 #include "core/inspector/InspectorInstrumentation.h" | 19 #include "core/inspector/InspectorInstrumentation.h" |
| 20 #include "core/loader/ThreadableLoader.h" | 20 #include "core/loader/ThreadableLoader.h" |
| 21 #include "core/loader/ThreadableLoaderClient.h" | 21 #include "core/loader/ThreadableLoaderClient.h" |
| 22 #include "core/page/ChromeClient.h" | 22 #include "core/page/ChromeClient.h" |
| 23 #include "core/page/Page.h" | 23 #include "core/page/Page.h" |
| 24 #include "modules/fetch/Body.h" | 24 #include "modules/fetch/Body.h" |
| 25 #include "modules/fetch/BodyStreamBuffer.h" | 25 #include "modules/fetch/BodyStreamBuffer.h" |
| 26 #include "modules/fetch/CompositeDataConsumerHandle.h" | 26 #include "modules/fetch/BytesConsumer.h" |
| 27 #include "modules/fetch/BytesConsumerForDataConsumerHandle.h" |
| 27 #include "modules/fetch/DataConsumerHandleUtil.h" | 28 #include "modules/fetch/DataConsumerHandleUtil.h" |
| 28 #include "modules/fetch/FetchFormDataConsumerHandle.h" | |
| 29 #include "modules/fetch/FetchRequestData.h" | 29 #include "modules/fetch/FetchRequestData.h" |
| 30 #include "modules/fetch/FormDataBytesConsumer.h" |
| 30 #include "modules/fetch/Response.h" | 31 #include "modules/fetch/Response.h" |
| 31 #include "modules/fetch/ResponseInit.h" | 32 #include "modules/fetch/ResponseInit.h" |
| 32 #include "platform/HTTPNames.h" | 33 #include "platform/HTTPNames.h" |
| 33 #include "platform/network/ResourceError.h" | 34 #include "platform/network/ResourceError.h" |
| 34 #include "platform/network/ResourceRequest.h" | 35 #include "platform/network/ResourceRequest.h" |
| 35 #include "platform/network/ResourceResponse.h" | 36 #include "platform/network/ResourceResponse.h" |
| 36 #include "platform/weborigin/SchemeRegistry.h" | 37 #include "platform/weborigin/SchemeRegistry.h" |
| 37 #include "platform/weborigin/SecurityOrigin.h" | 38 #include "platform/weborigin/SecurityOrigin.h" |
| 38 #include "platform/weborigin/SecurityPolicy.h" | 39 #include "platform/weborigin/SecurityPolicy.h" |
| 39 #include "public/platform/WebURLRequest.h" | 40 #include "public/platform/WebURLRequest.h" |
| 40 #include "wtf/HashSet.h" | 41 #include "wtf/HashSet.h" |
| 41 #include "wtf/Vector.h" | 42 #include "wtf/Vector.h" |
| 42 #include "wtf/text/WTFString.h" | 43 #include "wtf/text/WTFString.h" |
| 43 #include <memory> | 44 #include <memory> |
| 44 | 45 |
| 45 namespace blink { | 46 namespace blink { |
| 46 | 47 |
| 47 namespace { | 48 namespace { |
| 48 | 49 |
| 49 bool IsRedirectStatusCode(int statusCode) | 50 bool IsRedirectStatusCode(int statusCode) |
| 50 { | 51 { |
| 51 return (statusCode == 301 || statusCode == 302 || statusCode == 303 || statu
sCode == 307 || statusCode == 308); | 52 return (statusCode == 301 || statusCode == 302 || statusCode == 303 || statu
sCode == 307 || statusCode == 308); |
| 52 } | 53 } |
| 53 | 54 |
| 55 class SRIBytesConsumer final : public BytesConsumer { |
| 56 public: |
| 57 // BytesConsumer implementation |
| 58 Result beginRead(const char** buffer, size_t* available) override |
| 59 { |
| 60 if (!m_underlying) { |
| 61 *buffer = nullptr; |
| 62 *available = 0; |
| 63 return m_isCancelled ? Result::Done : Result::ShouldWait; |
| 64 } |
| 65 return m_underlying->beginRead(buffer, available); |
| 66 } |
| 67 Result endRead(size_t readSize) override |
| 68 { |
| 69 DCHECK(m_underlying); |
| 70 return m_underlying->endRead(readSize); |
| 71 } |
| 72 PassRefPtr<BlobDataHandle> drainAsBlobDataHandle(BlobSizePolicy policy) over
ride |
| 73 { |
| 74 return m_underlying ? m_underlying->drainAsBlobDataHandle(policy) : null
ptr; |
| 75 } |
| 76 PassRefPtr<EncodedFormData> drainAsFormData() override |
| 77 { |
| 78 return m_underlying ? m_underlying->drainAsFormData() : nullptr; |
| 79 } |
| 80 void setClient(BytesConsumer::Client* client) override |
| 81 { |
| 82 DCHECK(!m_client); |
| 83 DCHECK(client); |
| 84 if (m_underlying) |
| 85 m_underlying->setClient(client); |
| 86 else |
| 87 m_client = client; |
| 88 } |
| 89 void clearClient() override |
| 90 { |
| 91 if (m_underlying) |
| 92 m_underlying->clearClient(); |
| 93 else |
| 94 m_client = nullptr; |
| 95 } |
| 96 void cancel() override |
| 97 { |
| 98 if (m_underlying) { |
| 99 m_underlying->cancel(); |
| 100 } else { |
| 101 m_isCancelled = true; |
| 102 m_client = nullptr; |
| 103 } |
| 104 } |
| 105 PublicState getPublicState() const override |
| 106 { |
| 107 return m_underlying ? m_underlying->getPublicState() : m_isCancelled ? P
ublicState::Closed : PublicState::ReadableOrWaiting; |
| 108 } |
| 109 Error getError() const override |
| 110 { |
| 111 DCHECK(m_underlying); |
| 112 // We must not be in the errored state until we get updated. |
| 113 return m_underlying->getError(); |
| 114 } |
| 115 String debugName() const override |
| 116 { |
| 117 return "SRIBytesConsumer"; |
| 118 } |
| 119 |
| 120 // This function can be called at most once. |
| 121 void update(BytesConsumer* consumer) |
| 122 { |
| 123 DCHECK(!m_underlying); |
| 124 if (m_isCancelled) { |
| 125 // This consumer has already been closed. |
| 126 return; |
| 127 } |
| 128 |
| 129 m_underlying = consumer; |
| 130 if (m_client) { |
| 131 Client* client = m_client; |
| 132 m_client = nullptr; |
| 133 m_underlying->setClient(client); |
| 134 if (getPublicState() != PublicState::ReadableOrWaiting) |
| 135 client->onStateChange(); |
| 136 } |
| 137 } |
| 138 |
| 139 DEFINE_INLINE_TRACE() |
| 140 { |
| 141 visitor->trace(m_underlying); |
| 142 visitor->trace(m_client); |
| 143 BytesConsumer::trace(visitor); |
| 144 } |
| 145 |
| 146 private: |
| 147 Member<BytesConsumer> m_underlying; |
| 148 Member<Client> m_client; |
| 149 bool m_isCancelled = false; |
| 150 }; |
| 151 |
| 152 |
| 54 } // namespace | 153 } // namespace |
| 55 | 154 |
| 56 class FetchManager::Loader final : public GarbageCollectedFinalized<FetchManager
::Loader>, public ThreadableLoaderClient { | 155 class FetchManager::Loader final : public GarbageCollectedFinalized<FetchManager
::Loader>, public ThreadableLoaderClient { |
| 57 USING_PRE_FINALIZER(FetchManager::Loader, dispose); | 156 USING_PRE_FINALIZER(FetchManager::Loader, dispose); |
| 58 public: | 157 public: |
| 59 static Loader* create(ExecutionContext* executionContext, FetchManager* fetc
hManager, ScriptPromiseResolver* resolver, FetchRequestData* request, bool isIso
latedWorld) | 158 static Loader* create(ExecutionContext* executionContext, FetchManager* fetc
hManager, ScriptPromiseResolver* resolver, FetchRequestData* request, bool isIso
latedWorld) |
| 60 { | 159 { |
| 61 return new Loader(executionContext, fetchManager, resolver, request, isI
solatedWorld); | 160 return new Loader(executionContext, fetchManager, resolver, request, isI
solatedWorld); |
| 62 } | 161 } |
| 63 | 162 |
| 64 ~Loader() override; | 163 ~Loader() override; |
| 65 DECLARE_VIRTUAL_TRACE(); | 164 DECLARE_VIRTUAL_TRACE(); |
| 66 | 165 |
| 67 void didReceiveResponse(unsigned long, const ResourceResponse&, std::unique_
ptr<WebDataConsumerHandle>) override; | 166 void didReceiveResponse(unsigned long, const ResourceResponse&, std::unique_
ptr<WebDataConsumerHandle>) override; |
| 68 void didFinishLoading(unsigned long, double) override; | 167 void didFinishLoading(unsigned long, double) override; |
| 69 void didFail(const ResourceError&) override; | 168 void didFail(const ResourceError&) override; |
| 70 void didFailAccessControlCheck(const ResourceError&) override; | 169 void didFailAccessControlCheck(const ResourceError&) override; |
| 71 void didFailRedirectCheck() override; | 170 void didFailRedirectCheck() override; |
| 72 | 171 |
| 73 void start(); | 172 void start(); |
| 74 void dispose(); | 173 void dispose(); |
| 75 | 174 |
| 76 class SRIVerifier final : public GarbageCollectedFinalized<SRIVerifier>, pub
lic WebDataConsumerHandle::Client { | 175 class SRIVerifier final : public GarbageCollectedFinalized<SRIVerifier>, pub
lic WebDataConsumerHandle::Client { |
| 77 public: | 176 public: |
| 78 // Promptly clear m_handle and m_reader. | 177 // Promptly clear m_handle and m_reader. |
| 79 EAGERLY_FINALIZE(); | 178 EAGERLY_FINALIZE(); |
| 80 // SRIVerifier takes ownership of |handle| and |response|. | 179 // SRIVerifier takes ownership of |handle| and |response|. |
| 81 // |updater| must be garbage collected. The other arguments | 180 // |updater| must be garbage collected. The other arguments |
| 82 // all must have the lifetime of the give loader. | 181 // all must have the lifetime of the give loader. |
| 83 SRIVerifier(std::unique_ptr<WebDataConsumerHandle> handle, CompositeData
ConsumerHandle::Updater* updater, Response* response, FetchManager::Loader* load
er, String integrityMetadata, const KURL& url) | 182 SRIVerifier(std::unique_ptr<WebDataConsumerHandle> handle, SRIBytesConsu
mer* updater, Response* response, FetchManager::Loader* loader, String integrity
Metadata, const KURL& url) |
| 84 : m_handle(std::move(handle)) | 183 : m_handle(std::move(handle)) |
| 85 , m_updater(updater) | 184 , m_updater(updater) |
| 86 , m_response(response) | 185 , m_response(response) |
| 87 , m_loader(loader) | 186 , m_loader(loader) |
| 88 , m_integrityMetadata(integrityMetadata) | 187 , m_integrityMetadata(integrityMetadata) |
| 89 , m_url(url) | 188 , m_url(url) |
| 90 , m_finished(false) | 189 , m_finished(false) |
| 91 { | 190 { |
| 92 m_reader = m_handle->obtainReader(this); | 191 m_reader = m_handle->obtainReader(this); |
| 93 } | 192 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 107 m_buffer.append(static_cast<const char*>(buffer), size); | 206 m_buffer.append(static_cast<const char*>(buffer), size); |
| 108 m_reader->endRead(size); | 207 m_reader->endRead(size); |
| 109 } | 208 } |
| 110 } | 209 } |
| 111 if (r == WebDataConsumerHandle::ShouldWait) | 210 if (r == WebDataConsumerHandle::ShouldWait) |
| 112 return; | 211 return; |
| 113 String errorMessage = "Unknown error occurred while trying to verify
integrity."; | 212 String errorMessage = "Unknown error occurred while trying to verify
integrity."; |
| 114 m_finished = true; | 213 m_finished = true; |
| 115 if (r == WebDataConsumerHandle::Done) { | 214 if (r == WebDataConsumerHandle::Done) { |
| 116 if (SubresourceIntegrity::CheckSubresourceIntegrity(m_integrityM
etadata, m_buffer.data(), m_buffer.size(), m_url, *m_loader->document(), errorMe
ssage)) { | 215 if (SubresourceIntegrity::CheckSubresourceIntegrity(m_integrityM
etadata, m_buffer.data(), m_buffer.size(), m_url, *m_loader->document(), errorMe
ssage)) { |
| 117 m_updater->update(FetchFormDataConsumerHandle::create(m_buff
er.data(), m_buffer.size())); | 216 m_updater->update(new FormDataBytesConsumer(m_buffer.data(),
m_buffer.size())); |
| 118 m_loader->m_resolver->resolve(m_response); | 217 m_loader->m_resolver->resolve(m_response); |
| 119 m_loader->m_resolver.clear(); | 218 m_loader->m_resolver.clear(); |
| 120 // FetchManager::Loader::didFinishLoading() can | 219 // FetchManager::Loader::didFinishLoading() can |
| 121 // be called before didGetReadable() is called | 220 // be called before didGetReadable() is called |
| 122 // when the data is ready. In that case, | 221 // when the data is ready. In that case, |
| 123 // didFinishLoading() doesn't clean up and call | 222 // didFinishLoading() doesn't clean up and call |
| 124 // notifyFinished(), so it is necessary to | 223 // notifyFinished(), so it is necessary to |
| 125 // explicitly finish the loader here. | 224 // explicitly finish the loader here. |
| 126 if (m_loader->m_didFinishLoading) | 225 if (m_loader->m_didFinishLoading) |
| 127 m_loader->loadSucceeded(); | 226 m_loader->loadSucceeded(); |
| 128 return; | 227 return; |
| 129 } | 228 } |
| 130 } | 229 } |
| 131 m_updater->update(createUnexpectedErrorDataConsumerHandle()); | 230 m_updater->update(new BytesConsumerForDataConsumerHandle(m_response-
>getExecutionContext(), createFetchDataConsumerHandleFromWebHandle(createUnexpec
tedErrorDataConsumerHandle()))); |
| 132 m_loader->performNetworkError(errorMessage); | 231 m_loader->performNetworkError(errorMessage); |
| 133 } | 232 } |
| 134 | 233 |
| 135 bool isFinished() const { return m_finished; } | 234 bool isFinished() const { return m_finished; } |
| 136 | 235 |
| 137 DEFINE_INLINE_TRACE() | 236 DEFINE_INLINE_TRACE() |
| 138 { | 237 { |
| 139 visitor->trace(m_updater); | 238 visitor->trace(m_updater); |
| 140 visitor->trace(m_response); | 239 visitor->trace(m_response); |
| 141 visitor->trace(m_loader); | 240 visitor->trace(m_loader); |
| 142 } | 241 } |
| 143 private: | 242 private: |
| 144 std::unique_ptr<WebDataConsumerHandle> m_handle; | 243 std::unique_ptr<WebDataConsumerHandle> m_handle; |
| 145 Member<CompositeDataConsumerHandle::Updater> m_updater; | 244 Member<SRIBytesConsumer> m_updater; |
| 146 // We cannot store a Response because its JS wrapper can be collected. | 245 // We cannot store a Response because its JS wrapper can be collected. |
| 147 // TODO(yhirano): Fix this. | 246 // TODO(yhirano): Fix this. |
| 148 Member<Response> m_response; | 247 Member<Response> m_response; |
| 149 Member<FetchManager::Loader> m_loader; | 248 Member<FetchManager::Loader> m_loader; |
| 150 String m_integrityMetadata; | 249 String m_integrityMetadata; |
| 151 KURL m_url; | 250 KURL m_url; |
| 152 std::unique_ptr<WebDataConsumerHandle::Reader> m_reader; | 251 std::unique_ptr<WebDataConsumerHandle::Reader> m_reader; |
| 153 Vector<char> m_buffer; | 252 Vector<char> m_buffer; |
| 154 bool m_finished; | 253 bool m_finished; |
| 155 }; | 254 }; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 case WebServiceWorkerResponseTypeError: | 388 case WebServiceWorkerResponseTypeError: |
| 290 // When ServiceWorker respond to the request from fetch() with an | 389 // When ServiceWorker respond to the request from fetch() with an |
| 291 // error response, FetchManager::Loader::didFail() must be called | 390 // error response, FetchManager::Loader::didFail() must be called |
| 292 // instead. | 391 // instead. |
| 293 RELEASE_NOTREACHED(); | 392 RELEASE_NOTREACHED(); |
| 294 break; | 393 break; |
| 295 } | 394 } |
| 296 } | 395 } |
| 297 | 396 |
| 298 FetchResponseData* responseData = nullptr; | 397 FetchResponseData* responseData = nullptr; |
| 299 CompositeDataConsumerHandle::Updater* updater = nullptr; | 398 SRIBytesConsumer* sriConsumer = nullptr; |
| 300 if (m_request->integrity().isEmpty()) | 399 if (m_request->integrity().isEmpty()) { |
| 301 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer(
scriptState, createFetchDataConsumerHandleFromWebHandle(std::move(handle)))); | 400 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer(
scriptState, createFetchDataConsumerHandleFromWebHandle(std::move(handle)))); |
| 302 else | 401 } else { |
| 303 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer(
scriptState, createFetchDataConsumerHandleFromWebHandle(CompositeDataConsumerHan
dle::create(createWaitingDataConsumerHandle(), &updater)))); | 402 sriConsumer = new SRIBytesConsumer(); |
| 403 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer(
scriptState, sriConsumer)); |
| 404 } |
| 304 responseData->setStatus(response.httpStatusCode()); | 405 responseData->setStatus(response.httpStatusCode()); |
| 305 responseData->setStatusMessage(response.httpStatusText()); | 406 responseData->setStatusMessage(response.httpStatusText()); |
| 306 for (auto& it : response.httpHeaderFields()) | 407 for (auto& it : response.httpHeaderFields()) |
| 307 responseData->headerList()->append(it.key, it.value); | 408 responseData->headerList()->append(it.key, it.value); |
| 308 responseData->setURL(response.url()); | 409 responseData->setURL(response.url()); |
| 309 responseData->setMIMEType(response.mimeType()); | 410 responseData->setMIMEType(response.mimeType()); |
| 310 responseData->setResponseTime(response.responseTime()); | 411 responseData->setResponseTime(response.responseTime()); |
| 311 | 412 |
| 312 FetchResponseData* taintedResponse = nullptr; | 413 FetchResponseData* taintedResponse = nullptr; |
| 313 | 414 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 // parameters returned from obtaining a resource" | 459 // parameters returned from obtaining a resource" |
| 359 r->headers()->headerList()->remove(HTTPNames::Access_Control_Allow_Origi
n); | 460 r->headers()->headerList()->remove(HTTPNames::Access_Control_Allow_Origi
n); |
| 360 } | 461 } |
| 361 r->headers()->setGuard(Headers::ImmutableGuard); | 462 r->headers()->setGuard(Headers::ImmutableGuard); |
| 362 | 463 |
| 363 if (m_request->integrity().isEmpty()) { | 464 if (m_request->integrity().isEmpty()) { |
| 364 m_resolver->resolve(r); | 465 m_resolver->resolve(r); |
| 365 m_resolver.clear(); | 466 m_resolver.clear(); |
| 366 } else { | 467 } else { |
| 367 ASSERT(!m_integrityVerifier); | 468 ASSERT(!m_integrityVerifier); |
| 368 m_integrityVerifier = new SRIVerifier(std::move(handle), updater, r, thi
s, m_request->integrity(), response.url()); | 469 m_integrityVerifier = new SRIVerifier(std::move(handle), sriConsumer, r,
this, m_request->integrity(), response.url()); |
| 369 } | 470 } |
| 370 } | 471 } |
| 371 | 472 |
| 372 void FetchManager::Loader::didFinishLoading(unsigned long, double) | 473 void FetchManager::Loader::didFinishLoading(unsigned long, double) |
| 373 { | 474 { |
| 374 m_didFinishLoading = true; | 475 m_didFinishLoading = true; |
| 375 // If there is an integrity verifier, and it has not already finished, it | 476 // If there is an integrity verifier, and it has not already finished, it |
| 376 // will take care of finishing the load or performing a network error when | 477 // will take care of finishing the load or performing a network error when |
| 377 // verification is complete. | 478 // verification is complete. |
| 378 if (m_integrityVerifier && !m_integrityVerifier->isFinished()) | 479 if (m_integrityVerifier && !m_integrityVerifier->isFinished()) |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 loader->dispose(); | 843 loader->dispose(); |
| 743 } | 844 } |
| 744 | 845 |
| 745 DEFINE_TRACE(FetchManager) | 846 DEFINE_TRACE(FetchManager) |
| 746 { | 847 { |
| 747 visitor->trace(m_loaders); | 848 visitor->trace(m_loaders); |
| 748 ContextLifecycleObserver::trace(visitor); | 849 ContextLifecycleObserver::trace(visitor); |
| 749 } | 850 } |
| 750 | 851 |
| 751 } // namespace blink | 852 } // namespace blink |
| OLD | NEW |