Chromium Code Reviews| 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 } | 100 } |
| 101 }; | 101 }; |
| 102 | 102 |
| 103 } // namespace | 103 } // namespace |
| 104 | 104 |
| 105 ScriptPromise Body::arrayBuffer(ScriptState* scriptState) | 105 ScriptPromise Body::arrayBuffer(ScriptState* scriptState) |
| 106 { | 106 { |
| 107 if (m_opaque) | 107 if (m_opaque) |
| 108 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "The body is opaque.")); | 108 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "The body is opaque.")); |
| 109 | 109 |
| 110 if (bodyUsed()) | 110 if (isBodyLocked() || bodyUsed()) |
| 111 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Already read")); | 111 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Already read")); |
| 112 | 112 |
| 113 // When the main thread sends a V8::TerminateExecution() signal to a worker | 113 // When the main thread sends a V8::TerminateExecution() signal to a worker |
| 114 // thread, any V8 API on the worker thread starts returning an empty | 114 // thread, any V8 API on the worker thread starts returning an empty |
| 115 // handle. This can happen in Body::readAsync. To avoid the situation, we | 115 // handle. This can happen in Body::readAsync. To avoid the situation, we |
| 116 // first check the ExecutionContext and return immediately if it's already | 116 // first check the ExecutionContext and return immediately if it's already |
| 117 // gone (which means that the V8::TerminateExecution() signal has been sent | 117 // gone (which means that the V8::TerminateExecution() signal has been sent |
| 118 // to this worker thread). | 118 // to this worker thread). |
| 119 if (!scriptState->executionContext()) | 119 if (!scriptState->executionContext()) |
| 120 return ScriptPromise(); | 120 return ScriptPromise(); |
| 121 | 121 |
| 122 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 122 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 123 ScriptPromise promise = resolver->promise(); | 123 ScriptPromise promise = resolver->promise(); |
| 124 if (bodyBuffer()) { | 124 if (bodyBuffer()) { |
| 125 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoa der::createLoaderAsArrayBuffer(), new BodyArrayBufferConsumer(resolver)); | 125 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoa der::createLoaderAsArrayBuffer(), new BodyArrayBufferConsumer(resolver)); |
| 126 } else { | 126 } else { |
| 127 resolver->resolve(DOMArrayBuffer::create(0u, 1)); | 127 resolver->resolve(DOMArrayBuffer::create(0u, 1)); |
| 128 } | 128 } |
| 129 return promise; | 129 return promise; |
| 130 } | 130 } |
| 131 | 131 |
| 132 ScriptPromise Body::blob(ScriptState* scriptState) | 132 ScriptPromise Body::blob(ScriptState* scriptState) |
| 133 { | 133 { |
| 134 if (m_opaque) | 134 if (m_opaque) |
| 135 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "The body is opaque.")); | 135 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "The body is opaque.")); |
| 136 | 136 |
| 137 if (bodyUsed()) | 137 if (isBodyLocked() || bodyUsed()) |
| 138 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Already read")); | 138 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Already read")); |
| 139 | 139 |
| 140 // See above comment. | 140 // See above comment. |
| 141 if (!scriptState->executionContext()) | 141 if (!scriptState->executionContext()) |
| 142 return ScriptPromise(); | 142 return ScriptPromise(); |
| 143 | 143 |
| 144 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 144 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 145 ScriptPromise promise = resolver->promise(); | 145 ScriptPromise promise = resolver->promise(); |
| 146 if (bodyBuffer()) { | 146 if (bodyBuffer()) { |
| 147 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoa der::createLoaderAsBlobHandle(mimeType()), new BodyBlobConsumer(resolver)); | 147 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoa der::createLoaderAsBlobHandle(mimeType()), new BodyBlobConsumer(resolver)); |
| 148 } else { | 148 } else { |
| 149 OwnPtr<BlobData> blobData = BlobData::create(); | 149 OwnPtr<BlobData> blobData = BlobData::create(); |
| 150 blobData->setContentType(mimeType()); | 150 blobData->setContentType(mimeType()); |
| 151 resolver->resolve(Blob::create(BlobDataHandle::create(blobData.release() , 0))); | 151 resolver->resolve(Blob::create(BlobDataHandle::create(blobData.release() , 0))); |
| 152 } | 152 } |
| 153 return promise; | 153 return promise; |
| 154 | 154 |
| 155 } | 155 } |
| 156 | 156 |
| 157 ScriptPromise Body::json(ScriptState* scriptState) | 157 ScriptPromise Body::json(ScriptState* scriptState) |
| 158 { | 158 { |
| 159 if (m_opaque) | 159 if (m_opaque) |
| 160 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "The body is opaque.")); | 160 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "The body is opaque.")); |
| 161 | 161 |
| 162 if (bodyUsed()) | 162 if (isBodyLocked() || bodyUsed()) |
| 163 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Already read")); | 163 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Already read")); |
| 164 | 164 |
| 165 // See above comment. | 165 // See above comment. |
| 166 if (!scriptState->executionContext()) | 166 if (!scriptState->executionContext()) |
| 167 return ScriptPromise(); | 167 return ScriptPromise(); |
| 168 | 168 |
| 169 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 169 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 170 ScriptPromise promise = resolver->promise(); | 170 ScriptPromise promise = resolver->promise(); |
| 171 if (bodyBuffer()) { | 171 if (bodyBuffer()) { |
| 172 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoa der::createLoaderAsString(), new BodyJsonConsumer(resolver)); | 172 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoa der::createLoaderAsString(), new BodyJsonConsumer(resolver)); |
| 173 } else { | 173 } else { |
| 174 resolver->reject(V8ThrowException::createSyntaxError(scriptState->isolat e(), "Unexpected end of input")); | 174 resolver->reject(V8ThrowException::createSyntaxError(scriptState->isolat e(), "Unexpected end of input")); |
| 175 } | 175 } |
| 176 return promise; | 176 return promise; |
| 177 } | 177 } |
| 178 | 178 |
| 179 ScriptPromise Body::text(ScriptState* scriptState) | 179 ScriptPromise Body::text(ScriptState* scriptState) |
| 180 { | 180 { |
| 181 if (m_opaque) | 181 if (m_opaque) |
| 182 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "The body is opaque.")); | 182 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "The body is opaque.")); |
| 183 | 183 |
| 184 if (bodyUsed()) | 184 if (isBodyLocked() || bodyUsed()) |
| 185 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Already read")); | 185 return ScriptPromise::reject(scriptState, V8ThrowException::createTypeEr ror(scriptState->isolate(), "Already read")); |
| 186 | 186 |
| 187 // See above comment. | 187 // See above comment. |
| 188 if (!scriptState->executionContext()) | 188 if (!scriptState->executionContext()) |
| 189 return ScriptPromise(); | 189 return ScriptPromise(); |
| 190 | 190 |
| 191 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; | 191 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ; |
| 192 ScriptPromise promise = resolver->promise(); | 192 ScriptPromise promise = resolver->promise(); |
| 193 if (bodyBuffer()) { | 193 if (bodyBuffer()) { |
| 194 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoa der::createLoaderAsString(), new BodyTextConsumer(resolver)); | 194 bodyBuffer()->startLoading(scriptState->executionContext(), FetchDataLoa der::createLoaderAsString(), new BodyTextConsumer(resolver)); |
| 195 } else { | 195 } else { |
| 196 resolver->resolve(String()); | 196 resolver->resolve(String()); |
| 197 } | 197 } |
| 198 return promise; | 198 return promise; |
| 199 } | 199 } |
| 200 | 200 |
| 201 ReadableByteStream* Body::body() | 201 ReadableByteStream* Body::body() |
| 202 { | 202 { |
| 203 UseCounter::count(executionContext(), UseCounter::FetchBodyStream); | 203 UseCounter::count(executionContext(), UseCounter::FetchBodyStream); |
|
tyoshino (SeeGerritForStatus)
2015/10/30 04:50:34
This starts counting the calls from bodyUsed and i
yhirano
2015/10/30 06:00:57
Done.
| |
| 204 return bodyBuffer() ? bodyBuffer()->stream() : nullptr; | 204 return bodyBuffer() ? bodyBuffer()->stream() : nullptr; |
| 205 } | 205 } |
| 206 | 206 |
| 207 bool Body::bodyUsed() | 207 bool Body::bodyUsed() |
| 208 { | 208 { |
| 209 return m_bodyPassed || (body() && body()->isLocked()); | 209 return body() && body()->isDisturbed(); |
| 210 } | |
| 211 | |
| 212 bool Body::isBodyLocked() | |
| 213 { | |
| 214 return body() && body()->isLocked(); | |
| 210 } | 215 } |
| 211 | 216 |
| 212 bool Body::hasPendingActivity() const | 217 bool Body::hasPendingActivity() const |
| 213 { | 218 { |
| 214 if (executionContext()->activeDOMObjectsAreStopped()) | 219 if (executionContext()->activeDOMObjectsAreStopped()) |
| 215 return false; | 220 return false; |
| 216 if (!bodyBuffer()) | 221 if (!bodyBuffer()) |
| 217 return false; | 222 return false; |
| 218 return bodyBuffer()->hasPendingActivity(); | 223 return bodyBuffer()->hasPendingActivity(); |
| 219 } | 224 } |
| 220 | 225 |
| 221 Body::Body(ExecutionContext* context) | 226 Body::Body(ExecutionContext* context) |
| 222 : ActiveDOMObject(context) | 227 : ActiveDOMObject(context) |
| 223 , m_bodyPassed(false) | |
| 224 , m_opaque(false) | 228 , m_opaque(false) |
| 225 { | 229 { |
| 226 suspendIfNeeded(); | 230 suspendIfNeeded(); |
| 227 } | 231 } |
| 228 | 232 |
| 229 } // namespace blink | 233 } // namespace blink |
| OLD | NEW |