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 |