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 "config.h" | 5 #include "config.h" |
| 6 #include "modules/fetch/FetchManager.h" | 6 #include "modules/fetch/FetchManager.h" |
| 7 | 7 |
| 8 #include "bindings/core/v8/ExceptionState.h" | 8 #include "bindings/core/v8/ExceptionState.h" |
| 9 #include "bindings/core/v8/ScriptPromiseResolver.h" | 9 #include "bindings/core/v8/ScriptPromiseResolver.h" |
| 10 #include "bindings/core/v8/ScriptState.h" | 10 #include "bindings/core/v8/ScriptState.h" |
| 11 #include "bindings/core/v8/V8ThrowException.h" | 11 #include "bindings/core/v8/V8ThrowException.h" |
| 12 #include "core/dom/DOMArrayBuffer.h" | 12 #include "core/dom/DOMArrayBuffer.h" |
| 13 #include "core/dom/Document.h" | 13 #include "core/dom/Document.h" |
| 14 #include "core/dom/ExceptionCode.h" | 14 #include "core/dom/ExceptionCode.h" |
| 15 #include "core/fetch/FetchUtils.h" | 15 #include "core/fetch/FetchUtils.h" |
| 16 #include "core/fileapi/Blob.h" | 16 #include "core/fileapi/Blob.h" |
| 17 #include "core/frame/Frame.h" | 17 #include "core/frame/Frame.h" |
| 18 #include "core/frame/SubresourceIntegrity.h" | |
| 18 #include "core/frame/csp/ContentSecurityPolicy.h" | 19 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 19 #include "core/inspector/ConsoleMessage.h" | 20 #include "core/inspector/ConsoleMessage.h" |
| 20 #include "core/inspector/InspectorInstrumentation.h" | 21 #include "core/inspector/InspectorInstrumentation.h" |
| 21 #include "core/loader/ThreadableLoader.h" | 22 #include "core/loader/ThreadableLoader.h" |
| 22 #include "core/loader/ThreadableLoaderClient.h" | 23 #include "core/loader/ThreadableLoaderClient.h" |
| 23 #include "core/page/ChromeClient.h" | 24 #include "core/page/ChromeClient.h" |
| 24 #include "core/page/Page.h" | 25 #include "core/page/Page.h" |
| 25 #include "modules/fetch/Body.h" | 26 #include "modules/fetch/Body.h" |
| 26 #include "modules/fetch/BodyStreamBuffer.h" | 27 #include "modules/fetch/BodyStreamBuffer.h" |
| 27 #include "modules/fetch/DataConsumerHandleUtil.h" | 28 #include "modules/fetch/DataConsumerHandleUtil.h" |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 50 | 51 |
| 51 void didReceiveResponse(unsigned long, const ResourceResponse&, PassOwnPtr<W ebDataConsumerHandle>) override; | 52 void didReceiveResponse(unsigned long, const ResourceResponse&, PassOwnPtr<W ebDataConsumerHandle>) override; |
| 52 void didFinishLoading(unsigned long, double) override; | 53 void didFinishLoading(unsigned long, double) override; |
| 53 void didFail(const ResourceError&) override; | 54 void didFail(const ResourceError&) override; |
| 54 void didFailAccessControlCheck(const ResourceError&) override; | 55 void didFailAccessControlCheck(const ResourceError&) override; |
| 55 void didFailRedirectCheck() override; | 56 void didFailRedirectCheck() override; |
| 56 | 57 |
| 57 void start(); | 58 void start(); |
| 58 void dispose(); | 59 void dispose(); |
| 59 | 60 |
| 61 class IntegrityVerifiedDataConsumerHandle : public WebDataConsumerHandle { | |
| 62 public: | |
| 63 IntegrityVerifiedDataConsumerHandle(PassOwnPtr<WebDataConsumerHandle> ha ndle, String integrityMetadata, const KURL& url, FetchManager::Loader* loader) | |
| 64 : m_handle(handle) | |
| 65 , m_integrityMetadata(integrityMetadata) | |
| 66 , m_url(url) | |
| 67 , m_loader(loader) | |
| 68 , m_response(nullptr) | |
| 69 { | |
| 70 } | |
| 71 | |
| 72 void setResponse(Response* response) { m_response = response; } | |
| 73 | |
| 74 private: | |
| 75 class ReaderImpl final : public WebDataConsumerHandle::Reader { | |
| 76 public: | |
| 77 ReaderImpl(PassOwnPtr<WebDataConsumerHandle::Reader> reader, String integrityMetadata, const KURL& url, FetchManager::Loader* loader, Response* resp onse) | |
| 78 : m_reader(reader) | |
| 79 , m_integrityMetadata(integrityMetadata) | |
| 80 , m_url(url) | |
| 81 , m_loader(loader) | |
| 82 , m_response(response) | |
| 83 , m_firstRun(true) | |
| 84 { | |
| 85 } | |
| 86 Result read(void* data, size_t size, Flags flags, size_t* readSize) override | |
| 87 { | |
| 88 if (m_firstRun) { | |
| 89 m_firstRun = false; | |
| 90 String content; | |
| 91 char buf[1000]; | |
| 92 size_t amt; | |
| 93 while (m_reader->read(buf, 1000, flags, &amt) == Ok) | |
|
yhirano
2015/08/11 09:22:08
Do you want to read all data from the pipe with th
jww
2015/08/12 16:40:14
This is addressed by your suggestion of implementi
yhirano
2015/08/13 18:10:36
Yes.
| |
| 94 content.append(buf, amt); | |
| 95 String errorMessage; | |
| 96 if (!SubresourceIntegrity::CheckSubresourceIntegrity(m_integ rityMetadata, content, m_url, *m_loader->document(), errorMessage)) { | |
|
yhirano
2015/08/11 09:22:08
This function can be called on a different thread
jww
2015/08/12 16:40:14
This is no longer a problem if your suggestion of
| |
| 97 m_loader->performNetworkError(errorMessage); | |
| 98 return UnexpectedError; | |
| 99 } | |
| 100 m_loader->m_resolver->resolve(m_response); | |
| 101 m_loader->m_resolver.clear(); | |
| 102 m_response = nullptr; | |
| 103 } | |
| 104 | |
| 105 return m_reader->read(data, size, flags, readSize); | |
| 106 } | |
| 107 | |
| 108 Result beginRead(const void** buffer, Flags flags, size_t* available ) override | |
| 109 { | |
| 110 return m_reader->beginRead(buffer, flags, available); | |
| 111 } | |
| 112 | |
| 113 Result endRead(size_t readSize) override | |
| 114 { | |
| 115 return m_reader->endRead(readSize); | |
| 116 } | |
| 117 | |
| 118 private: | |
| 119 OwnPtr<WebDataConsumerHandle::Reader> m_reader; | |
| 120 String m_integrityMetadata; | |
| 121 KURL m_url; | |
| 122 FetchManager::Loader* m_loader; | |
| 123 Response* m_response; | |
| 124 bool m_firstRun; | |
| 125 }; | |
| 126 | |
| 127 Reader* obtainReaderInternal(Client* client) override | |
|
yhirano
2015/08/11 09:22:08
A difficult point is that obtainReaderInternal can
jww
2015/08/12 16:40:14
Acknowledged.
| |
| 128 { | |
| 129 return new ReaderImpl(m_handle->obtainReader(client), m_integrityMet adata, m_url, m_loader, m_response); | |
| 130 } | |
| 131 const char* debugName() const override { return m_handle->debugName(); } | |
| 132 | |
| 133 OwnPtr<WebDataConsumerHandle> m_handle; | |
| 134 String m_integrityMetadata; | |
| 135 KURL m_url; | |
| 136 FetchManager::Loader* m_loader; | |
| 137 Response* m_response; | |
| 138 }; | |
| 139 | |
| 60 private: | 140 private: |
| 61 Loader(ExecutionContext*, FetchManager*, ScriptPromiseResolver*, FetchReques tData*); | 141 Loader(ExecutionContext*, FetchManager*, ScriptPromiseResolver*, FetchReques tData*); |
| 62 | 142 |
| 63 void performBasicFetch(); | 143 void performBasicFetch(); |
| 64 void performNetworkError(const String& message); | 144 void performNetworkError(const String& message); |
| 65 void performHTTPFetch(bool corsFlag, bool corsPreflightFlag); | 145 void performHTTPFetch(bool corsFlag, bool corsPreflightFlag); |
| 66 void failed(const String& message); | 146 void failed(const String& message); |
| 67 void notifyFinished(); | 147 void notifyFinished(); |
| 68 Document* document() const; | 148 Document* document() const; |
| 69 | 149 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 break; | 195 break; |
| 116 case WebURLRequest::FetchRequestModeNoCORS: | 196 case WebURLRequest::FetchRequestModeNoCORS: |
| 117 m_request->setResponseTainting(FetchRequestData::OpaqueTainting); | 197 m_request->setResponseTainting(FetchRequestData::OpaqueTainting); |
| 118 break; | 198 break; |
| 119 case WebURLRequest::FetchRequestModeCORS: | 199 case WebURLRequest::FetchRequestModeCORS: |
| 120 case WebURLRequest::FetchRequestModeCORSWithForcedPreflight: | 200 case WebURLRequest::FetchRequestModeCORSWithForcedPreflight: |
| 121 m_request->setResponseTainting(FetchRequestData::CORSTainting); | 201 m_request->setResponseTainting(FetchRequestData::CORSTainting); |
| 122 break; | 202 break; |
| 123 } | 203 } |
| 124 } | 204 } |
| 125 FetchResponseData* responseData = FetchResponseData::createWithBuffer(new Bo dyStreamBuffer(createFetchDataConsumerHandleFromWebHandle(handle))); | 205 |
| 206 FetchResponseData* responseData; | |
| 207 IntegrityVerifiedDataConsumerHandle* integrityVerifier = nullptr; | |
| 208 if (m_request->integrity().isEmpty()) { | |
| 209 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer( createFetchDataConsumerHandleFromWebHandle(handle))); | |
| 210 } else { | |
| 211 integrityVerifier = new IntegrityVerifiedDataConsumerHandle(handle, m_re quest->integrity(), m_request->url(), this); | |
| 212 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer( createFetchDataConsumerHandleFromWebHandle(adoptPtr(integrityVerifier)))); | |
| 213 } | |
| 126 responseData->setStatus(response.httpStatusCode()); | 214 responseData->setStatus(response.httpStatusCode()); |
| 127 responseData->setStatusMessage(response.httpStatusText()); | 215 responseData->setStatusMessage(response.httpStatusText()); |
| 128 for (auto& it : response.httpHeaderFields()) | 216 for (auto& it : response.httpHeaderFields()) |
| 129 responseData->headerList()->append(it.key, it.value); | 217 responseData->headerList()->append(it.key, it.value); |
| 130 responseData->setURL(response.url()); | 218 responseData->setURL(response.url()); |
| 131 responseData->setMIMEType(response.mimeType()); | 219 responseData->setMIMEType(response.mimeType()); |
| 132 | 220 |
| 133 FetchResponseData* taintedResponse = responseData; | 221 FetchResponseData* taintedResponse = responseData; |
| 134 switch (m_request->tainting()) { | 222 switch (m_request->tainting()) { |
| 135 case FetchRequestData::BasicTainting: | 223 case FetchRequestData::BasicTainting: |
| 136 taintedResponse = responseData->createBasicFilteredResponse(); | 224 taintedResponse = responseData->createBasicFilteredResponse(); |
| 137 break; | 225 break; |
| 138 case FetchRequestData::CORSTainting: | 226 case FetchRequestData::CORSTainting: |
| 139 taintedResponse = responseData->createCORSFilteredResponse(); | 227 taintedResponse = responseData->createCORSFilteredResponse(); |
| 140 break; | 228 break; |
| 141 case FetchRequestData::OpaqueTainting: | 229 case FetchRequestData::OpaqueTainting: |
| 142 taintedResponse = responseData->createOpaqueFilteredResponse(); | 230 taintedResponse = responseData->createOpaqueFilteredResponse(); |
| 143 break; | 231 break; |
| 144 } | 232 } |
| 233 | |
| 145 Response* r = Response::create(m_resolver->executionContext(), taintedRespon se); | 234 Response* r = Response::create(m_resolver->executionContext(), taintedRespon se); |
| 146 r->headers()->setGuard(Headers::ImmutableGuard); | 235 r->headers()->setGuard(Headers::ImmutableGuard); |
| 147 m_resolver->resolve(r); | 236 |
| 148 m_resolver.clear(); | 237 if (integrityVerifier) { |
| 238 integrityVerifier->setResponse(r); | |
| 239 } else { | |
| 240 m_resolver->resolve(r); | |
| 241 m_resolver.clear(); | |
| 242 } | |
| 149 } | 243 } |
| 150 | 244 |
| 151 void FetchManager::Loader::didFinishLoading(unsigned long, double) | 245 void FetchManager::Loader::didFinishLoading(unsigned long, double) |
| 152 { | 246 { |
| 153 ASSERT(!m_failed); | 247 ASSERT(!m_failed); |
| 154 m_finished = true; | 248 m_finished = true; |
| 155 | 249 |
| 156 if (document() && document()->frame() && document()->frame()->page() | 250 if (document() && document()->frame() && document()->frame()->page() |
| 157 && m_responseHttpStatusCode >= 200 && m_responseHttpStatusCode < 300) { | 251 && m_responseHttpStatusCode >= 200 && m_responseHttpStatusCode < 300) { |
| 158 document()->frame()->page()->chromeClient().ajaxSucceeded(document()->fr ame()); | 252 document()->frame()->page()->chromeClient().ajaxSucceeded(document()->fr ame()); |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 457 | 551 |
| 458 DEFINE_TRACE(FetchManager) | 552 DEFINE_TRACE(FetchManager) |
| 459 { | 553 { |
| 460 #if ENABLE(OILPAN) | 554 #if ENABLE(OILPAN) |
| 461 visitor->trace(m_executionContext); | 555 visitor->trace(m_executionContext); |
| 462 visitor->trace(m_loaders); | 556 visitor->trace(m_loaders); |
| 463 #endif | 557 #endif |
| 464 } | 558 } |
| 465 | 559 |
| 466 } // namespace blink | 560 } // namespace blink |
| OLD | NEW |