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 "modules/fetch/BodyStreamBuffer.h" | 5 #include "modules/fetch/BodyStreamBuffer.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ScriptState.h" | 7 #include "bindings/core/v8/ScriptState.h" |
| 8 #include "bindings/core/v8/V8HiddenValue.h" | 8 #include "bindings/core/v8/V8HiddenValue.h" |
| 9 #include "core/dom/DOMArrayBuffer.h" | 9 #include "core/dom/DOMArrayBuffer.h" |
| 10 #include "core/dom/DOMTypedArray.h" | 10 #include "core/dom/DOMTypedArray.h" |
| 11 #include "core/dom/ExceptionCode.h" | 11 #include "core/dom/ExceptionCode.h" |
| 12 #include "core/streams/ReadableStreamController.h" | 12 #include "core/streams/ReadableStreamController.h" |
| 13 #include "core/streams/ReadableStreamOperations.h" | 13 #include "core/streams/ReadableStreamOperations.h" |
| 14 #include "modules/fetch/Body.h" | 14 #include "modules/fetch/Body.h" |
| 15 #include "modules/fetch/DataConsumerHandleUtil.h" | 15 #include "modules/fetch/DataConsumerHandleUtil.h" |
| 16 #include "modules/fetch/ReadableStreamDataConsumerHandle.h" | |
| 16 #include "platform/RuntimeEnabledFeatures.h" | 17 #include "platform/RuntimeEnabledFeatures.h" |
| 17 #include "platform/blob/BlobData.h" | 18 #include "platform/blob/BlobData.h" |
| 18 #include "platform/network/EncodedFormData.h" | 19 #include "platform/network/EncodedFormData.h" |
| 19 | 20 |
| 20 namespace blink { | 21 namespace blink { |
| 21 | 22 |
| 22 class BodyStreamBuffer::LoaderClient final : public GarbageCollectedFinalized<Lo aderClient>, public ActiveDOMObject, public FetchDataLoader::Client { | 23 class BodyStreamBuffer::LoaderClient final : public GarbageCollectedFinalized<Lo aderClient>, public ActiveDOMObject, public FetchDataLoader::Client { |
| 23 WTF_MAKE_NONCOPYABLE(LoaderClient); | 24 WTF_MAKE_NONCOPYABLE(LoaderClient); |
| 24 USING_GARBAGE_COLLECTED_MIXIN(LoaderClient); | 25 USING_GARBAGE_COLLECTED_MIXIN(LoaderClient); |
| 25 public: | 26 public: |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 77 | 78 |
| 78 Member<BodyStreamBuffer> m_buffer; | 79 Member<BodyStreamBuffer> m_buffer; |
| 79 Member<FetchDataLoader::Client> m_client; | 80 Member<FetchDataLoader::Client> m_client; |
| 80 }; | 81 }; |
| 81 | 82 |
| 82 BodyStreamBuffer::BodyStreamBuffer(ScriptState* scriptState, PassOwnPtr<FetchDat aConsumerHandle> handle) | 83 BodyStreamBuffer::BodyStreamBuffer(ScriptState* scriptState, PassOwnPtr<FetchDat aConsumerHandle> handle) |
| 83 : UnderlyingSourceBase(scriptState) | 84 : UnderlyingSourceBase(scriptState) |
| 84 , m_scriptState(scriptState) | 85 , m_scriptState(scriptState) |
| 85 , m_handle(std::move(handle)) | 86 , m_handle(std::move(handle)) |
| 86 , m_reader(m_handle->obtainReader(this)) | 87 , m_reader(m_handle->obtainReader(this)) |
| 88 , m_madeFromReadableStream(false) | |
| 87 { | 89 { |
| 88 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) { | 90 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) { |
| 89 ScriptState::Scope scope(scriptState); | 91 ScriptState::Scope scope(scriptState); |
| 90 v8::Local<v8::Value> bodyValue = toV8(this, scriptState); | 92 v8::Local<v8::Value> bodyValue = toV8(this, scriptState); |
| 91 ASSERT(!bodyValue.IsEmpty()); | 93 ASSERT(!bodyValue.IsEmpty()); |
| 92 ASSERT(bodyValue->IsObject()); | 94 ASSERT(bodyValue->IsObject()); |
| 93 v8::Local<v8::Object> body = bodyValue.As<v8::Object>(); | 95 v8::Local<v8::Object> body = bodyValue.As<v8::Object>(); |
| 94 | 96 |
| 95 ScriptValue readableStream = ReadableStreamOperations::createReadableStr eam( | 97 ScriptValue readableStream = ReadableStreamOperations::createReadableStr eam( |
| 96 scriptState, this, ReadableStreamOperations::createCountQueuingStrat egy(scriptState, 0)); | 98 scriptState, this, ReadableStreamOperations::createCountQueuingStrat egy(scriptState, 0)); |
| 97 V8HiddenValue::setHiddenValue(scriptState, body, V8HiddenValue::internal BodyStream(scriptState->isolate()), readableStream.v8Value()); | 99 V8HiddenValue::setHiddenValue(scriptState, body, V8HiddenValue::internal BodyStream(scriptState->isolate()), readableStream.v8Value()); |
| 98 } else { | 100 } else { |
| 99 m_stream = new ReadableByteStream(this, new ReadableByteStream::StrictSt rategy); | 101 m_stream = new ReadableByteStream(this, new ReadableByteStream::StrictSt rategy); |
| 100 m_stream->didSourceStart(); | 102 m_stream->didSourceStart(); |
| 101 } | 103 } |
| 102 } | 104 } |
| 103 | 105 |
| 106 BodyStreamBuffer::BodyStreamBuffer(ScriptState* scriptState, ScriptValue stream) | |
| 107 : UnderlyingSourceBase(scriptState) | |
| 108 , m_scriptState(scriptState) | |
| 109 , m_madeFromReadableStream(true) | |
| 110 { | |
| 111 ScriptState::Scope scope(scriptState); | |
| 112 ASSERT(RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()); | |
| 113 ASSERT(ReadableStreamOperations::isReadableStream(scriptState, stream)); | |
|
haraken
2016/05/12 08:22:57
Use DCHECK.
yhirano
2016/05/12 08:28:15
Done.
| |
| 114 v8::Local<v8::Value> bodyValue = toV8(this, scriptState); | |
| 115 ASSERT(!bodyValue.IsEmpty()); | |
| 116 ASSERT(bodyValue->IsObject()); | |
| 117 v8::Local<v8::Object> body = bodyValue.As<v8::Object>(); | |
| 118 | |
| 119 V8HiddenValue::setHiddenValue(scriptState, body, V8HiddenValue::internalBody Stream(scriptState->isolate()), stream.v8Value()); | |
| 120 } | |
| 121 | |
| 104 ScriptValue BodyStreamBuffer::stream() | 122 ScriptValue BodyStreamBuffer::stream() |
| 105 { | 123 { |
| 106 ScriptState::Scope scope(m_scriptState.get()); | 124 ScriptState::Scope scope(m_scriptState.get()); |
| 107 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) { | 125 if (RuntimeEnabledFeatures::responseBodyWithV8ExtraStreamEnabled()) { |
| 108 v8::Local<v8::Value> bodyValue = toV8(this, m_scriptState.get()); | 126 v8::Local<v8::Value> bodyValue = toV8(this, m_scriptState.get()); |
| 109 ASSERT(!bodyValue.IsEmpty()); | 127 ASSERT(!bodyValue.IsEmpty()); |
| 110 ASSERT(bodyValue->IsObject()); | 128 ASSERT(bodyValue->IsObject()); |
| 111 v8::Local<v8::Object> body = bodyValue.As<v8::Object>(); | 129 v8::Local<v8::Object> body = bodyValue.As<v8::Object>(); |
| 112 return ScriptValue(m_scriptState.get(), V8HiddenValue::getHiddenValue(m_ scriptState.get(), body, V8HiddenValue::internalBodyStream(m_scriptState->isolat e()))); | 130 return ScriptValue(m_scriptState.get(), V8HiddenValue::getHiddenValue(m_ scriptState.get(), body, V8HiddenValue::internalBodyStream(m_scriptState->isolat e()))); |
| 113 } | 131 } |
| 114 return ScriptValue(m_scriptState.get(), toV8(m_stream, m_scriptState.get())) ; | 132 return ScriptValue(m_scriptState.get(), toV8(m_stream, m_scriptState.get())) ; |
| 115 } | 133 } |
| 116 | 134 |
| 117 PassRefPtr<BlobDataHandle> BodyStreamBuffer::drainAsBlobDataHandle(FetchDataCons umerHandle::Reader::BlobSizePolicy policy) | 135 PassRefPtr<BlobDataHandle> BodyStreamBuffer::drainAsBlobDataHandle(FetchDataCons umerHandle::Reader::BlobSizePolicy policy) |
| 118 { | 136 { |
| 119 ASSERT(!isStreamLocked()); | 137 ASSERT(!isStreamLocked()); |
| 120 ASSERT(!isStreamDisturbed()); | 138 ASSERT(!isStreamDisturbed()); |
| 121 if (isStreamClosed() || isStreamErrored()) | 139 if (isStreamClosed() || isStreamErrored()) |
| 122 return nullptr; | 140 return nullptr; |
| 123 | 141 |
| 142 if (m_madeFromReadableStream) | |
| 143 return nullptr; | |
| 144 | |
| 124 RefPtr<BlobDataHandle> blobDataHandle = m_reader->drainAsBlobDataHandle(poli cy); | 145 RefPtr<BlobDataHandle> blobDataHandle = m_reader->drainAsBlobDataHandle(poli cy); |
| 125 if (blobDataHandle) { | 146 if (blobDataHandle) { |
| 126 closeAndLockAndDisturb(); | 147 closeAndLockAndDisturb(); |
| 127 return blobDataHandle.release(); | 148 return blobDataHandle.release(); |
| 128 } | 149 } |
| 129 return nullptr; | 150 return nullptr; |
| 130 } | 151 } |
| 131 | 152 |
| 132 PassRefPtr<EncodedFormData> BodyStreamBuffer::drainAsFormData() | 153 PassRefPtr<EncodedFormData> BodyStreamBuffer::drainAsFormData() |
| 133 { | 154 { |
| 134 ASSERT(!isStreamLocked()); | 155 ASSERT(!isStreamLocked()); |
| 135 ASSERT(!isStreamDisturbed()); | 156 ASSERT(!isStreamDisturbed()); |
| 136 if (isStreamClosed() || isStreamErrored()) | 157 if (isStreamClosed() || isStreamErrored()) |
| 137 return nullptr; | 158 return nullptr; |
| 138 | 159 |
| 160 if (m_madeFromReadableStream) | |
| 161 return nullptr; | |
| 162 | |
| 139 RefPtr<EncodedFormData> formData = m_reader->drainAsFormData(); | 163 RefPtr<EncodedFormData> formData = m_reader->drainAsFormData(); |
| 140 if (formData) { | 164 if (formData) { |
| 141 closeAndLockAndDisturb(); | 165 closeAndLockAndDisturb(); |
| 142 return formData.release(); | 166 return formData.release(); |
| 143 } | 167 } |
| 144 return nullptr; | 168 return nullptr; |
| 145 } | 169 } |
| 146 | 170 |
| 147 PassOwnPtr<FetchDataConsumerHandle> BodyStreamBuffer::releaseHandle() | 171 PassOwnPtr<FetchDataConsumerHandle> BodyStreamBuffer::releaseHandle() |
| 148 { | 172 { |
| 149 ASSERT(!isStreamLocked()); | 173 ASSERT(!isStreamLocked()); |
| 150 ASSERT(!isStreamDisturbed()); | 174 ASSERT(!isStreamDisturbed()); |
| 175 | |
| 176 if (m_madeFromReadableStream) { | |
| 177 ScriptState::Scope scope(m_scriptState.get()); | |
| 178 NonThrowableExceptionState exceptionState; | |
| 179 ScriptValue reader = ReadableStreamOperations::getReader(m_scriptState.g et(), stream(), exceptionState); | |
|
haraken
2016/05/12 08:22:57
Is it okay to ignore the exception?
yhirano
2016/05/12 08:28:15
Yes. It throws an exception only when locked, and
| |
| 180 // We need to have |reader| alive by some means (as written in | |
| 181 // ReadableStreamDataConsumerHandle). |this| BodyStreamBuffer will be | |
| 182 // kept alive while the stream is locked and readable, and the stream | |
| 183 // has a reference to the reader. Hence we don't need to keep the reader | |
| 184 // explicitly. | |
| 185 return ReadableStreamDataConsumerHandle::create(m_scriptState.get(), rea der); | |
| 186 } | |
| 187 | |
| 151 // We need to call these before calling closeAndLockAndDisturb. | 188 // We need to call these before calling closeAndLockAndDisturb. |
| 152 const bool isClosed = isStreamClosed(); | 189 const bool isClosed = isStreamClosed(); |
| 153 const bool isErrored = isStreamErrored(); | 190 const bool isErrored = isStreamErrored(); |
| 154 OwnPtr<FetchDataConsumerHandle> handle = m_handle.release(); | 191 OwnPtr<FetchDataConsumerHandle> handle = m_handle.release(); |
| 155 | 192 |
| 156 closeAndLockAndDisturb(); | 193 closeAndLockAndDisturb(); |
| 157 | 194 |
| 158 if (isClosed) { | 195 if (isClosed) { |
| 159 // Note that the stream cannot be "draining", because it doesn't have | 196 // Note that the stream cannot be "draining", because it doesn't have |
| 160 // the internal buffer. | 197 // the internal buffer. |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 378 | 415 |
| 379 void BodyStreamBuffer::stopLoading() | 416 void BodyStreamBuffer::stopLoading() |
| 380 { | 417 { |
| 381 if (!m_loader) | 418 if (!m_loader) |
| 382 return; | 419 return; |
| 383 m_loader->cancel(); | 420 m_loader->cancel(); |
| 384 m_loader = nullptr; | 421 m_loader = nullptr; |
| 385 } | 422 } |
| 386 | 423 |
| 387 } // namespace blink | 424 } // namespace blink |
| OLD | NEW |