Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(291)

Side by Side Diff: Source/modules/fetch/FetchManager.cpp

Issue 1171913003: **** [WIP] Blink-side: Implement FetchBlobDataConsumerHandle **** (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Clean up. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/ExceptionCode.h" 13 #include "core/dom/ExceptionCode.h"
14 #include "core/fetch/FetchUtils.h" 14 #include "core/fetch/FetchUtils.h"
15 #include "core/fileapi/Blob.h" 15 #include "core/fileapi/Blob.h"
16 #include "core/frame/csp/ContentSecurityPolicy.h" 16 #include "core/frame/csp/ContentSecurityPolicy.h"
17 #include "core/inspector/ConsoleMessage.h" 17 #include "core/inspector/ConsoleMessage.h"
18 #include "core/loader/ThreadableLoader.h" 18 #include "core/loader/ThreadableLoader.h"
19 #include "core/loader/ThreadableLoaderClient.h" 19 #include "core/loader/ThreadableLoaderClient.h"
20 #include "modules/fetch/Body.h" 20 #include "modules/fetch/Body.h"
21 #include "modules/fetch/BodyStreamBuffer.h" 21 #include "modules/fetch/BodyStreamBuffer.h"
22 #include "modules/fetch/DataConsumerHandleUtil.h"
22 #include "modules/fetch/FetchRequestData.h" 23 #include "modules/fetch/FetchRequestData.h"
23 #include "modules/fetch/Response.h" 24 #include "modules/fetch/Response.h"
24 #include "modules/fetch/ResponseInit.h" 25 #include "modules/fetch/ResponseInit.h"
25 #include "platform/network/ResourceError.h" 26 #include "platform/network/ResourceError.h"
26 #include "platform/network/ResourceRequest.h" 27 #include "platform/network/ResourceRequest.h"
27 #include "platform/network/ResourceResponse.h" 28 #include "platform/network/ResourceResponse.h"
28 #include "platform/weborigin/SecurityOrigin.h" 29 #include "platform/weborigin/SecurityOrigin.h"
29 #include "public/platform/WebURLRequest.h" 30 #include "public/platform/WebURLRequest.h"
30 #include "wtf/HashSet.h" 31 #include "wtf/HashSet.h"
31 32
32 namespace blink { 33 namespace blink {
33 34
34 class FetchManager::Loader final : public NoBaseWillBeGarbageCollectedFinalized< FetchManager::Loader>, public ThreadableLoaderClient, public ContextLifecycleObs erver { 35 class FetchManager::Loader final : public NoBaseWillBeGarbageCollectedFinalized< FetchManager::Loader>, public ThreadableLoaderClient, public ContextLifecycleObs erver {
35 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(FetchManager::Loader); 36 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(FetchManager::Loader);
36 public: 37 public:
37 static PassOwnPtrWillBeRawPtr<Loader> create(ExecutionContext* executionCont ext, FetchManager* fetchManager, PassRefPtrWillBeRawPtr<ScriptPromiseResolver> r esolver, FetchRequestData* request) 38 static PassOwnPtrWillBeRawPtr<Loader> create(ExecutionContext* executionCont ext, FetchManager* fetchManager, PassRefPtrWillBeRawPtr<ScriptPromiseResolver> r esolver, FetchRequestData* request)
38 { 39 {
39 return adoptPtrWillBeNoop(new Loader(executionContext, fetchManager, res olver, request)); 40 return adoptPtrWillBeNoop(new Loader(executionContext, fetchManager, res olver, request));
40 } 41 }
41 42
42 ~Loader() override; 43 ~Loader() override;
43 DECLARE_VIRTUAL_TRACE(); 44 DECLARE_VIRTUAL_TRACE();
44 45
45 void didReceiveResponse(unsigned long, const ResourceResponse&, PassOwnPtr<W ebDataConsumerHandle>) override; 46 void didReceiveResponse(unsigned long, const ResourceResponse&, PassOwnPtr<W ebDataConsumerHandle>) override;
46 void didReceiveData(const char*, unsigned) override;
47 void didFinishLoading(unsigned long, double) override; 47 void didFinishLoading(unsigned long, double) override;
48 void didFail(const ResourceError&) override; 48 void didFail(const ResourceError&) override;
49 void didFailAccessControlCheck(const ResourceError&) override; 49 void didFailAccessControlCheck(const ResourceError&) override;
50 void didFailRedirectCheck() override; 50 void didFailRedirectCheck() override;
51 51
52 void start(); 52 void start();
53 void cancel(); 53 void cancel();
54 void dispose(); 54 void dispose();
55 55
56 private: 56 private:
57 class Canceller : public BodyStreamBuffer::Canceller {
58 public:
59 explicit Canceller(Loader* loader) : m_loader(loader) { }
60 void cancel() override
61 {
62 if (m_loader)
63 m_loader->cancel();
64 }
65
66 #if !ENABLE(OILPAN)
67 // FIXME: This function should go away once Oilpan is shipped.
68 void disconnect() { m_loader = nullptr; }
69 #endif
70
71 DEFINE_INLINE_VIRTUAL_TRACE()
72 {
73 visitor->trace(m_loader);
74 BodyStreamBuffer::Canceller::trace(visitor);
75 }
76
77 private:
78 // |m_loader| is a raw ptr in non-oilpan circumstance to avoid
79 // circular reference. It will be cleared when the loader is destructed.
80 RawPtrWillBeMember<Loader> m_loader;
81 };
82
83
84 Loader(ExecutionContext*, FetchManager*, PassRefPtrWillBeRawPtr<ScriptPromis eResolver>, FetchRequestData*); 57 Loader(ExecutionContext*, FetchManager*, PassRefPtrWillBeRawPtr<ScriptPromis eResolver>, FetchRequestData*);
85 58
86 void performBasicFetch(); 59 void performBasicFetch();
87 void performNetworkError(const String& message); 60 void performNetworkError(const String& message);
88 void performHTTPFetch(bool corsFlag, bool corsPreflightFlag); 61 void performHTTPFetch(bool corsFlag, bool corsPreflightFlag);
89 void failed(const String& message); 62 void failed(const String& message);
90 void notifyFinished(); 63 void notifyFinished();
91 64
92 RawPtrWillBeMember<FetchManager> m_fetchManager; 65 RawPtrWillBeMember<FetchManager> m_fetchManager;
93 RefPtrWillBeMember<ScriptPromiseResolver> m_resolver; 66 RefPtrWillBeMember<ScriptPromiseResolver> m_resolver;
94 PersistentWillBeMember<FetchRequestData> m_request; 67 PersistentWillBeMember<FetchRequestData> m_request;
95 PersistentWillBeMember<BodyStreamBuffer> m_responseBuffer;
96 RefPtr<ThreadableLoader> m_loader; 68 RefPtr<ThreadableLoader> m_loader;
97 // Hold as a member in order to call |disconnect|. This member can be
98 // eliminated once Oilpan is shipped.
99 PersistentWillBeMember<Canceller> m_canceller;
100 bool m_failed; 69 bool m_failed;
101 bool m_finished; 70 bool m_finished;
102 }; 71 };
103 72
104 FetchManager::Loader::Loader(ExecutionContext* executionContext, FetchManager* f etchManager, PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver, FetchReques tData* request) 73 FetchManager::Loader::Loader(ExecutionContext* executionContext, FetchManager* f etchManager, PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver, FetchReques tData* request)
105 : ContextLifecycleObserver(executionContext) 74 : ContextLifecycleObserver(executionContext)
106 , m_fetchManager(fetchManager) 75 , m_fetchManager(fetchManager)
107 , m_resolver(resolver) 76 , m_resolver(resolver)
108 , m_request(request) 77 , m_request(request)
109 , m_canceller(new Canceller(this))
110 , m_failed(false) 78 , m_failed(false)
111 , m_finished(false) 79 , m_finished(false)
112 { 80 {
113 } 81 }
114 82
115 FetchManager::Loader::~Loader() 83 FetchManager::Loader::~Loader()
116 { 84 {
117 ASSERT(!m_loader); 85 ASSERT(!m_loader);
118 #if !ENABLE(OILPAN)
119 // FIXME: This should go away once Oilpan is shipped.
120 m_canceller->disconnect();
121 #endif
122 } 86 }
123 87
124 DEFINE_TRACE(FetchManager::Loader) 88 DEFINE_TRACE(FetchManager::Loader)
125 { 89 {
126 visitor->trace(m_fetchManager); 90 visitor->trace(m_fetchManager);
127 visitor->trace(m_resolver); 91 visitor->trace(m_resolver);
128 visitor->trace(m_request); 92 visitor->trace(m_request);
129 visitor->trace(m_responseBuffer);
130 visitor->trace(m_canceller);
131 ContextLifecycleObserver::trace(visitor); 93 ContextLifecycleObserver::trace(visitor);
132 } 94 }
133 95
134 void FetchManager::Loader::didReceiveResponse(unsigned long, const ResourceRespo nse& response, PassOwnPtr<WebDataConsumerHandle> handle) 96 void FetchManager::Loader::didReceiveResponse(unsigned long, const ResourceRespo nse& response, PassOwnPtr<WebDataConsumerHandle> handle)
135 { 97 {
136 // FIXME: Use |handle|. 98 ASSERT(handle);
137 ASSERT_UNUSED(handle, !handle);
138 // Recompute the tainting if the request was redirected to a different 99 // Recompute the tainting if the request was redirected to a different
139 // origin. 100 // origin.
140 if (!SecurityOrigin::create(response.url())->isSameSchemeHostPort(m_request- >origin().get())) { 101 if (!SecurityOrigin::create(response.url())->isSameSchemeHostPort(m_request- >origin().get())) {
141 switch (m_request->mode()) { 102 switch (m_request->mode()) {
142 case WebURLRequest::FetchRequestModeSameOrigin: 103 case WebURLRequest::FetchRequestModeSameOrigin:
143 ASSERT_NOT_REACHED(); 104 ASSERT_NOT_REACHED();
144 break; 105 break;
145 case WebURLRequest::FetchRequestModeNoCORS: 106 case WebURLRequest::FetchRequestModeNoCORS:
146 m_request->setResponseTainting(FetchRequestData::OpaqueTainting); 107 m_request->setResponseTainting(FetchRequestData::OpaqueTainting);
147 break; 108 break;
148 case WebURLRequest::FetchRequestModeCORS: 109 case WebURLRequest::FetchRequestModeCORS:
149 case WebURLRequest::FetchRequestModeCORSWithForcedPreflight: 110 case WebURLRequest::FetchRequestModeCORSWithForcedPreflight:
150 m_request->setResponseTainting(FetchRequestData::CORSTainting); 111 m_request->setResponseTainting(FetchRequestData::CORSTainting);
151 break; 112 break;
152 } 113 }
153 } 114 }
154 m_responseBuffer = new BodyStreamBuffer(m_canceller); 115 FetchResponseData* responseData = FetchResponseData::createWithBuffer(create FetchDataConsumerHandleFromWebHandle(handle));
155 FetchResponseData* responseData = FetchResponseData::createWithBuffer(m_resp onseBuffer);
156 responseData->setStatus(response.httpStatusCode()); 116 responseData->setStatus(response.httpStatusCode());
157 responseData->setStatusMessage(response.httpStatusText()); 117 responseData->setStatusMessage(response.httpStatusText());
158 for (auto& it : response.httpHeaderFields()) 118 for (auto& it : response.httpHeaderFields())
159 responseData->headerList()->append(it.key, it.value); 119 responseData->headerList()->append(it.key, it.value);
160 responseData->setURL(response.url()); 120 responseData->setURL(response.url());
161 responseData->setMIMEType(response.mimeType()); 121 responseData->setMIMEType(response.mimeType());
162 122
163 FetchResponseData* taintedResponse = responseData; 123 FetchResponseData* taintedResponse = responseData;
164 switch (m_request->tainting()) { 124 switch (m_request->tainting()) {
165 case FetchRequestData::BasicTainting: 125 case FetchRequestData::BasicTainting:
166 taintedResponse = responseData->createBasicFilteredResponse(); 126 taintedResponse = responseData->createBasicFilteredResponse();
167 break; 127 break;
168 case FetchRequestData::CORSTainting: 128 case FetchRequestData::CORSTainting:
169 taintedResponse = responseData->createCORSFilteredResponse(); 129 taintedResponse = responseData->createCORSFilteredResponse();
170 break; 130 break;
171 case FetchRequestData::OpaqueTainting: 131 case FetchRequestData::OpaqueTainting:
172 taintedResponse = responseData->createOpaqueFilteredResponse(); 132 taintedResponse = responseData->createOpaqueFilteredResponse();
173 break; 133 break;
174 } 134 }
175 Response* r = Response::create(m_resolver->executionContext(), taintedRespon se); 135 Response* r = Response::create(m_resolver->executionContext(), taintedRespon se);
176 r->headers()->setGuard(Headers::ImmutableGuard); 136 r->headers()->setGuard(Headers::ImmutableGuard);
177 m_resolver->resolve(r); 137 m_resolver->resolve(r);
178 m_resolver.clear(); 138 m_resolver.clear();
179 } 139 }
180 140
181 void FetchManager::Loader::didReceiveData(const char* data, unsigned size)
182 {
183 m_responseBuffer->write(DOMArrayBuffer::create(data, size));
184 }
185
186 void FetchManager::Loader::didFinishLoading(unsigned long, double) 141 void FetchManager::Loader::didFinishLoading(unsigned long, double)
187 { 142 {
188 ASSERT(m_responseBuffer);
189 ASSERT(!m_failed); 143 ASSERT(!m_failed);
190 m_responseBuffer->close();
191 m_responseBuffer.clear();
192 m_finished = true; 144 m_finished = true;
193 notifyFinished(); 145 notifyFinished();
194 } 146 }
195 147
196 void FetchManager::Loader::didFail(const ResourceError& error) 148 void FetchManager::Loader::didFail(const ResourceError& error)
197 { 149 {
198 if (error.isCancellation() || error.isTimeout() || error.domain() != errorDo mainBlinkInternal) 150 if (error.isCancellation() || error.isTimeout() || error.domain() != errorDo mainBlinkInternal)
199 failed(String()); 151 failed(String());
200 else 152 else
201 failed("Fetch API cannot load " + error.failingURL() + ". " + error.loca lizedDescription()); 153 failed("Fetch API cannot load " + error.failingURL() + ". " + error.loca lizedDescription());
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 performHTTPFetch(true, false); 257 performHTTPFetch(true, false);
306 } 258 }
307 259
308 void FetchManager::Loader::cancel() 260 void FetchManager::Loader::cancel()
309 { 261 {
310 m_finished = true; 262 m_finished = true;
311 if (m_loader) { 263 if (m_loader) {
312 m_loader->cancel(); 264 m_loader->cancel();
313 m_loader.clear(); 265 m_loader.clear();
314 } 266 }
315 if (m_responseBuffer) {
316 m_responseBuffer->close();
317 m_responseBuffer.clear();
318 }
319 if (m_resolver) { 267 if (m_resolver) {
320 // Note: In the current implementation this branch is never taken 268 // Note: In the current implementation this branch is never taken
321 // because this function can be called only through the body stream. 269 // because this function can be called only through the body stream.
322 ScriptState* scriptState = m_resolver->scriptState(); 270 ScriptState* scriptState = m_resolver->scriptState();
323 ScriptState::Scope scope(scriptState); 271 ScriptState::Scope scope(scriptState);
324 m_resolver->reject(V8ThrowException::createTypeError(scriptState->isolat e(), "fetch is cancelled")); 272 m_resolver->reject(V8ThrowException::createTypeError(scriptState->isolat e(), "fetch is cancelled"));
325 m_resolver.clear(); 273 m_resolver.clear();
326 } 274 }
327 275
328 notifyFinished(); 276 notifyFinished();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 323
376 if (m_request->method() != "GET" && m_request->method() != "HEAD") { 324 if (m_request->method() != "GET" && m_request->method() != "HEAD") {
377 RefPtr<BlobDataHandle> blobDataHandle = m_request->blobDataHandle(); 325 RefPtr<BlobDataHandle> blobDataHandle = m_request->blobDataHandle();
378 if (blobDataHandle.get()) { 326 if (blobDataHandle.get()) {
379 RefPtr<FormData> httpBody(FormData::create()); 327 RefPtr<FormData> httpBody(FormData::create());
380 httpBody->appendBlob(blobDataHandle->uuid(), blobDataHandle); 328 httpBody->appendBlob(blobDataHandle->uuid(), blobDataHandle);
381 request.setHTTPBody(httpBody); 329 request.setHTTPBody(httpBody);
382 } 330 }
383 } 331 }
384 332
333 request.setUseStreamOnResponse(true);
334
385 // "2. Append `Referer`/empty byte sequence, if |HTTPRequest|'s |referrer| 335 // "2. Append `Referer`/empty byte sequence, if |HTTPRequest|'s |referrer|
386 // is none, and `Referer`/|HTTPRequest|'s referrer, serialized and utf-8 336 // is none, and `Referer`/|HTTPRequest|'s referrer, serialized and utf-8
387 // encoded, otherwise, to HTTPRequest's header list. 337 // encoded, otherwise, to HTTPRequest's header list.
388 // We set the referrer using workerGlobalScope's URL in 338 // We set the referrer using workerGlobalScope's URL in
389 // WorkerThreadableLoader. 339 // WorkerThreadableLoader.
390 340
391 // "3. Append `Host`, ..." 341 // "3. Append `Host`, ..."
392 // FIXME: Implement this when the spec is fixed. 342 // FIXME: Implement this when the spec is fixed.
393 343
394 // "4.If |HTTPRequest|'s force Origin header flag is set, append `Origin`/ 344 // "4.If |HTTPRequest|'s force Origin header flag is set, append `Origin`/
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 performNetworkError("Can't create ThreadableLoader"); 381 performNetworkError("Can't create ThreadableLoader");
432 } 382 }
433 383
434 void FetchManager::Loader::failed(const String& message) 384 void FetchManager::Loader::failed(const String& message)
435 { 385 {
436 if (m_failed || m_finished) 386 if (m_failed || m_finished)
437 return; 387 return;
438 m_failed = true; 388 m_failed = true;
439 if (!message.isEmpty()) 389 if (!message.isEmpty())
440 executionContext()->addConsoleMessage(ConsoleMessage::create(JSMessageSo urce, ErrorMessageLevel, message)); 390 executionContext()->addConsoleMessage(ConsoleMessage::create(JSMessageSo urce, ErrorMessageLevel, message));
441 if (m_responseBuffer) { 391 if (m_resolver) {
442 m_responseBuffer->error(DOMException::create(NetworkError, "Failed to fe tch"));
443 m_responseBuffer.clear();
444 } else if (m_resolver) {
445 if (!m_resolver->executionContext() || m_resolver->executionContext()->a ctiveDOMObjectsAreStopped()) 392 if (!m_resolver->executionContext() || m_resolver->executionContext()->a ctiveDOMObjectsAreStopped())
446 return; 393 return;
447 ScriptState* state = m_resolver->scriptState(); 394 ScriptState* state = m_resolver->scriptState();
448 ScriptState::Scope scope(state); 395 ScriptState::Scope scope(state);
449 m_resolver->reject(V8ThrowException::createTypeError(state->isolate(), " Failed to fetch")); 396 m_resolver->reject(V8ThrowException::createTypeError(state->isolate(), " Failed to fetch"));
450 } 397 }
451 notifyFinished(); 398 notifyFinished();
452 } 399 }
453 400
454 void FetchManager::Loader::notifyFinished() 401 void FetchManager::Loader::notifyFinished()
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 449
503 DEFINE_TRACE(FetchManager) 450 DEFINE_TRACE(FetchManager)
504 { 451 {
505 #if ENABLE(OILPAN) 452 #if ENABLE(OILPAN)
506 visitor->trace(m_executionContext); 453 visitor->trace(m_executionContext);
507 visitor->trace(m_loaders); 454 visitor->trace(m_loaders);
508 #endif 455 #endif
509 } 456 }
510 457
511 } // namespace blink 458 } // namespace blink
OLDNEW
« no previous file with comments | « Source/modules/fetch/FetchBlobDataConsumerHandleTest.cpp ('k') | Source/modules/fetch/FetchRequestData.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698