| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "net/spdy/bidirectional_stream_spdy_impl.h" | 5 #include "net/spdy/bidirectional_stream_spdy_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 bool /*send_request_headers_automatically*/, | 53 bool /*send_request_headers_automatically*/, |
| 54 BidirectionalStreamImpl::Delegate* delegate, | 54 BidirectionalStreamImpl::Delegate* delegate, |
| 55 std::unique_ptr<base::Timer> timer) { | 55 std::unique_ptr<base::Timer> timer) { |
| 56 DCHECK(!stream_); | 56 DCHECK(!stream_); |
| 57 DCHECK(timer); | 57 DCHECK(timer); |
| 58 | 58 |
| 59 delegate_ = delegate; | 59 delegate_ = delegate; |
| 60 timer_ = std::move(timer); | 60 timer_ = std::move(timer); |
| 61 | 61 |
| 62 if (!spdy_session_) { | 62 if (!spdy_session_) { |
| 63 delegate_->OnFailed(ERR_CONNECTION_CLOSED); | 63 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 64 FROM_HERE, |
| 65 base::Bind(&BidirectionalStreamSpdyImpl::NotifyError, |
| 66 weak_factory_.GetWeakPtr(), ERR_CONNECTION_CLOSED)); |
| 64 return; | 67 return; |
| 65 } | 68 } |
| 66 | 69 |
| 67 request_info_ = request_info; | 70 request_info_ = request_info; |
| 68 | 71 |
| 69 int rv = stream_request_.StartRequest( | 72 int rv = stream_request_.StartRequest( |
| 70 SPDY_BIDIRECTIONAL_STREAM, spdy_session_, request_info_->url, | 73 SPDY_BIDIRECTIONAL_STREAM, spdy_session_, request_info_->url, |
| 71 request_info_->priority, net_log, | 74 request_info_->priority, net_log, |
| 72 base::Bind(&BidirectionalStreamSpdyImpl::OnStreamInitialized, | 75 base::Bind(&BidirectionalStreamSpdyImpl::OnStreamInitialized, |
| 73 weak_factory_.GetWeakPtr())); | 76 weak_factory_.GetWeakPtr())); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 97 // Read will complete asynchronously and Delegate::OnReadCompleted will be | 100 // Read will complete asynchronously and Delegate::OnReadCompleted will be |
| 98 // called upon completion. | 101 // called upon completion. |
| 99 read_buffer_ = buf; | 102 read_buffer_ = buf; |
| 100 read_buffer_len_ = buf_len; | 103 read_buffer_len_ = buf_len; |
| 101 return ERR_IO_PENDING; | 104 return ERR_IO_PENDING; |
| 102 } | 105 } |
| 103 | 106 |
| 104 void BidirectionalStreamSpdyImpl::SendData(const scoped_refptr<IOBuffer>& data, | 107 void BidirectionalStreamSpdyImpl::SendData(const scoped_refptr<IOBuffer>& data, |
| 105 int length, | 108 int length, |
| 106 bool end_stream) { | 109 bool end_stream) { |
| 107 DCHECK(!stream_closed_); | 110 DCHECK(length > 0 || (length == 0 && end_stream)); |
| 108 DCHECK(stream_); | 111 |
| 112 if (!stream_) { |
| 113 LOG(ERROR) << "Trying to send data when stream has been destroyed."; |
| 114 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 115 FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::NotifyError, |
| 116 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); |
| 117 return; |
| 118 } |
| 109 | 119 |
| 110 stream_->SendData(data.get(), length, | 120 stream_->SendData(data.get(), length, |
| 111 end_stream ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND); | 121 end_stream ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND); |
| 112 } | 122 } |
| 113 | 123 |
| 114 void BidirectionalStreamSpdyImpl::SendvData( | 124 void BidirectionalStreamSpdyImpl::SendvData( |
| 115 const std::vector<scoped_refptr<IOBuffer>>& buffers, | 125 const std::vector<scoped_refptr<IOBuffer>>& buffers, |
| 116 const std::vector<int>& lengths, | 126 const std::vector<int>& lengths, |
| 117 bool end_stream) { | 127 bool end_stream) { |
| 118 DCHECK(!stream_closed_); | |
| 119 DCHECK(stream_); | |
| 120 DCHECK_EQ(buffers.size(), lengths.size()); | 128 DCHECK_EQ(buffers.size(), lengths.size()); |
| 121 | 129 |
| 130 if (!stream_) { |
| 131 LOG(ERROR) << "Trying to send data when stream has been destroyed."; |
| 132 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 133 FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::NotifyError, |
| 134 weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); |
| 135 return; |
| 136 } |
| 137 |
| 122 int total_len = 0; | 138 int total_len = 0; |
| 123 for (int len : lengths) { | 139 for (int len : lengths) { |
| 124 total_len += len; | 140 total_len += len; |
| 125 } | 141 } |
| 126 | 142 |
| 127 pending_combined_buffer_ = new net::IOBuffer(total_len); | 143 pending_combined_buffer_ = new net::IOBuffer(total_len); |
| 128 int len = 0; | 144 int len = 0; |
| 129 // TODO(xunjieli): Get rid of extra copy. Coalesce headers and data frames. | 145 // TODO(xunjieli): Get rid of extra copy. Coalesce headers and data frames. |
| 130 for (size_t i = 0; i < buffers.size(); ++i) { | 146 for (size_t i = 0; i < buffers.size(); ++i) { |
| 131 memcpy(pending_combined_buffer_->data() + len, buffers[i]->data(), | 147 memcpy(pending_combined_buffer_->data() + len, buffers[i]->data(), |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 void BidirectionalStreamSpdyImpl::OnClose(int status) { | 237 void BidirectionalStreamSpdyImpl::OnClose(int status) { |
| 222 DCHECK(stream_); | 238 DCHECK(stream_); |
| 223 | 239 |
| 224 stream_closed_ = true; | 240 stream_closed_ = true; |
| 225 closed_stream_status_ = status; | 241 closed_stream_status_ = status; |
| 226 closed_stream_received_bytes_ = stream_->raw_received_bytes(); | 242 closed_stream_received_bytes_ = stream_->raw_received_bytes(); |
| 227 closed_stream_sent_bytes_ = stream_->raw_sent_bytes(); | 243 closed_stream_sent_bytes_ = stream_->raw_sent_bytes(); |
| 228 stream_.reset(); | 244 stream_.reset(); |
| 229 | 245 |
| 230 if (status != OK) { | 246 if (status != OK) { |
| 231 delegate_->OnFailed(status); | 247 NotifyError(status); |
| 232 return; | 248 return; |
| 233 } | 249 } |
| 234 // Complete any remaining read, as all data has been buffered. | 250 // Complete any remaining read, as all data has been buffered. |
| 235 // If user has not called ReadData (i.e |read_buffer_| is nullptr), this will | 251 // If user has not called ReadData (i.e |read_buffer_| is nullptr), this will |
| 236 // do nothing. | 252 // do nothing. |
| 237 timer_->Stop(); | 253 timer_->Stop(); |
| 238 DoBufferedRead(); | 254 DoBufferedRead(); |
| 239 } | 255 } |
| 240 | 256 |
| 241 int BidirectionalStreamSpdyImpl::SendRequestHeadersHelper() { | 257 int BidirectionalStreamSpdyImpl::SendRequestHeadersHelper() { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 260 stream_ = stream_request_.ReleaseStream(); | 276 stream_ = stream_request_.ReleaseStream(); |
| 261 stream_->SetDelegate(this); | 277 stream_->SetDelegate(this); |
| 262 rv = SendRequestHeadersHelper(); | 278 rv = SendRequestHeadersHelper(); |
| 263 if (rv == OK) { | 279 if (rv == OK) { |
| 264 OnRequestHeadersSent(); | 280 OnRequestHeadersSent(); |
| 265 return; | 281 return; |
| 266 } else if (rv == ERR_IO_PENDING) { | 282 } else if (rv == ERR_IO_PENDING) { |
| 267 return; | 283 return; |
| 268 } | 284 } |
| 269 } | 285 } |
| 286 NotifyError(rv); |
| 287 } |
| 288 |
| 289 void BidirectionalStreamSpdyImpl::NotifyError(int rv) { |
| 270 delegate_->OnFailed(rv); | 290 delegate_->OnFailed(rv); |
| 271 } | 291 } |
| 272 | 292 |
| 273 void BidirectionalStreamSpdyImpl::ScheduleBufferedRead() { | 293 void BidirectionalStreamSpdyImpl::ScheduleBufferedRead() { |
| 274 // If there is already a scheduled DoBufferedRead, don't issue | 294 // If there is already a scheduled DoBufferedRead, don't issue |
| 275 // another one. Mark that we have received more data and return. | 295 // another one. Mark that we have received more data and return. |
| 276 if (timer_->IsRunning()) { | 296 if (timer_->IsRunning()) { |
| 277 more_read_data_pending_ = true; | 297 more_read_data_pending_ = true; |
| 278 return; | 298 return; |
| 279 } | 299 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 309 | 329 |
| 310 bool BidirectionalStreamSpdyImpl::ShouldWaitForMoreBufferedData() const { | 330 bool BidirectionalStreamSpdyImpl::ShouldWaitForMoreBufferedData() const { |
| 311 if (stream_closed_) | 331 if (stream_closed_) |
| 312 return false; | 332 return false; |
| 313 DCHECK_GT(read_buffer_len_, 0); | 333 DCHECK_GT(read_buffer_len_, 0); |
| 314 return read_data_queue_.GetTotalSize() < | 334 return read_data_queue_.GetTotalSize() < |
| 315 static_cast<size_t>(read_buffer_len_); | 335 static_cast<size_t>(read_buffer_len_); |
| 316 } | 336 } |
| 317 | 337 |
| 318 } // namespace net | 338 } // namespace net |
| OLD | NEW |