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