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

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

Issue 1233573002: [Fetch API] Remove DrainingBuffer. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 5 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 | Annotate | Revision Log
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/Body.h" 6 #include "modules/fetch/Body.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/V8ArrayBuffer.h" 11 #include "bindings/core/v8/V8ArrayBuffer.h"
12 #include "bindings/core/v8/V8ThrowException.h" 12 #include "bindings/core/v8/V8ThrowException.h"
13 #include "core/dom/DOMArrayBuffer.h" 13 #include "core/dom/DOMArrayBuffer.h"
14 #include "core/dom/DOMTypedArray.h" 14 #include "core/dom/DOMTypedArray.h"
15 #include "core/dom/ExceptionCode.h" 15 #include "core/dom/ExceptionCode.h"
16 #include "core/fileapi/Blob.h" 16 #include "core/fileapi/Blob.h"
17 #include "core/frame/UseCounter.h" 17 #include "core/frame/UseCounter.h"
18 #include "core/streams/ReadableByteStream.h"
19 #include "core/streams/ReadableByteStreamReader.h"
20 #include "core/streams/UnderlyingSource.h"
21 #include "modules/fetch/BodyStreamBuffer.h" 18 #include "modules/fetch/BodyStreamBuffer.h"
22 #include "modules/fetch/DataConsumerHandleUtil.h" 19 #include "modules/fetch/FetchDataLoader.h"
23 #include "modules/fetch/FetchBlobDataConsumerHandle.h" 20 #include "wtf/PassRefPtr.h"
21 #include "wtf/RefPtr.h"
24 22
25 namespace blink { 23 namespace blink {
26 24
27 class Body::ReadableStreamSource : public GarbageCollectedFinalized<Body::Readab leStreamSource>, public UnderlyingSource, public WebDataConsumerHandle::Client, public BodyStreamBuffer::DrainingStreamNotificationClient { 25 namespace {
28 USING_GARBAGE_COLLECTED_MIXIN(ReadableStreamSource); 26
27 class BodyConsumerBase : public GarbageCollectedFinalized<BodyConsumerBase>, pub lic FetchDataLoader::Client {
28 WTF_MAKE_NONCOPYABLE(BodyConsumerBase);
29 USING_GARBAGE_COLLECTED_MIXIN(BodyConsumerBase);
29 public: 30 public:
30 ReadableStreamSource(ExecutionContext* executionContext, BodyStreamBuffer* b uffer) 31 explicit BodyConsumerBase(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> reso lver) : m_resolver(resolver) {}
31 : m_bodyStreamBuffer(buffer) 32 PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver() { return m_resolver ; }
32 , m_streamNeedsMore(false) 33 void didFetchDataLoadFailed() override
33 #if ENABLE(ASSERT)
34 , m_drained(false)
35 , m_isCloseCalled(false)
36 , m_isErrorCalled(false)
37 #endif
38 { 34 {
39 if (m_bodyStreamBuffer) 35 ScriptState::Scope scope(resolver()->scriptState());
40 obtainReader(); 36 m_resolver->reject(V8ThrowException::createTypeError(resolver()->scriptS tate()->isolate(), "Failed to fetch"));
41 } 37 }
42 38
43 ~ReadableStreamSource() override { } 39 DEFINE_INLINE_TRACE()
44
45 void startStream(ReadableByteStream* stream)
46 { 40 {
47 m_stream = stream; 41 visitor->trace(m_resolver);
48 stream->didSourceStart(); 42 FetchDataLoader::Client::trace(visitor);
49 if (!m_bodyStreamBuffer)
50 close();
51 }
52 // Creates a new BodyStreamBuffer to drain the data.
53 PassOwnPtr<DrainingBodyStreamBuffer> createDrainingStream()
54 {
55 if (!m_bodyStreamBuffer)
56 return nullptr;
57
58 #if ENABLE(ASSERT)
59 ASSERT(!m_drained);
60 m_drained = true;
61 ASSERT(!(m_stream->stateInternal() == ReadableByteStream::Closed && !m_i sCloseCalled));
62 ASSERT(!(m_stream->stateInternal() == ReadableByteStream::Errored && !m_ isErrorCalled));
63 #endif
64
65 m_reader.clear();
66 return DrainingBodyStreamBuffer::create(m_bodyStreamBuffer, this);
67 }
68
69 DEFINE_INLINE_VIRTUAL_TRACE()
70 {
71 visitor->trace(m_bodyStreamBuffer);
72 visitor->trace(m_stream);
73 UnderlyingSource::trace(visitor);
74 DrainingStreamNotificationClient::trace(visitor);
75 }
76
77 void close()
78 {
79 m_reader.clear();
80 m_stream->close();
81 if (m_bodyStreamBuffer)
82 m_bodyStreamBuffer = BodyStreamBuffer::createEmpty();
83 #if ENABLE(ASSERT)
84 m_isCloseCalled = true;
85 #endif
86 }
87
88 void error()
89 {
90 m_reader.clear();
91 m_stream->error(DOMException::create(NetworkError, "network error"));
92 if (m_bodyStreamBuffer)
93 m_bodyStreamBuffer = BodyStreamBuffer::create(createFetchDataConsume rHandleFromWebHandle(createUnexpectedErrorDataConsumerHandle()));
94 #if ENABLE(ASSERT)
95 m_isErrorCalled = true;
96 #endif
97 } 43 }
98 44
99 private: 45 private:
100 void obtainReader() 46 RefPtrWillBeMember<ScriptPromiseResolver> m_resolver;
101 {
102 m_reader = m_bodyStreamBuffer->handle()->obtainReader(this);
103 }
104
105 void didFetchDataLoadFinishedFromDrainingStream()
106 {
107 ASSERT(m_bodyStreamBuffer);
108 ASSERT(m_drained);
109
110 #if ENABLE(ASSERT)
111 m_drained = false;
112 #endif
113 obtainReader();
114 // We have to call didGetReadable() now to call close()/error() if
115 // necessary.
116 // didGetReadable() would be called asynchronously, but it is too late.
117 didGetReadable();
118 }
119
120 void didGetReadable() override
121 {
122 if (!m_streamNeedsMore) {
123 // Perform zero-length read to call close()/error() early.
124 size_t readSize;
125 WebDataConsumerHandle::Result result = m_reader->read(nullptr, 0, We bDataConsumerHandle::FlagNone, &readSize);
126 switch (result) {
127 case WebDataConsumerHandle::Ok:
128 case WebDataConsumerHandle::ShouldWait:
129 return;
130 case WebDataConsumerHandle::Done:
131 close();
132 return;
133 case WebDataConsumerHandle::Busy:
134 case WebDataConsumerHandle::ResourceExhausted:
135 case WebDataConsumerHandle::UnexpectedError:
136 error();
137 return;
138 }
139 }
140
141 processData();
142 }
143
144 // UnderlyingSource functions.
145 void pullSource() override
146 {
147 ASSERT(!m_streamNeedsMore);
148 m_streamNeedsMore = true;
149
150 ASSERT(!m_drained);
151
152 processData();
153 }
154
155 ScriptPromise cancelSource(ScriptState* scriptState, ScriptValue reason) ove rride
156 {
157 close();
158 return ScriptPromise::cast(scriptState, v8::Undefined(scriptState->isola te()));
159 }
160
161 // Reads data and writes the data to |m_stream|, as long as data are
162 // available and the stream has pending reads.
163 void processData()
164 {
165 ASSERT(m_reader);
166 while (m_streamNeedsMore) {
167 const void* buffer;
168 size_t available;
169 WebDataConsumerHandle::Result result = m_reader->beginRead(&buffer, WebDataConsumerHandle::FlagNone, &available);
170 switch (result) {
171 case WebDataConsumerHandle::Ok:
172 m_streamNeedsMore = m_stream->enqueue(DOMUint8Array::create(stat ic_cast<const unsigned char*>(buffer), available));
173 m_reader->endRead(available);
174 break;
175
176 case WebDataConsumerHandle::Done:
177 close();
178 return;
179
180 case WebDataConsumerHandle::ShouldWait:
181 return;
182
183 case WebDataConsumerHandle::Busy:
184 case WebDataConsumerHandle::ResourceExhausted:
185 case WebDataConsumerHandle::UnexpectedError:
186 error();
187 return;
188 }
189 }
190 }
191
192 // Source of data.
193 Member<BodyStreamBuffer> m_bodyStreamBuffer;
194 OwnPtr<FetchDataConsumerHandle::Reader> m_reader;
195
196 Member<ReadableByteStream> m_stream;
197 bool m_streamNeedsMore;
198 #if ENABLE(ASSERT)
199 bool m_drained;
200 bool m_isCloseCalled;
201 bool m_isErrorCalled;
202 #endif
203 }; 47 };
204 48
205 ScriptPromise Body::readAsync(ScriptState* scriptState, ResponseType type) 49 class BodyBlobConsumer final : public BodyConsumerBase {
50 WTF_MAKE_NONCOPYABLE(BodyBlobConsumer);
51 public:
52 explicit BodyBlobConsumer(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> reso lver) : BodyConsumerBase(resolver) {}
53
54 void didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandle) override
55 {
56 resolver()->resolve(Blob::create(blobDataHandle));
57 }
58 };
59
60 class BodyArrayBufferConsumer final : public BodyConsumerBase {
61 WTF_MAKE_NONCOPYABLE(BodyArrayBufferConsumer);
62 public:
63 explicit BodyArrayBufferConsumer(PassRefPtrWillBeRawPtr<ScriptPromiseResolve r> resolver) : BodyConsumerBase(resolver) {}
64
65 void didFetchDataLoadedArrayBuffer(PassRefPtr<DOMArrayBuffer> arrayBuffer) o verride
66 {
67 resolver()->resolve(arrayBuffer);
68 }
69 };
70
71 class BodyTextConsumer final : public BodyConsumerBase {
72 WTF_MAKE_NONCOPYABLE(BodyTextConsumer);
73 public:
74 explicit BodyTextConsumer(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> reso lver) : BodyConsumerBase(resolver) {}
75
76 void didFetchDataLoadedString(const String& string) override
77 {
78 resolver()->resolve(string);
79 }
80 };
81
82 class BodyJsonConsumer final : public BodyConsumerBase {
83 WTF_MAKE_NONCOPYABLE(BodyJsonConsumer);
84 public:
85 explicit BodyJsonConsumer(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> reso lver) : BodyConsumerBase(resolver) {}
86
87 void didFetchDataLoadedString(const String& string) override
88 {
89 if (!resolver()->executionContext() || resolver()->executionContext()->a ctiveDOMObjectsAreStopped())
90 return;
91 ScriptState::Scope scope(resolver()->scriptState());
92 v8::Isolate* isolate = resolver()->scriptState()->isolate();
93 v8::Local<v8::String> inputString = v8String(isolate, string);
94 v8::TryCatch trycatch;
95 v8::Local<v8::Value> parsed;
96 if (v8Call(v8::JSON::Parse(isolate, inputString), parsed, trycatch))
97 resolver()->resolve(parsed);
98 else
99 resolver()->reject(trycatch.Exception());
100 }
101 };
102
103 } // namespace
104
105 ScriptPromise Body::arrayBuffer(ScriptState* scriptState)
206 { 106 {
207 if (bodyUsed()) 107 if (bodyUsed())
208 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Already read")); 108 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Already read"));
209 109
210 // When the main thread sends a V8::TerminateExecution() signal to a worker 110 // When the main thread sends a V8::TerminateExecution() signal to a worker
211 // thread, any V8 API on the worker thread starts returning an empty 111 // thread, any V8 API on the worker thread starts returning an empty
212 // handle. This can happen in Body::readAsync. To avoid the situation, we 112 // handle. This can happen in Body::readAsync. To avoid the situation, we
213 // first check the ExecutionContext and return immediately if it's already 113 // first check the ExecutionContext and return immediately if it's already
214 // gone (which means that the V8::TerminateExecution() signal has been sent 114 // gone (which means that the V8::TerminateExecution() signal has been sent
215 // to this worker thread). 115 // to this worker thread).
216 ExecutionContext* executionContext = scriptState->executionContext(); 116 if (!scriptState->executionContext())
217 if (!executionContext)
218 return ScriptPromise(); 117 return ScriptPromise();
219 118
220 lockBody(); 119 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
221 m_responseType = type; 120 ScriptPromise promise = resolver->promise();
222 121 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader: :createLoaderAsArrayBuffer(), new BodyArrayBufferConsumer(resolver));
223 ASSERT(!m_resolver);
224 m_resolver = ScriptPromiseResolver::create(scriptState);
225 ScriptPromise promise = m_resolver->promise();
226
227 if (m_stream->stateInternal() == ReadableStream::Closed) {
228 resolveWithEmptyDataSynchronously();
229 } else if (m_stream->stateInternal() == ReadableStream::Errored) {
230 m_resolver->reject(m_stream->storedException());
231 m_resolver.clear();
232 } else {
233 readAsyncFromDrainingBodyStreamBuffer(createDrainingStream(), mimeType() );
234 }
235 return promise; 122 return promise;
236 } 123 }
237 124
238 void Body::resolveWithEmptyDataSynchronously()
239 {
240 // We resolve the resolver manually in order not to use member
241 // variables.
242 switch (m_responseType) {
243 case ResponseAsArrayBuffer:
244 m_resolver->resolve(DOMArrayBuffer::create(nullptr, 0));
245 break;
246 case ResponseAsBlob: {
247 OwnPtr<BlobData> blobData = BlobData::create();
248 blobData->setContentType(mimeType());
249 m_resolver->resolve(Blob::create(BlobDataHandle::create(blobData.release (), 0)));
250 break;
251 }
252 case ResponseAsText:
253 m_resolver->resolve(String());
254 break;
255 case ResponseAsFormData:
256 // TODO(yhirano): Implement this.
257 ASSERT_NOT_REACHED();
258 break;
259 case ResponseAsJSON: {
260 ScriptState::Scope scope(m_resolver->scriptState());
261 m_resolver->reject(V8ThrowException::createSyntaxError(m_resolver->scrip tState()->isolate(), "Unexpected end of input"));
262 break;
263 }
264 case ResponseUnknown:
265 ASSERT_NOT_REACHED();
266 break;
267 }
268 m_resolver.clear();
269 }
270
271 void Body::readAsyncFromDrainingBodyStreamBuffer(PassOwnPtr<DrainingBodyStreamBu ffer> buffer, const String& mimeType)
272 {
273 if (!buffer) {
274 resolveWithEmptyDataSynchronously();
275 m_streamSource->close();
276 return;
277 }
278
279 FetchDataLoader* fetchDataLoader = nullptr;
280
281 switch (m_responseType) {
282 case ResponseAsArrayBuffer:
283 fetchDataLoader = FetchDataLoader::createLoaderAsArrayBuffer();
284 break;
285
286 case ResponseAsJSON:
287 case ResponseAsText:
288 fetchDataLoader = FetchDataLoader::createLoaderAsString();
289 break;
290
291 case ResponseAsBlob:
292 fetchDataLoader = FetchDataLoader::createLoaderAsBlobHandle(mimeType);
293 break;
294
295 case ResponseAsFormData:
296 // FIXME: Implement this.
297 ASSERT_NOT_REACHED();
298 return;
299
300 default:
301 ASSERT_NOT_REACHED();
302 return;
303 }
304
305 buffer->startLoading(fetchDataLoader, this);
306 }
307
308 ScriptPromise Body::arrayBuffer(ScriptState* scriptState)
309 {
310 return readAsync(scriptState, ResponseAsArrayBuffer);
311 }
312
313 ScriptPromise Body::blob(ScriptState* scriptState) 125 ScriptPromise Body::blob(ScriptState* scriptState)
314 { 126 {
315 return readAsync(scriptState, ResponseAsBlob); 127 if (bodyUsed())
316 } 128 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Already read"));
317 129
318 ScriptPromise Body::formData(ScriptState* scriptState) 130 // See above comment.
319 { 131 if (!scriptState->executionContext())
320 return readAsync(scriptState, ResponseAsFormData); 132 return ScriptPromise();
133
134 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
135 ScriptPromise promise = resolver->promise();
136 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader: :createLoaderAsBlobHandle(mimeType()), new BodyBlobConsumer(resolver));
137 return promise;
138
321 } 139 }
322 140
323 ScriptPromise Body::json(ScriptState* scriptState) 141 ScriptPromise Body::json(ScriptState* scriptState)
324 { 142 {
325 return readAsync(scriptState, ResponseAsJSON); 143 if (bodyUsed())
144 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Already read"));
145
146 // See above comment.
147 if (!scriptState->executionContext())
148 return ScriptPromise();
149
150 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
151 ScriptPromise promise = resolver->promise();
152 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader: :createLoaderAsString(), new BodyJsonConsumer(resolver));
153 return promise;
326 } 154 }
327 155
328 ScriptPromise Body::text(ScriptState* scriptState) 156 ScriptPromise Body::text(ScriptState* scriptState)
329 { 157 {
330 return readAsync(scriptState, ResponseAsText); 158 if (bodyUsed())
159 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Already read"));
160
161 // See above comment.
162 if (!scriptState->executionContext())
163 return ScriptPromise();
164
165 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver:: create(scriptState);
166 ScriptPromise promise = resolver->promise();
167 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader: :createLoaderAsString(), new BodyTextConsumer(resolver));
168 return promise;
331 } 169 }
332 170
333 ReadableByteStream* Body::body() 171 ReadableByteStream* Body::body()
334 { 172 {
335 UseCounter::count(executionContext(), UseCounter::FetchBodyStream); 173 UseCounter::count(executionContext(), UseCounter::FetchBodyStream);
336 return m_stream; 174 return bodyBuffer()->stream();
337 } 175 }
338 176
339 bool Body::bodyUsed() const 177 bool Body::bodyUsed()
340 { 178 {
341 return m_bodyUsed || m_stream->isLocked(); 179 return m_bodyPassed || body()->isLocked();
342 }
343
344 void Body::lockBody(LockBodyOption option)
345 {
346 ASSERT(!bodyUsed());
347 if (option == PassBody)
348 m_bodyUsed = true;
349 ASSERT(!m_stream->isLocked());
350 TrackExceptionState exceptionState;
351 m_stream->getBytesReader(executionContext(), exceptionState);
352 ASSERT(!exceptionState.hadException());
353 }
354
355 void Body::setBody(BodyStreamBuffer* buffer)
356 {
357 m_streamSource = new ReadableStreamSource(executionContext(), buffer);
358 m_stream = new ReadableByteStream(m_streamSource, new ReadableByteStream::St rictStrategy);
359 m_streamSource->startStream(m_stream);
360 }
361
362 PassOwnPtr<DrainingBodyStreamBuffer> Body::createDrainingStream()
363 {
364 return m_streamSource->createDrainingStream();
365 } 180 }
366 181
367 bool Body::hasPendingActivity() const 182 bool Body::hasPendingActivity() const
368 { 183 {
369 if (executionContext()->activeDOMObjectsAreStopped()) 184 if (executionContext()->activeDOMObjectsAreStopped())
370 return false; 185 return false;
371 if (m_resolver) 186 return bodyBuffer()->hasPendingActivity();
372 return true;
373 if (m_stream->isLocked())
374 return true;
375 return false;
376 } 187 }
377 188
378 DEFINE_TRACE(Body) 189 Body::Body(ExecutionContext* context) : ActiveDOMObject(context), m_bodyPassed(f alse)
379 { 190 {
380 visitor->trace(m_resolver); 191 suspendIfNeeded();
381 visitor->trace(m_stream);
382 visitor->trace(m_streamSource);
383 ActiveDOMObject::trace(visitor);
384 FetchDataLoader::Client::trace(visitor);
385 }
386
387 Body::Body(ExecutionContext* context)
388 : ActiveDOMObject(context)
389 , m_bodyUsed(false)
390 , m_responseType(ResponseType::ResponseUnknown)
391 , m_streamSource(new ReadableStreamSource(context, nullptr))
392 , m_stream(new ReadableByteStream(m_streamSource, new ReadableByteStream::St rictStrategy))
393 {
394 m_streamSource->startStream(m_stream);
395 }
396
397 void Body::resolveJSON(const String& string)
398 {
399 ASSERT(m_responseType == ResponseAsJSON);
400 ScriptState::Scope scope(m_resolver->scriptState());
401 v8::Isolate* isolate = m_resolver->scriptState()->isolate();
402 v8::Local<v8::String> inputString = v8String(isolate, string);
403 v8::TryCatch trycatch;
404 v8::Local<v8::Value> parsed;
405 if (v8Call(v8::JSON::Parse(isolate, inputString), parsed, trycatch))
406 m_resolver->resolve(parsed);
407 else
408 m_resolver->reject(trycatch.Exception());
409 }
410
411 // FetchDataLoader::Client functions.
412 void Body::didFetchDataLoadFailed()
413 {
414 if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
415 return;
416
417 if (m_resolver) {
418 if (!m_resolver->executionContext() || m_resolver->executionContext()->a ctiveDOMObjectsAreStopped()) {
419 m_resolver.clear();
420 return;
421 }
422 ScriptState* state = m_resolver->scriptState();
423 ScriptState::Scope scope(state);
424 m_resolver->reject(V8ThrowException::createTypeError(state->isolate(), " Failed to fetch"));
425 m_resolver.clear();
426 }
427 }
428
429 void Body::didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandl e)
430 {
431 if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
432 return;
433
434 ASSERT(m_responseType == ResponseAsBlob);
435 m_resolver->resolve(Blob::create(blobDataHandle));
436 m_resolver.clear();
437 }
438
439 void Body::didFetchDataLoadedArrayBuffer(PassRefPtr<DOMArrayBuffer> arrayBuffer)
440 {
441 if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
442 return;
443
444 ASSERT(m_responseType == ResponseAsArrayBuffer);
445 m_resolver->resolve(arrayBuffer);
446 m_resolver.clear();
447 }
448
449 void Body::didFetchDataLoadedString(const String& str)
450 {
451 if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
452 return;
453
454 switch (m_responseType) {
455 case ResponseAsJSON:
456 resolveJSON(str);
457 break;
458 case ResponseAsText:
459 m_resolver->resolve(str);
460 break;
461 default:
462 ASSERT_NOT_REACHED();
463 }
464
465 m_resolver.clear();
466 } 192 }
467 193
468 } // namespace blink 194 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698