| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/spdy_stream.h" | 5 #include "net/spdy/spdy_stream.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <utility> |
| 8 | 9 |
| 9 #include "base/bind.h" | 10 #include "base/bind.h" |
| 10 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 11 #include "base/location.h" | 12 #include "base/location.h" |
| 12 #include "base/logging.h" | 13 #include "base/logging.h" |
| 13 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
| 14 #include "base/single_thread_task_runner.h" | 15 #include "base/single_thread_task_runner.h" |
| 15 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
| 16 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
| 17 #include "base/thread_task_runner_handle.h" | 18 #include "base/thread_task_runner_handle.h" |
| 18 #include "base/values.h" | 19 #include "base/values.h" |
| 19 #include "net/spdy/spdy_buffer_producer.h" | 20 #include "net/spdy/spdy_buffer_producer.h" |
| 20 #include "net/spdy/spdy_http_utils.h" | 21 #include "net/spdy/spdy_http_utils.h" |
| 21 #include "net/spdy/spdy_session.h" | 22 #include "net/spdy/spdy_session.h" |
| 22 | 23 |
| 23 namespace net { | 24 namespace net { |
| 24 | 25 |
| 25 namespace { | 26 namespace { |
| 26 | 27 |
| 27 scoped_ptr<base::Value> NetLogSpdyStreamErrorCallback( | 28 scoped_ptr<base::Value> NetLogSpdyStreamErrorCallback( |
| 28 SpdyStreamId stream_id, | 29 SpdyStreamId stream_id, |
| 29 int status, | 30 int status, |
| 30 const std::string* description, | 31 const std::string* description, |
| 31 NetLogCaptureMode /* capture_mode */) { | 32 NetLogCaptureMode /* capture_mode */) { |
| 32 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 33 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| 33 dict->SetInteger("stream_id", static_cast<int>(stream_id)); | 34 dict->SetInteger("stream_id", static_cast<int>(stream_id)); |
| 34 dict->SetInteger("status", status); | 35 dict->SetInteger("status", status); |
| 35 dict->SetString("description", *description); | 36 dict->SetString("description", *description); |
| 36 return dict.Pass(); | 37 return std::move(dict); |
| 37 } | 38 } |
| 38 | 39 |
| 39 scoped_ptr<base::Value> NetLogSpdyStreamWindowUpdateCallback( | 40 scoped_ptr<base::Value> NetLogSpdyStreamWindowUpdateCallback( |
| 40 SpdyStreamId stream_id, | 41 SpdyStreamId stream_id, |
| 41 int32_t delta, | 42 int32_t delta, |
| 42 int32_t window_size, | 43 int32_t window_size, |
| 43 NetLogCaptureMode /* capture_mode */) { | 44 NetLogCaptureMode /* capture_mode */) { |
| 44 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 45 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
| 45 dict->SetInteger("stream_id", stream_id); | 46 dict->SetInteger("stream_id", stream_id); |
| 46 dict->SetInteger("delta", delta); | 47 dict->SetInteger("delta", delta); |
| 47 dict->SetInteger("window_size", window_size); | 48 dict->SetInteger("window_size", window_size); |
| 48 return dict.Pass(); | 49 return std::move(dict); |
| 49 } | 50 } |
| 50 | 51 |
| 51 bool ContainsUppercaseAscii(const std::string& str) { | 52 bool ContainsUppercaseAscii(const std::string& str) { |
| 52 for (std::string::const_iterator i(str.begin()); i != str.end(); ++i) { | 53 for (std::string::const_iterator i(str.begin()); i != str.end(); ++i) { |
| 53 if (*i >= 'A' && *i <= 'Z') { | 54 if (*i >= 'A' && *i <= 'Z') { |
| 54 return true; | 55 return true; |
| 55 } | 56 } |
| 56 } | 57 } |
| 57 return false; | 58 return false; |
| 58 } | 59 } |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 response_headers_status_ = RESPONSE_HEADERS_ARE_COMPLETE; | 180 response_headers_status_ = RESPONSE_HEADERS_ARE_COMPLETE; |
| 180 | 181 |
| 181 while (!pending_recv_data_.empty()) { | 182 while (!pending_recv_data_.empty()) { |
| 182 // Take ownership of the first element of |pending_recv_data_|. | 183 // Take ownership of the first element of |pending_recv_data_|. |
| 183 scoped_ptr<SpdyBuffer> buffer = std::move(pending_recv_data_.at(0)); | 184 scoped_ptr<SpdyBuffer> buffer = std::move(pending_recv_data_.at(0)); |
| 184 pending_recv_data_.erase(pending_recv_data_.begin()); | 185 pending_recv_data_.erase(pending_recv_data_.begin()); |
| 185 | 186 |
| 186 bool eof = (buffer == NULL); | 187 bool eof = (buffer == NULL); |
| 187 | 188 |
| 188 CHECK(delegate_); | 189 CHECK(delegate_); |
| 189 delegate_->OnDataReceived(buffer.Pass()); | 190 delegate_->OnDataReceived(std::move(buffer)); |
| 190 | 191 |
| 191 // OnDataReceived() may have closed |this|. | 192 // OnDataReceived() may have closed |this|. |
| 192 if (!weak_this) | 193 if (!weak_this) |
| 193 return; | 194 return; |
| 194 | 195 |
| 195 if (eof) { | 196 if (eof) { |
| 196 DCHECK(pending_recv_data_.empty()); | 197 DCHECK(pending_recv_data_.empty()); |
| 197 session_->CloseActiveStream(stream_id_, OK); | 198 session_->CloseActiveStream(stream_id_, OK); |
| 198 DCHECK(!weak_this); | 199 DCHECK(!weak_this); |
| 199 // |pending_recv_data_| is invalid at this point. | 200 // |pending_recv_data_| is invalid at this point. |
| 200 break; | 201 break; |
| 201 } | 202 } |
| 202 } | 203 } |
| 203 } | 204 } |
| 204 | 205 |
| 205 scoped_ptr<SpdyFrame> SpdyStream::ProduceSynStreamFrame() { | 206 scoped_ptr<SpdyFrame> SpdyStream::ProduceSynStreamFrame() { |
| 206 CHECK_EQ(io_state_, STATE_IDLE); | 207 CHECK_EQ(io_state_, STATE_IDLE); |
| 207 CHECK(request_headers_); | 208 CHECK(request_headers_); |
| 208 CHECK_GT(stream_id_, 0u); | 209 CHECK_GT(stream_id_, 0u); |
| 209 | 210 |
| 210 SpdyControlFlags flags = | 211 SpdyControlFlags flags = |
| 211 (pending_send_status_ == NO_MORE_DATA_TO_SEND) ? | 212 (pending_send_status_ == NO_MORE_DATA_TO_SEND) ? |
| 212 CONTROL_FLAG_FIN : CONTROL_FLAG_NONE; | 213 CONTROL_FLAG_FIN : CONTROL_FLAG_NONE; |
| 213 scoped_ptr<SpdyFrame> frame(session_->CreateSynStream( | 214 scoped_ptr<SpdyFrame> frame(session_->CreateSynStream( |
| 214 stream_id_, priority_, flags, *request_headers_)); | 215 stream_id_, priority_, flags, *request_headers_)); |
| 215 send_time_ = base::TimeTicks::Now(); | 216 send_time_ = base::TimeTicks::Now(); |
| 216 return frame.Pass(); | 217 return frame; |
| 217 } | 218 } |
| 218 | 219 |
| 219 void SpdyStream::DetachDelegate() { | 220 void SpdyStream::DetachDelegate() { |
| 220 DCHECK(!IsClosed()); | 221 DCHECK(!IsClosed()); |
| 221 delegate_ = NULL; | 222 delegate_ = NULL; |
| 222 Cancel(); | 223 Cancel(); |
| 223 } | 224 } |
| 224 | 225 |
| 225 void SpdyStream::AdjustSendWindowSize(int32_t delta_window_size) { | 226 void SpdyStream::AdjustSendWindowSize(int32_t delta_window_size) { |
| 226 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); | 227 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 return; | 551 return; |
| 551 buffer->AddConsumeCallback( | 552 buffer->AddConsumeCallback( |
| 552 base::Bind(&SpdyStream::OnReadBufferConsumed, GetWeakPtr())); | 553 base::Bind(&SpdyStream::OnReadBufferConsumed, GetWeakPtr())); |
| 553 } | 554 } |
| 554 | 555 |
| 555 // Track our bandwidth. | 556 // Track our bandwidth. |
| 556 recv_bytes_ += length; | 557 recv_bytes_ += length; |
| 557 recv_last_byte_time_ = base::TimeTicks::Now(); | 558 recv_last_byte_time_ = base::TimeTicks::Now(); |
| 558 | 559 |
| 559 // May close |this|. | 560 // May close |this|. |
| 560 delegate_->OnDataReceived(buffer.Pass()); | 561 delegate_->OnDataReceived(std::move(buffer)); |
| 561 } | 562 } |
| 562 | 563 |
| 563 void SpdyStream::OnPaddingConsumed(size_t len) { | 564 void SpdyStream::OnPaddingConsumed(size_t len) { |
| 564 if (session_->flow_control_state() >= SpdySession::FLOW_CONTROL_STREAM) { | 565 if (session_->flow_control_state() >= SpdySession::FLOW_CONTROL_STREAM) { |
| 565 // Decrease window size because padding bytes are received. | 566 // Decrease window size because padding bytes are received. |
| 566 // Increase window size because padding bytes are consumed (by discarding). | 567 // Increase window size because padding bytes are consumed (by discarding). |
| 567 // Net result: |unacked_recv_window_bytes_| increases by |len|, | 568 // Net result: |unacked_recv_window_bytes_| increases by |len|, |
| 568 // |recv_window_size_| does not change. | 569 // |recv_window_size_| does not change. |
| 569 base::WeakPtr<SpdyStream> weak_this = GetWeakPtr(); | 570 base::WeakPtr<SpdyStream> weak_this = GetWeakPtr(); |
| 570 // May close the stream. | 571 // May close the stream. |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 return weak_ptr_factory_.GetWeakPtr(); | 702 return weak_ptr_factory_.GetWeakPtr(); |
| 702 } | 703 } |
| 703 | 704 |
| 704 int SpdyStream::SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> request_headers, | 705 int SpdyStream::SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> request_headers, |
| 705 SpdySendStatus send_status) { | 706 SpdySendStatus send_status) { |
| 706 CHECK_NE(type_, SPDY_PUSH_STREAM); | 707 CHECK_NE(type_, SPDY_PUSH_STREAM); |
| 707 CHECK_EQ(pending_send_status_, MORE_DATA_TO_SEND); | 708 CHECK_EQ(pending_send_status_, MORE_DATA_TO_SEND); |
| 708 CHECK(!request_headers_); | 709 CHECK(!request_headers_); |
| 709 CHECK(!pending_send_data_.get()); | 710 CHECK(!pending_send_data_.get()); |
| 710 CHECK_EQ(io_state_, STATE_IDLE); | 711 CHECK_EQ(io_state_, STATE_IDLE); |
| 711 request_headers_ = request_headers.Pass(); | 712 request_headers_ = std::move(request_headers); |
| 712 pending_send_status_ = send_status; | 713 pending_send_status_ = send_status; |
| 713 session_->EnqueueStreamWrite( | 714 session_->EnqueueStreamWrite( |
| 714 GetWeakPtr(), SYN_STREAM, | 715 GetWeakPtr(), SYN_STREAM, |
| 715 scoped_ptr<SpdyBufferProducer>( | 716 scoped_ptr<SpdyBufferProducer>( |
| 716 new SynStreamBufferProducer(GetWeakPtr()))); | 717 new SynStreamBufferProducer(GetWeakPtr()))); |
| 717 return ERR_IO_PENDING; | 718 return ERR_IO_PENDING; |
| 718 } | 719 } |
| 719 | 720 |
| 720 void SpdyStream::SendData(IOBuffer* data, | 721 void SpdyStream::SendData(IOBuffer* data, |
| 721 int length, | 722 int length, |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 875 // here anyway just in case this changes. | 876 // here anyway just in case this changes. |
| 876 data_buffer->AddConsumeCallback( | 877 data_buffer->AddConsumeCallback( |
| 877 base::Bind(&SpdyStream::OnWriteBufferConsumed, | 878 base::Bind(&SpdyStream::OnWriteBufferConsumed, |
| 878 GetWeakPtr(), payload_size)); | 879 GetWeakPtr(), payload_size)); |
| 879 } | 880 } |
| 880 } | 881 } |
| 881 | 882 |
| 882 session_->EnqueueStreamWrite( | 883 session_->EnqueueStreamWrite( |
| 883 GetWeakPtr(), DATA, | 884 GetWeakPtr(), DATA, |
| 884 scoped_ptr<SpdyBufferProducer>( | 885 scoped_ptr<SpdyBufferProducer>( |
| 885 new SimpleBufferProducer(data_buffer.Pass()))); | 886 new SimpleBufferProducer(std::move(data_buffer)))); |
| 886 } | 887 } |
| 887 | 888 |
| 888 int SpdyStream::MergeWithResponseHeaders( | 889 int SpdyStream::MergeWithResponseHeaders( |
| 889 const SpdyHeaderBlock& new_response_headers) { | 890 const SpdyHeaderBlock& new_response_headers) { |
| 890 if (new_response_headers.find("transfer-encoding") != | 891 if (new_response_headers.find("transfer-encoding") != |
| 891 new_response_headers.end()) { | 892 new_response_headers.end()) { |
| 892 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, | 893 session_->ResetStream(stream_id_, RST_STREAM_PROTOCOL_ERROR, |
| 893 "Received transfer-encoding header"); | 894 "Received transfer-encoding header"); |
| 894 return ERR_SPDY_PROTOCOL_ERROR; | 895 return ERR_SPDY_PROTOCOL_ERROR; |
| 895 } | 896 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 961 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, | 962 description = base::StringPrintf("Unknown state 0x%08X (%u)", state, |
| 962 state); | 963 state); |
| 963 break; | 964 break; |
| 964 } | 965 } |
| 965 return description; | 966 return description; |
| 966 } | 967 } |
| 967 | 968 |
| 968 #undef STATE_CASE | 969 #undef STATE_CASE |
| 969 | 970 |
| 970 } // namespace net | 971 } // namespace net |
| OLD | NEW |