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 |