| 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/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" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "wtf/RefPtr.h" | 21 #include "wtf/RefPtr.h" |
| 22 | 22 |
| 23 namespace blink { | 23 namespace blink { |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 class BodyConsumerBase : public GarbageCollectedFinalized<BodyConsumerBase>, pub
lic FetchDataLoader::Client { | 27 class BodyConsumerBase : public GarbageCollectedFinalized<BodyConsumerBase>, pub
lic FetchDataLoader::Client { |
| 28 WTF_MAKE_NONCOPYABLE(BodyConsumerBase); | 28 WTF_MAKE_NONCOPYABLE(BodyConsumerBase); |
| 29 USING_GARBAGE_COLLECTED_MIXIN(BodyConsumerBase); | 29 USING_GARBAGE_COLLECTED_MIXIN(BodyConsumerBase); |
| 30 public: | 30 public: |
| 31 explicit BodyConsumerBase(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> reso
lver) : m_resolver(resolver) {} | 31 explicit BodyConsumerBase(ScriptPromiseResolver* resolver) : m_resolver(reso
lver) {} |
| 32 PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver() { return m_resolver
; } | 32 ScriptPromiseResolver* resolver() { return m_resolver; } |
| 33 void didFetchDataLoadFailed() override | 33 void didFetchDataLoadFailed() override |
| 34 { | 34 { |
| 35 ScriptState::Scope scope(resolver()->scriptState()); | 35 ScriptState::Scope scope(resolver()->scriptState()); |
| 36 m_resolver->reject(V8ThrowException::createTypeError(resolver()->scriptS
tate()->isolate(), "Failed to fetch")); | 36 m_resolver->reject(V8ThrowException::createTypeError(resolver()->scriptS
tate()->isolate(), "Failed to fetch")); |
| 37 } | 37 } |
| 38 | 38 |
| 39 DEFINE_INLINE_TRACE() | 39 DEFINE_INLINE_TRACE() |
| 40 { | 40 { |
| 41 visitor->trace(m_resolver); | 41 visitor->trace(m_resolver); |
| 42 FetchDataLoader::Client::trace(visitor); | 42 FetchDataLoader::Client::trace(visitor); |
| 43 } | 43 } |
| 44 | 44 |
| 45 private: | 45 private: |
| 46 RefPtrWillBeMember<ScriptPromiseResolver> m_resolver; | 46 Member<ScriptPromiseResolver> m_resolver; |
| 47 }; | 47 }; |
| 48 | 48 |
| 49 class BodyBlobConsumer final : public BodyConsumerBase { | 49 class BodyBlobConsumer final : public BodyConsumerBase { |
| 50 WTF_MAKE_NONCOPYABLE(BodyBlobConsumer); | 50 WTF_MAKE_NONCOPYABLE(BodyBlobConsumer); |
| 51 public: | 51 public: |
| 52 explicit BodyBlobConsumer(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> reso
lver) : BodyConsumerBase(resolver) {} | 52 explicit BodyBlobConsumer(ScriptPromiseResolver* resolver) : BodyConsumerBas
e(resolver) {} |
| 53 | 53 |
| 54 void didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandle)
override | 54 void didFetchDataLoadedBlobHandle(PassRefPtr<BlobDataHandle> blobDataHandle)
override |
| 55 { | 55 { |
| 56 resolver()->resolve(Blob::create(blobDataHandle)); | 56 resolver()->resolve(Blob::create(blobDataHandle)); |
| 57 } | 57 } |
| 58 }; | 58 }; |
| 59 | 59 |
| 60 class BodyArrayBufferConsumer final : public BodyConsumerBase { | 60 class BodyArrayBufferConsumer final : public BodyConsumerBase { |
| 61 WTF_MAKE_NONCOPYABLE(BodyArrayBufferConsumer); | 61 WTF_MAKE_NONCOPYABLE(BodyArrayBufferConsumer); |
| 62 public: | 62 public: |
| 63 explicit BodyArrayBufferConsumer(PassRefPtrWillBeRawPtr<ScriptPromiseResolve
r> resolver) : BodyConsumerBase(resolver) {} | 63 explicit BodyArrayBufferConsumer(ScriptPromiseResolver* resolver) : BodyCons
umerBase(resolver) {} |
| 64 | 64 |
| 65 void didFetchDataLoadedArrayBuffer(PassRefPtr<DOMArrayBuffer> arrayBuffer) o
verride | 65 void didFetchDataLoadedArrayBuffer(PassRefPtr<DOMArrayBuffer> arrayBuffer) o
verride |
| 66 { | 66 { |
| 67 resolver()->resolve(arrayBuffer); | 67 resolver()->resolve(arrayBuffer); |
| 68 } | 68 } |
| 69 }; | 69 }; |
| 70 | 70 |
| 71 class BodyTextConsumer final : public BodyConsumerBase { | 71 class BodyTextConsumer final : public BodyConsumerBase { |
| 72 WTF_MAKE_NONCOPYABLE(BodyTextConsumer); | 72 WTF_MAKE_NONCOPYABLE(BodyTextConsumer); |
| 73 public: | 73 public: |
| 74 explicit BodyTextConsumer(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> reso
lver) : BodyConsumerBase(resolver) {} | 74 explicit BodyTextConsumer(ScriptPromiseResolver* resolver) : BodyConsumerBas
e(resolver) {} |
| 75 | 75 |
| 76 void didFetchDataLoadedString(const String& string) override | 76 void didFetchDataLoadedString(const String& string) override |
| 77 { | 77 { |
| 78 resolver()->resolve(string); | 78 resolver()->resolve(string); |
| 79 } | 79 } |
| 80 }; | 80 }; |
| 81 | 81 |
| 82 class BodyJsonConsumer final : public BodyConsumerBase { | 82 class BodyJsonConsumer final : public BodyConsumerBase { |
| 83 WTF_MAKE_NONCOPYABLE(BodyJsonConsumer); | 83 WTF_MAKE_NONCOPYABLE(BodyJsonConsumer); |
| 84 public: | 84 public: |
| 85 explicit BodyJsonConsumer(PassRefPtrWillBeRawPtr<ScriptPromiseResolver> reso
lver) : BodyConsumerBase(resolver) {} | 85 explicit BodyJsonConsumer(ScriptPromiseResolver* resolver) : BodyConsumerBas
e(resolver) {} |
| 86 | 86 |
| 87 void didFetchDataLoadedString(const String& string) override | 87 void didFetchDataLoadedString(const String& string) override |
| 88 { | 88 { |
| 89 if (!resolver()->executionContext() || resolver()->executionContext()->a
ctiveDOMObjectsAreStopped()) | 89 if (!resolver()->executionContext() || resolver()->executionContext()->a
ctiveDOMObjectsAreStopped()) |
| 90 return; | 90 return; |
| 91 ScriptState::Scope scope(resolver()->scriptState()); | 91 ScriptState::Scope scope(resolver()->scriptState()); |
| 92 v8::Isolate* isolate = resolver()->scriptState()->isolate(); | 92 v8::Isolate* isolate = resolver()->scriptState()->isolate(); |
| 93 v8::Local<v8::String> inputString = v8String(isolate, string); | 93 v8::Local<v8::String> inputString = v8String(isolate, string); |
| 94 v8::TryCatch trycatch; | 94 v8::TryCatch trycatch; |
| 95 v8::Local<v8::Value> parsed; | 95 v8::Local<v8::Value> parsed; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 109 | 109 |
| 110 // 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 |
| 111 // 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 |
| 112 // 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 |
| 113 // first check the ExecutionContext and return immediately if it's already | 113 // first check the ExecutionContext and return immediately if it's already |
| 114 // gone (which means that the V8::TerminateExecution() signal has been sent | 114 // gone (which means that the V8::TerminateExecution() signal has been sent |
| 115 // to this worker thread). | 115 // to this worker thread). |
| 116 if (!scriptState->executionContext()) | 116 if (!scriptState->executionContext()) |
| 117 return ScriptPromise(); | 117 return ScriptPromise(); |
| 118 | 118 |
| 119 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::
create(scriptState); | 119 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
| 120 ScriptPromise promise = resolver->promise(); | 120 ScriptPromise promise = resolver->promise(); |
| 121 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader:
:createLoaderAsArrayBuffer(), new BodyArrayBufferConsumer(resolver)); | 121 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader:
:createLoaderAsArrayBuffer(), new BodyArrayBufferConsumer(resolver)); |
| 122 return promise; | 122 return promise; |
| 123 } | 123 } |
| 124 | 124 |
| 125 ScriptPromise Body::blob(ScriptState* scriptState) | 125 ScriptPromise Body::blob(ScriptState* scriptState) |
| 126 { | 126 { |
| 127 if (bodyUsed()) | 127 if (bodyUsed()) |
| 128 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr
ror(scriptState->isolate(), "Already read")); | 128 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr
ror(scriptState->isolate(), "Already read")); |
| 129 | 129 |
| 130 // See above comment. | 130 // See above comment. |
| 131 if (!scriptState->executionContext()) | 131 if (!scriptState->executionContext()) |
| 132 return ScriptPromise(); | 132 return ScriptPromise(); |
| 133 | 133 |
| 134 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::
create(scriptState); | 134 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
| 135 ScriptPromise promise = resolver->promise(); | 135 ScriptPromise promise = resolver->promise(); |
| 136 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader:
:createLoaderAsBlobHandle(mimeType()), new BodyBlobConsumer(resolver)); | 136 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader:
:createLoaderAsBlobHandle(mimeType()), new BodyBlobConsumer(resolver)); |
| 137 return promise; | 137 return promise; |
| 138 | 138 |
| 139 } | 139 } |
| 140 | 140 |
| 141 ScriptPromise Body::json(ScriptState* scriptState) | 141 ScriptPromise Body::json(ScriptState* scriptState) |
| 142 { | 142 { |
| 143 if (bodyUsed()) | 143 if (bodyUsed()) |
| 144 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr
ror(scriptState->isolate(), "Already read")); | 144 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr
ror(scriptState->isolate(), "Already read")); |
| 145 | 145 |
| 146 // See above comment. | 146 // See above comment. |
| 147 if (!scriptState->executionContext()) | 147 if (!scriptState->executionContext()) |
| 148 return ScriptPromise(); | 148 return ScriptPromise(); |
| 149 | 149 |
| 150 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::
create(scriptState); | 150 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
| 151 ScriptPromise promise = resolver->promise(); | 151 ScriptPromise promise = resolver->promise(); |
| 152 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader:
:createLoaderAsString(), new BodyJsonConsumer(resolver)); | 152 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader:
:createLoaderAsString(), new BodyJsonConsumer(resolver)); |
| 153 return promise; | 153 return promise; |
| 154 } | 154 } |
| 155 | 155 |
| 156 ScriptPromise Body::text(ScriptState* scriptState) | 156 ScriptPromise Body::text(ScriptState* scriptState) |
| 157 { | 157 { |
| 158 if (bodyUsed()) | 158 if (bodyUsed()) |
| 159 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr
ror(scriptState->isolate(), "Already read")); | 159 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr
ror(scriptState->isolate(), "Already read")); |
| 160 | 160 |
| 161 // See above comment. | 161 // See above comment. |
| 162 if (!scriptState->executionContext()) | 162 if (!scriptState->executionContext()) |
| 163 return ScriptPromise(); | 163 return ScriptPromise(); |
| 164 | 164 |
| 165 RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::
create(scriptState); | 165 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
| 166 ScriptPromise promise = resolver->promise(); | 166 ScriptPromise promise = resolver->promise(); |
| 167 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader:
:createLoaderAsString(), new BodyTextConsumer(resolver)); | 167 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoader:
:createLoaderAsString(), new BodyTextConsumer(resolver)); |
| 168 return promise; | 168 return promise; |
| 169 } | 169 } |
| 170 | 170 |
| 171 ReadableByteStream* Body::body() | 171 ReadableByteStream* Body::body() |
| 172 { | 172 { |
| 173 UseCounter::count(executionContext(), UseCounter::FetchBodyStream); | 173 UseCounter::count(executionContext(), UseCounter::FetchBodyStream); |
| 174 return bodyBuffer()->stream(); | 174 return bodyBuffer()->stream(); |
| 175 } | 175 } |
| 176 | 176 |
| 177 bool Body::bodyUsed() | 177 bool Body::bodyUsed() |
| 178 { | 178 { |
| 179 return m_bodyPassed || body()->isLocked(); | 179 return m_bodyPassed || body()->isLocked(); |
| 180 } | 180 } |
| 181 | 181 |
| 182 bool Body::hasPendingActivity() const | 182 bool Body::hasPendingActivity() const |
| 183 { | 183 { |
| 184 if (executionContext()->activeDOMObjectsAreStopped()) | 184 if (executionContext()->activeDOMObjectsAreStopped()) |
| 185 return false; | 185 return false; |
| 186 return bodyBuffer()->hasPendingActivity(); | 186 return bodyBuffer()->hasPendingActivity(); |
| 187 } | 187 } |
| 188 | 188 |
| 189 Body::Body(ExecutionContext* context) : ActiveDOMObject(context), m_bodyPassed(f
alse) | 189 Body::Body(ExecutionContext* context) : ActiveDOMObject(context), m_bodyPassed(f
alse) |
| 190 { | 190 { |
| 191 suspendIfNeeded(); | 191 suspendIfNeeded(); |
| 192 } | 192 } |
| 193 | 193 |
| 194 } // namespace blink | 194 } // namespace blink |
| OLD | NEW |