Chromium Code Reviews| 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 : public BytesConsumer { | |
|
hiroshige
2016/09/27 07:45:43
final
yhirano
2016/09/27 07:53:58
Done.
| |
| 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(client); | |
|
hiroshige
2016/09/27 07:45:43
DCHECK(!m_client);
yhirano
2016/09/27 07:53:58
Done.
| |
| 83 if (m_underlying) | |
| 84 m_underlying->setClient(client); | |
| 85 else | |
| 86 m_client = nullptr; | |
|
hiroshige
2016/09/27 07:45:43
|m_client = client|?
yhirano
2016/09/27 07:53:58
You're right, thank you. Done.
| |
| 87 } | |
| 88 void clearClient() override | |
| 89 { | |
| 90 if (m_underlying) | |
| 91 m_underlying->clearClient(); | |
| 92 else | |
| 93 m_client = nullptr; | |
| 94 } | |
| 95 void cancel() override | |
| 96 { | |
| 97 if (m_underlying) | |
| 98 m_underlying->cancel(); | |
| 99 else | |
| 100 m_isCancelled = true; | |
|
hiroshige
2016/09/27 07:45:43
Do we need to clear |m_client| here?
yhirano
2016/09/27 07:53:58
Nice catch. Done.
| |
| 101 } | |
| 102 PublicState getPublicState() const override | |
| 103 { | |
| 104 return m_underlying ? m_underlying->getPublicState() : m_isCancelled ? P ublicState::Closed : PublicState::ReadableOrWaiting; | |
| 105 } | |
| 106 Error getError() const override | |
| 107 { | |
| 108 DCHECK(m_underlying); | |
| 109 // We must not be in the errored state until we get updated. | |
| 110 return m_underlying->getError(); | |
| 111 } | |
| 112 String debugName() const override | |
| 113 { | |
| 114 return "SRIBytesConsumer"; | |
| 115 } | |
| 116 | |
| 117 // This function can be called at most once. | |
| 118 void update(BytesConsumer* consumer) | |
| 119 { | |
| 120 DCHECK(!m_underlying); | |
| 121 if (m_isCancelled) { | |
| 122 // This consumer has already been closed. | |
| 123 return; | |
| 124 } | |
| 125 | |
| 126 m_underlying = consumer; | |
| 127 if (m_client) { | |
| 128 Client* client = m_client; | |
| 129 m_client = nullptr; | |
| 130 m_underlying->setClient(client); | |
| 131 if (getPublicState() != PublicState::ReadableOrWaiting) | |
| 132 client->onStateChange(); | |
| 133 } | |
| 134 } | |
| 135 | |
| 136 DEFINE_INLINE_TRACE() | |
| 137 { | |
| 138 visitor->trace(m_underlying); | |
| 139 visitor->trace(m_client); | |
| 140 BytesConsumer::trace(visitor); | |
| 141 } | |
| 142 | |
| 143 private: | |
| 144 Member<BytesConsumer> m_underlying; | |
| 145 Member<Client> m_client; | |
| 146 bool m_isCancelled = false; | |
| 147 }; | |
| 148 | |
| 149 | |
| 54 } // namespace | 150 } // namespace |
| 55 | 151 |
| 56 class FetchManager::Loader final : public GarbageCollectedFinalized<FetchManager ::Loader>, public ThreadableLoaderClient { | 152 class FetchManager::Loader final : public GarbageCollectedFinalized<FetchManager ::Loader>, public ThreadableLoaderClient { |
| 57 USING_PRE_FINALIZER(FetchManager::Loader, dispose); | 153 USING_PRE_FINALIZER(FetchManager::Loader, dispose); |
| 58 public: | 154 public: |
| 59 static Loader* create(ExecutionContext* executionContext, FetchManager* fetc hManager, ScriptPromiseResolver* resolver, FetchRequestData* request, bool isIso latedWorld) | 155 static Loader* create(ExecutionContext* executionContext, FetchManager* fetc hManager, ScriptPromiseResolver* resolver, FetchRequestData* request, bool isIso latedWorld) |
| 60 { | 156 { |
| 61 return new Loader(executionContext, fetchManager, resolver, request, isI solatedWorld); | 157 return new Loader(executionContext, fetchManager, resolver, request, isI solatedWorld); |
| 62 } | 158 } |
| 63 | 159 |
| 64 ~Loader() override; | 160 ~Loader() override; |
| 65 DECLARE_VIRTUAL_TRACE(); | 161 DECLARE_VIRTUAL_TRACE(); |
| 66 | 162 |
| 67 void didReceiveResponse(unsigned long, const ResourceResponse&, std::unique_ ptr<WebDataConsumerHandle>) override; | 163 void didReceiveResponse(unsigned long, const ResourceResponse&, std::unique_ ptr<WebDataConsumerHandle>) override; |
| 68 void didFinishLoading(unsigned long, double) override; | 164 void didFinishLoading(unsigned long, double) override; |
| 69 void didFail(const ResourceError&) override; | 165 void didFail(const ResourceError&) override; |
| 70 void didFailAccessControlCheck(const ResourceError&) override; | 166 void didFailAccessControlCheck(const ResourceError&) override; |
| 71 void didFailRedirectCheck() override; | 167 void didFailRedirectCheck() override; |
| 72 | 168 |
| 73 void start(); | 169 void start(); |
| 74 void dispose(); | 170 void dispose(); |
| 75 | 171 |
| 76 class SRIVerifier final : public GarbageCollectedFinalized<SRIVerifier>, pub lic WebDataConsumerHandle::Client { | 172 class SRIVerifier final : public GarbageCollectedFinalized<SRIVerifier>, pub lic WebDataConsumerHandle::Client { |
| 77 public: | 173 public: |
| 78 // Promptly clear m_handle and m_reader. | 174 // Promptly clear m_handle and m_reader. |
| 79 EAGERLY_FINALIZE(); | 175 EAGERLY_FINALIZE(); |
| 80 // SRIVerifier takes ownership of |handle| and |response|. | 176 // SRIVerifier takes ownership of |handle| and |response|. |
| 81 // |updater| must be garbage collected. The other arguments | 177 // |updater| must be garbage collected. The other arguments |
| 82 // all must have the lifetime of the give loader. | 178 // 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) | 179 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)) | 180 : m_handle(std::move(handle)) |
| 85 , m_updater(updater) | 181 , m_updater(updater) |
| 86 , m_response(response) | 182 , m_response(response) |
| 87 , m_loader(loader) | 183 , m_loader(loader) |
| 88 , m_integrityMetadata(integrityMetadata) | 184 , m_integrityMetadata(integrityMetadata) |
| 89 , m_url(url) | 185 , m_url(url) |
| 90 , m_finished(false) | 186 , m_finished(false) |
| 91 { | 187 { |
| 92 m_reader = m_handle->obtainReader(this); | 188 m_reader = m_handle->obtainReader(this); |
| 93 } | 189 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 107 m_buffer.append(static_cast<const char*>(buffer), size); | 203 m_buffer.append(static_cast<const char*>(buffer), size); |
| 108 m_reader->endRead(size); | 204 m_reader->endRead(size); |
| 109 } | 205 } |
| 110 } | 206 } |
| 111 if (r == WebDataConsumerHandle::ShouldWait) | 207 if (r == WebDataConsumerHandle::ShouldWait) |
| 112 return; | 208 return; |
| 113 String errorMessage = "Unknown error occurred while trying to verify integrity."; | 209 String errorMessage = "Unknown error occurred while trying to verify integrity."; |
| 114 m_finished = true; | 210 m_finished = true; |
| 115 if (r == WebDataConsumerHandle::Done) { | 211 if (r == WebDataConsumerHandle::Done) { |
| 116 if (SubresourceIntegrity::CheckSubresourceIntegrity(m_integrityM etadata, m_buffer.data(), m_buffer.size(), m_url, *m_loader->document(), errorMe ssage)) { | 212 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())); | 213 m_updater->update(new FormDataBytesConsumer(m_buffer.data(), m_buffer.size())); |
| 118 m_loader->m_resolver->resolve(m_response); | 214 m_loader->m_resolver->resolve(m_response); |
| 119 m_loader->m_resolver.clear(); | 215 m_loader->m_resolver.clear(); |
| 120 // FetchManager::Loader::didFinishLoading() can | 216 // FetchManager::Loader::didFinishLoading() can |
| 121 // be called before didGetReadable() is called | 217 // be called before didGetReadable() is called |
| 122 // when the data is ready. In that case, | 218 // when the data is ready. In that case, |
| 123 // didFinishLoading() doesn't clean up and call | 219 // didFinishLoading() doesn't clean up and call |
| 124 // notifyFinished(), so it is necessary to | 220 // notifyFinished(), so it is necessary to |
| 125 // explicitly finish the loader here. | 221 // explicitly finish the loader here. |
| 126 if (m_loader->m_didFinishLoading) | 222 if (m_loader->m_didFinishLoading) |
| 127 m_loader->loadSucceeded(); | 223 m_loader->loadSucceeded(); |
| 128 return; | 224 return; |
| 129 } | 225 } |
| 130 } | 226 } |
| 131 m_updater->update(createUnexpectedErrorDataConsumerHandle()); | 227 m_updater->update(new BytesConsumerForDataConsumerHandle(m_response- >getExecutionContext(), createFetchDataConsumerHandleFromWebHandle(createUnexpec tedErrorDataConsumerHandle()))); |
|
hiroshige
2016/09/27 07:45:43
Do you plan to create BytesConsumer-version of cre
yhirano
2016/09/27 07:53:58
Yes, I will do that.
| |
| 132 m_loader->performNetworkError(errorMessage); | 228 m_loader->performNetworkError(errorMessage); |
| 133 } | 229 } |
| 134 | 230 |
| 135 bool isFinished() const { return m_finished; } | 231 bool isFinished() const { return m_finished; } |
| 136 | 232 |
| 137 DEFINE_INLINE_TRACE() | 233 DEFINE_INLINE_TRACE() |
| 138 { | 234 { |
| 139 visitor->trace(m_updater); | 235 visitor->trace(m_updater); |
| 140 visitor->trace(m_response); | 236 visitor->trace(m_response); |
| 141 visitor->trace(m_loader); | 237 visitor->trace(m_loader); |
| 142 } | 238 } |
| 143 private: | 239 private: |
| 144 std::unique_ptr<WebDataConsumerHandle> m_handle; | 240 std::unique_ptr<WebDataConsumerHandle> m_handle; |
| 145 Member<CompositeDataConsumerHandle::Updater> m_updater; | 241 Member<SRIBytesConsumer> m_updater; |
| 146 // We cannot store a Response because its JS wrapper can be collected. | 242 // We cannot store a Response because its JS wrapper can be collected. |
| 147 // TODO(yhirano): Fix this. | 243 // TODO(yhirano): Fix this. |
| 148 Member<Response> m_response; | 244 Member<Response> m_response; |
| 149 Member<FetchManager::Loader> m_loader; | 245 Member<FetchManager::Loader> m_loader; |
| 150 String m_integrityMetadata; | 246 String m_integrityMetadata; |
| 151 KURL m_url; | 247 KURL m_url; |
| 152 std::unique_ptr<WebDataConsumerHandle::Reader> m_reader; | 248 std::unique_ptr<WebDataConsumerHandle::Reader> m_reader; |
| 153 Vector<char> m_buffer; | 249 Vector<char> m_buffer; |
| 154 bool m_finished; | 250 bool m_finished; |
| 155 }; | 251 }; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 289 case WebServiceWorkerResponseTypeError: | 385 case WebServiceWorkerResponseTypeError: |
| 290 // When ServiceWorker respond to the request from fetch() with an | 386 // When ServiceWorker respond to the request from fetch() with an |
| 291 // error response, FetchManager::Loader::didFail() must be called | 387 // error response, FetchManager::Loader::didFail() must be called |
| 292 // instead. | 388 // instead. |
| 293 RELEASE_NOTREACHED(); | 389 RELEASE_NOTREACHED(); |
| 294 break; | 390 break; |
| 295 } | 391 } |
| 296 } | 392 } |
| 297 | 393 |
| 298 FetchResponseData* responseData = nullptr; | 394 FetchResponseData* responseData = nullptr; |
| 299 CompositeDataConsumerHandle::Updater* updater = nullptr; | 395 SRIBytesConsumer* sriConsumer = nullptr; |
| 300 if (m_request->integrity().isEmpty()) | 396 if (m_request->integrity().isEmpty()) { |
| 301 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer( scriptState, createFetchDataConsumerHandleFromWebHandle(std::move(handle)))); | 397 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer( scriptState, createFetchDataConsumerHandleFromWebHandle(std::move(handle)))); |
| 302 else | 398 } else { |
| 303 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer( scriptState, createFetchDataConsumerHandleFromWebHandle(CompositeDataConsumerHan dle::create(createWaitingDataConsumerHandle(), &updater)))); | 399 sriConsumer = new SRIBytesConsumer(); |
| 400 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer( scriptState, sriConsumer)); | |
| 401 } | |
| 304 responseData->setStatus(response.httpStatusCode()); | 402 responseData->setStatus(response.httpStatusCode()); |
| 305 responseData->setStatusMessage(response.httpStatusText()); | 403 responseData->setStatusMessage(response.httpStatusText()); |
| 306 for (auto& it : response.httpHeaderFields()) | 404 for (auto& it : response.httpHeaderFields()) |
| 307 responseData->headerList()->append(it.key, it.value); | 405 responseData->headerList()->append(it.key, it.value); |
| 308 responseData->setURL(response.url()); | 406 responseData->setURL(response.url()); |
| 309 responseData->setMIMEType(response.mimeType()); | 407 responseData->setMIMEType(response.mimeType()); |
| 310 responseData->setResponseTime(response.responseTime()); | 408 responseData->setResponseTime(response.responseTime()); |
| 311 | 409 |
| 312 FetchResponseData* taintedResponse = nullptr; | 410 FetchResponseData* taintedResponse = nullptr; |
| 313 | 411 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 358 // parameters returned from obtaining a resource" | 456 // parameters returned from obtaining a resource" |
| 359 r->headers()->headerList()->remove(HTTPNames::Access_Control_Allow_Origi n); | 457 r->headers()->headerList()->remove(HTTPNames::Access_Control_Allow_Origi n); |
| 360 } | 458 } |
| 361 r->headers()->setGuard(Headers::ImmutableGuard); | 459 r->headers()->setGuard(Headers::ImmutableGuard); |
| 362 | 460 |
| 363 if (m_request->integrity().isEmpty()) { | 461 if (m_request->integrity().isEmpty()) { |
| 364 m_resolver->resolve(r); | 462 m_resolver->resolve(r); |
| 365 m_resolver.clear(); | 463 m_resolver.clear(); |
| 366 } else { | 464 } else { |
| 367 ASSERT(!m_integrityVerifier); | 465 ASSERT(!m_integrityVerifier); |
| 368 m_integrityVerifier = new SRIVerifier(std::move(handle), updater, r, thi s, m_request->integrity(), response.url()); | 466 m_integrityVerifier = new SRIVerifier(std::move(handle), sriConsumer, r, this, m_request->integrity(), response.url()); |
| 369 } | 467 } |
| 370 } | 468 } |
| 371 | 469 |
| 372 void FetchManager::Loader::didFinishLoading(unsigned long, double) | 470 void FetchManager::Loader::didFinishLoading(unsigned long, double) |
| 373 { | 471 { |
| 374 m_didFinishLoading = true; | 472 m_didFinishLoading = true; |
| 375 // If there is an integrity verifier, and it has not already finished, it | 473 // 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 | 474 // will take care of finishing the load or performing a network error when |
| 377 // verification is complete. | 475 // verification is complete. |
| 378 if (m_integrityVerifier && !m_integrityVerifier->isFinished()) | 476 if (m_integrityVerifier && !m_integrityVerifier->isFinished()) |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 742 loader->dispose(); | 840 loader->dispose(); |
| 743 } | 841 } |
| 744 | 842 |
| 745 DEFINE_TRACE(FetchManager) | 843 DEFINE_TRACE(FetchManager) |
| 746 { | 844 { |
| 747 visitor->trace(m_loaders); | 845 visitor->trace(m_loaders); |
| 748 ContextLifecycleObserver::trace(visitor); | 846 ContextLifecycleObserver::trace(visitor); |
| 749 } | 847 } |
| 750 | 848 |
| 751 } // namespace blink | 849 } // namespace blink |
| OLD | NEW |