| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/BytesConsumerForDataConsumerHandle.h" | 5 #include "modules/fetch/BytesConsumerForDataConsumerHandle.h" |
| 6 | 6 |
| 7 #include "core/dom/ExecutionContext.h" |
| 8 #include "core/dom/TaskRunnerHelper.h" |
| 9 #include "public/platform/WebTaskRunner.h" |
| 10 #include "public/platform/WebTraceLocation.h" |
| 11 #include "wtf/Functional.h" |
| 12 |
| 7 #include <algorithm> | 13 #include <algorithm> |
| 8 #include <string.h> | 14 #include <string.h> |
| 9 | 15 |
| 10 namespace blink { | 16 namespace blink { |
| 11 | 17 |
| 12 BytesConsumerForDataConsumerHandle::BytesConsumerForDataConsumerHandle(std::uniq
ue_ptr<FetchDataConsumerHandle> handle) | 18 BytesConsumerForDataConsumerHandle::BytesConsumerForDataConsumerHandle(Execution
Context* executionContext, std::unique_ptr<FetchDataConsumerHandle> handle) |
| 13 : m_reader(handle->obtainFetchDataReader(this)) | 19 : m_executionContext(executionContext) |
| 20 , m_reader(handle->obtainFetchDataReader(this)) |
| 14 { | 21 { |
| 15 } | 22 } |
| 16 | 23 |
| 17 BytesConsumerForDataConsumerHandle::~BytesConsumerForDataConsumerHandle() {} | 24 BytesConsumerForDataConsumerHandle::~BytesConsumerForDataConsumerHandle() |
| 25 { |
| 26 } |
| 18 | 27 |
| 19 BytesConsumer::Result BytesConsumerForDataConsumerHandle::read(char* buffer, siz
e_t size, size_t* readSize) | 28 BytesConsumer::Result BytesConsumerForDataConsumerHandle::read(char* buffer, siz
e_t size, size_t* readSize) |
| 20 { | 29 { |
| 30 DCHECK(!m_isInTwoPhaseRead); |
| 21 *readSize = 0; | 31 *readSize = 0; |
| 22 if (m_state == InternalState::Closed) | 32 if (m_state == InternalState::Closed) |
| 23 return Result::Done; | 33 return Result::Done; |
| 24 if (m_state == InternalState::Errored) | 34 if (m_state == InternalState::Errored) |
| 25 return Result::Error; | 35 return Result::Error; |
| 26 | 36 |
| 27 WebDataConsumerHandle::Result r = m_reader->read(buffer, size, WebDataConsum
erHandle::FlagNone, readSize); | 37 WebDataConsumerHandle::Result r = m_reader->read(buffer, size, WebDataConsum
erHandle::FlagNone, readSize); |
| 28 switch (r) { | 38 switch (r) { |
| 29 case WebDataConsumerHandle::Ok: | 39 case WebDataConsumerHandle::Ok: |
| 30 return Result::Ok; | 40 return Result::Ok; |
| 31 case WebDataConsumerHandle::ShouldWait: | 41 case WebDataConsumerHandle::ShouldWait: |
| 32 return Result::ShouldWait; | 42 return Result::ShouldWait; |
| 33 case WebDataConsumerHandle::Done: | 43 case WebDataConsumerHandle::Done: |
| 34 close(); | 44 close(); |
| 35 return Result::Done; | 45 return Result::Done; |
| 36 case WebDataConsumerHandle::Busy: | 46 case WebDataConsumerHandle::Busy: |
| 37 case WebDataConsumerHandle::ResourceExhausted: | 47 case WebDataConsumerHandle::ResourceExhausted: |
| 38 case WebDataConsumerHandle::UnexpectedError: | 48 case WebDataConsumerHandle::UnexpectedError: |
| 39 error(); | 49 error(); |
| 40 return Result::Error; | 50 return Result::Error; |
| 41 } | 51 } |
| 42 NOTREACHED(); | 52 NOTREACHED(); |
| 43 return Result::Error; | 53 return Result::Error; |
| 44 } | 54 } |
| 45 | 55 |
| 46 BytesConsumer::Result BytesConsumerForDataConsumerHandle::beginRead(const char**
buffer, size_t* available) | 56 BytesConsumer::Result BytesConsumerForDataConsumerHandle::beginRead(const char**
buffer, size_t* available) |
| 47 { | 57 { |
| 58 DCHECK(!m_isInTwoPhaseRead); |
| 48 *buffer = nullptr; | 59 *buffer = nullptr; |
| 49 *available = 0; | 60 *available = 0; |
| 50 if (m_state == InternalState::Closed) | 61 if (m_state == InternalState::Closed) |
| 51 return Result::Done; | 62 return Result::Done; |
| 52 if (m_state == InternalState::Errored) | 63 if (m_state == InternalState::Errored) |
| 53 return Result::Error; | 64 return Result::Error; |
| 54 | 65 |
| 55 WebDataConsumerHandle::Result r = m_reader->beginRead(reinterpret_cast<const
void**>(buffer), WebDataConsumerHandle::FlagNone, available); | 66 WebDataConsumerHandle::Result r = m_reader->beginRead(reinterpret_cast<const
void**>(buffer), WebDataConsumerHandle::FlagNone, available); |
| 56 switch (r) { | 67 switch (r) { |
| 57 case WebDataConsumerHandle::Ok: | 68 case WebDataConsumerHandle::Ok: |
| 69 m_isInTwoPhaseRead = true; |
| 58 return Result::Ok; | 70 return Result::Ok; |
| 59 case WebDataConsumerHandle::ShouldWait: | 71 case WebDataConsumerHandle::ShouldWait: |
| 60 return Result::ShouldWait; | 72 return Result::ShouldWait; |
| 61 case WebDataConsumerHandle::Done: | 73 case WebDataConsumerHandle::Done: |
| 62 close(); | 74 close(); |
| 63 return Result::Done; | 75 return Result::Done; |
| 64 case WebDataConsumerHandle::Busy: | 76 case WebDataConsumerHandle::Busy: |
| 65 case WebDataConsumerHandle::ResourceExhausted: | 77 case WebDataConsumerHandle::ResourceExhausted: |
| 66 case WebDataConsumerHandle::UnexpectedError: | 78 case WebDataConsumerHandle::UnexpectedError: |
| 67 error(); | 79 error(); |
| 68 return Result::Error; | 80 return Result::Error; |
| 69 } | 81 } |
| 70 NOTREACHED(); | 82 NOTREACHED(); |
| 71 return Result::Error; | 83 return Result::Error; |
| 72 } | 84 } |
| 73 | 85 |
| 74 BytesConsumer::Result BytesConsumerForDataConsumerHandle::endRead(size_t read) | 86 BytesConsumer::Result BytesConsumerForDataConsumerHandle::endRead(size_t read) |
| 75 { | 87 { |
| 88 DCHECK(m_isInTwoPhaseRead); |
| 89 m_isInTwoPhaseRead = false; |
| 76 DCHECK(m_state == InternalState::Readable || m_state == InternalState::Waiti
ng); | 90 DCHECK(m_state == InternalState::Readable || m_state == InternalState::Waiti
ng); |
| 77 WebDataConsumerHandle::Result r = m_reader->endRead(read); | 91 WebDataConsumerHandle::Result r = m_reader->endRead(read); |
| 78 if (r == WebDataConsumerHandle::Ok) | 92 if (r != WebDataConsumerHandle::Ok) { |
| 79 return Result::Ok; | 93 m_hasPendingNotification = false; |
| 80 error(); | 94 error(); |
| 81 return Result::Error; | 95 return Result::Error; |
| 96 } |
| 97 if (m_hasPendingNotification) { |
| 98 m_hasPendingNotification = false; |
| 99 TaskRunnerHelper::get(TaskType::Networking, m_executionContext)->postTas
k(BLINK_FROM_HERE, WTF::bind(&BytesConsumerForDataConsumerHandle::notify, wrapPe
rsistent(this))); |
| 100 } |
| 101 return Result::Ok; |
| 82 } | 102 } |
| 83 | 103 |
| 84 PassRefPtr<BlobDataHandle> BytesConsumerForDataConsumerHandle::drainAsBlobDataHa
ndle(BlobSizePolicy policy) | 104 PassRefPtr<BlobDataHandle> BytesConsumerForDataConsumerHandle::drainAsBlobDataHa
ndle(BlobSizePolicy policy) |
| 85 { | 105 { |
| 86 if (!m_reader) | 106 if (!m_reader) |
| 87 return nullptr; | 107 return nullptr; |
| 88 | 108 |
| 89 RefPtr<BlobDataHandle> handle; | 109 RefPtr<BlobDataHandle> handle; |
| 90 if (policy == BlobSizePolicy::DisallowBlobWithInvalidSize) { | 110 if (policy == BlobSizePolicy::DisallowBlobWithInvalidSize) { |
| 91 handle = m_reader->drainAsBlobDataHandle(FetchDataConsumerHandle::Reader
::DisallowBlobWithInvalidSize); | 111 handle = m_reader->drainAsBlobDataHandle(FetchDataConsumerHandle::Reader
::DisallowBlobWithInvalidSize); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 106 RefPtr<EncodedFormData> formData = m_reader->drainAsFormData(); | 126 RefPtr<EncodedFormData> formData = m_reader->drainAsFormData(); |
| 107 if (formData) | 127 if (formData) |
| 108 close(); | 128 close(); |
| 109 return formData.release(); | 129 return formData.release(); |
| 110 } | 130 } |
| 111 | 131 |
| 112 void BytesConsumerForDataConsumerHandle::setClient(BytesConsumer::Client* client
) | 132 void BytesConsumerForDataConsumerHandle::setClient(BytesConsumer::Client* client
) |
| 113 { | 133 { |
| 114 DCHECK(!m_client); | 134 DCHECK(!m_client); |
| 115 DCHECK(client); | 135 DCHECK(client); |
| 116 m_client = client; | 136 if (m_state == InternalState::Readable || m_state == InternalState::Waiting) |
| 137 m_client = client; |
| 117 } | 138 } |
| 118 | 139 |
| 119 void BytesConsumerForDataConsumerHandle::clearClient() | 140 void BytesConsumerForDataConsumerHandle::clearClient() |
| 120 { | 141 { |
| 121 DCHECK(m_client); | |
| 122 m_client = nullptr; | 142 m_client = nullptr; |
| 123 } | 143 } |
| 124 | 144 |
| 125 void BytesConsumerForDataConsumerHandle::cancel() | 145 void BytesConsumerForDataConsumerHandle::cancel() |
| 126 { | 146 { |
| 147 DCHECK(!m_isInTwoPhaseRead); |
| 127 if (m_state == InternalState::Readable || m_state == InternalState::Waiting)
{ | 148 if (m_state == InternalState::Readable || m_state == InternalState::Waiting)
{ |
| 128 // We don't want the client to be notified in this case. | 149 // We don't want the client to be notified in this case. |
| 129 BytesConsumer::Client* client = m_client; | 150 BytesConsumer::Client* client = m_client; |
| 130 m_client = nullptr; | 151 m_client = nullptr; |
| 131 close(); | 152 close(); |
| 132 m_client = client; | 153 m_client = client; |
| 133 } | 154 } |
| 134 } | 155 } |
| 135 | 156 |
| 136 BytesConsumer::PublicState BytesConsumerForDataConsumerHandle::getPublicState()
const | 157 BytesConsumer::PublicState BytesConsumerForDataConsumerHandle::getPublicState()
const |
| 137 { | 158 { |
| 138 return getPublicStateFromInternalState(m_state); | 159 return getPublicStateFromInternalState(m_state); |
| 139 } | 160 } |
| 140 | 161 |
| 141 void BytesConsumerForDataConsumerHandle::didGetReadable() | 162 void BytesConsumerForDataConsumerHandle::didGetReadable() |
| 142 { | 163 { |
| 143 DCHECK(m_state == InternalState::Readable || m_state == InternalState::Waiti
ng); | 164 DCHECK(m_state == InternalState::Readable || m_state == InternalState::Waiti
ng); |
| 165 if (m_isInTwoPhaseRead) { |
| 166 m_hasPendingNotification = true; |
| 167 return; |
| 168 } |
| 144 // Perform zero-length read to call check handle's status. | 169 // Perform zero-length read to call check handle's status. |
| 145 size_t readSize; | 170 size_t readSize; |
| 146 WebDataConsumerHandle::Result result = m_reader->read(nullptr, 0, WebDataCon
sumerHandle::FlagNone, &readSize); | 171 WebDataConsumerHandle::Result result = m_reader->read(nullptr, 0, WebDataCon
sumerHandle::FlagNone, &readSize); |
| 172 BytesConsumer::Client* client = m_client; |
| 147 switch (result) { | 173 switch (result) { |
| 148 case WebDataConsumerHandle::Ok: | 174 case WebDataConsumerHandle::Ok: |
| 149 case WebDataConsumerHandle::ShouldWait: | 175 case WebDataConsumerHandle::ShouldWait: |
| 150 if (m_client) | 176 if (client) |
| 151 m_client->onStateChange(); | 177 client->onStateChange(); |
| 152 return; | 178 return; |
| 153 case WebDataConsumerHandle::Done: | 179 case WebDataConsumerHandle::Done: |
| 154 close(); | 180 close(); |
| 155 if (m_client) | 181 if (client) |
| 156 m_client->onStateChange(); | 182 client->onStateChange(); |
| 157 return; | 183 return; |
| 158 case WebDataConsumerHandle::Busy: | 184 case WebDataConsumerHandle::Busy: |
| 159 case WebDataConsumerHandle::ResourceExhausted: | 185 case WebDataConsumerHandle::ResourceExhausted: |
| 160 case WebDataConsumerHandle::UnexpectedError: | 186 case WebDataConsumerHandle::UnexpectedError: |
| 161 error(); | 187 error(); |
| 162 if (m_client) | 188 if (client) |
| 163 m_client->onStateChange(); | 189 client->onStateChange(); |
| 164 return; | 190 return; |
| 165 } | 191 } |
| 166 return; | 192 return; |
| 167 } | 193 } |
| 168 | 194 |
| 169 DEFINE_TRACE(BytesConsumerForDataConsumerHandle) | 195 DEFINE_TRACE(BytesConsumerForDataConsumerHandle) |
| 170 { | 196 { |
| 197 visitor->trace(m_executionContext); |
| 171 visitor->trace(m_client); | 198 visitor->trace(m_client); |
| 172 BytesConsumer::trace(visitor); | 199 BytesConsumer::trace(visitor); |
| 173 } | 200 } |
| 174 | 201 |
| 175 void BytesConsumerForDataConsumerHandle::close() | 202 void BytesConsumerForDataConsumerHandle::close() |
| 176 { | 203 { |
| 204 DCHECK(!m_isInTwoPhaseRead); |
| 177 if (m_state == InternalState::Closed) | 205 if (m_state == InternalState::Closed) |
| 178 return; | 206 return; |
| 179 DCHECK(m_state == InternalState::Readable || m_state == InternalState::Waiti
ng); | 207 DCHECK(m_state == InternalState::Readable || m_state == InternalState::Waiti
ng); |
| 180 m_state = InternalState::Closed; | 208 m_state = InternalState::Closed; |
| 181 m_reader = nullptr; | 209 m_reader = nullptr; |
| 210 clearClient(); |
| 182 } | 211 } |
| 183 | 212 |
| 184 void BytesConsumerForDataConsumerHandle::error() | 213 void BytesConsumerForDataConsumerHandle::error() |
| 185 { | 214 { |
| 215 DCHECK(!m_isInTwoPhaseRead); |
| 186 if (m_state == InternalState::Errored) | 216 if (m_state == InternalState::Errored) |
| 187 return; | 217 return; |
| 188 DCHECK(m_state == InternalState::Readable || m_state == InternalState::Waiti
ng); | 218 DCHECK(m_state == InternalState::Readable || m_state == InternalState::Waiti
ng); |
| 189 m_state = InternalState::Errored; | 219 m_state = InternalState::Errored; |
| 190 m_reader = nullptr; | 220 m_reader = nullptr; |
| 191 m_error = Error("error"); | 221 m_error = Error("error"); |
| 222 clearClient(); |
| 223 } |
| 224 |
| 225 void BytesConsumerForDataConsumerHandle::notify() |
| 226 { |
| 227 if (m_state == InternalState::Closed || m_state == InternalState::Errored) |
| 228 return; |
| 229 didGetReadable(); |
| 192 } | 230 } |
| 193 | 231 |
| 194 } // namespace blink | 232 } // namespace blink |
| OLD | NEW |