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

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

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

Powered by Google App Engine
This is Rietveld 408576698