| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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_session.h" | 5 #include "net/spdy/spdy_session.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/linked_ptr.h" | 8 #include "base/linked_ptr.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 streams_abandoned_count_(0), | 248 streams_abandoned_count_(0), |
| 249 frames_received_(0), | 249 frames_received_(0), |
| 250 sent_settings_(false), | 250 sent_settings_(false), |
| 251 received_settings_(false), | 251 received_settings_(false), |
| 252 initial_send_window_size_(spdy::kInitialWindowSize), | 252 initial_send_window_size_(spdy::kInitialWindowSize), |
| 253 initial_recv_window_size_(spdy::kInitialWindowSize), | 253 initial_recv_window_size_(spdy::kInitialWindowSize), |
| 254 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)) { | 254 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)) { |
| 255 DCHECK(HttpStreamFactory::spdy_enabled()); | 255 DCHECK(HttpStreamFactory::spdy_enabled()); |
| 256 net_log_.BeginEvent( | 256 net_log_.BeginEvent( |
| 257 NetLog::TYPE_SPDY_SESSION, | 257 NetLog::TYPE_SPDY_SESSION, |
| 258 new NetLogSpdySessionParameter(host_port_proxy_pair_)); | 258 make_scoped_refptr( |
| 259 new NetLogSpdySessionParameter(host_port_proxy_pair_))); |
| 259 | 260 |
| 260 // TODO(mbelshe): consider randomization of the stream_hi_water_mark. | 261 // TODO(mbelshe): consider randomization of the stream_hi_water_mark. |
| 261 | 262 |
| 262 spdy_framer_.set_visitor(this); | 263 spdy_framer_.set_visitor(this); |
| 263 | 264 |
| 264 SendSettings(); | 265 SendSettings(); |
| 265 } | 266 } |
| 266 | 267 |
| 267 SpdySession::~SpdySession() { | 268 SpdySession::~SpdySession() { |
| 268 state_ = CLOSED; | 269 state_ = CLOSED; |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 flags, false, headers.get())); | 457 flags, false, headers.get())); |
| 457 QueueFrame(syn_frame.get(), priority, stream); | 458 QueueFrame(syn_frame.get(), priority, stream); |
| 458 | 459 |
| 459 static base::StatsCounter spdy_requests("spdy.requests"); | 460 static base::StatsCounter spdy_requests("spdy.requests"); |
| 460 spdy_requests.Increment(); | 461 spdy_requests.Increment(); |
| 461 streams_initiated_count_++; | 462 streams_initiated_count_++; |
| 462 | 463 |
| 463 if (net_log().IsLoggingAllEvents()) { | 464 if (net_log().IsLoggingAllEvents()) { |
| 464 net_log().AddEvent( | 465 net_log().AddEvent( |
| 465 NetLog::TYPE_SPDY_SESSION_SYN_STREAM, | 466 NetLog::TYPE_SPDY_SESSION_SYN_STREAM, |
| 466 new NetLogSpdySynParameter(headers, flags, stream_id)); | 467 make_scoped_refptr( |
| 468 new NetLogSpdySynParameter(headers, flags, stream_id))); |
| 467 } | 469 } |
| 468 | 470 |
| 469 return ERR_IO_PENDING; | 471 return ERR_IO_PENDING; |
| 470 } | 472 } |
| 471 | 473 |
| 472 int SpdySession::WriteStreamData(spdy::SpdyStreamId stream_id, | 474 int SpdySession::WriteStreamData(spdy::SpdyStreamId stream_id, |
| 473 net::IOBuffer* data, int len, | 475 net::IOBuffer* data, int len, |
| 474 spdy::SpdyDataFlags flags) { | 476 spdy::SpdyDataFlags flags) { |
| 475 // Find our stream | 477 // Find our stream |
| 476 DCHECK(IsStreamActive(stream_id)); | 478 DCHECK(IsStreamActive(stream_id)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 487 // Obey send window size of the stream if flow control is enabled. | 489 // Obey send window size of the stream if flow control is enabled. |
| 488 if (use_flow_control_) { | 490 if (use_flow_control_) { |
| 489 if (stream->send_window_size() <= 0) { | 491 if (stream->send_window_size() <= 0) { |
| 490 // Because we queue frames onto the session, it is possible that | 492 // Because we queue frames onto the session, it is possible that |
| 491 // a stream was not flow controlled at the time it attempted the | 493 // a stream was not flow controlled at the time it attempted the |
| 492 // write, but when we go to fulfill the write, it is now flow | 494 // write, but when we go to fulfill the write, it is now flow |
| 493 // controlled. This is why we need the session to mark the stream | 495 // controlled. This is why we need the session to mark the stream |
| 494 // as stalled - because only the session knows for sure when the | 496 // as stalled - because only the session knows for sure when the |
| 495 // stall occurs. | 497 // stall occurs. |
| 496 stream->set_stalled_by_flow_control(true); | 498 stream->set_stalled_by_flow_control(true); |
| 497 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_STALLED_ON_SEND_WINDOW, | 499 net_log().AddEvent( |
| 498 new NetLogIntegerParameter("stream_id", stream_id)); | 500 NetLog::TYPE_SPDY_SESSION_STALLED_ON_SEND_WINDOW, |
| 501 make_scoped_refptr( |
| 502 new NetLogIntegerParameter("stream_id", stream_id))); |
| 499 return ERR_IO_PENDING; | 503 return ERR_IO_PENDING; |
| 500 } | 504 } |
| 501 int new_len = std::min(len, stream->send_window_size()); | 505 int new_len = std::min(len, stream->send_window_size()); |
| 502 if (new_len < len) { | 506 if (new_len < len) { |
| 503 len = new_len; | 507 len = new_len; |
| 504 flags = static_cast<spdy::SpdyDataFlags>(flags & ~spdy::DATA_FLAG_FIN); | 508 flags = static_cast<spdy::SpdyDataFlags>(flags & ~spdy::DATA_FLAG_FIN); |
| 505 } | 509 } |
| 506 stream->DecreaseSendWindowSize(len); | 510 stream->DecreaseSendWindowSize(len); |
| 507 } | 511 } |
| 508 | 512 |
| 509 if (net_log().IsLoggingAllEvents()) | 513 if (net_log().IsLoggingAllEvents()) { |
| 510 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_SEND_DATA, | 514 net_log().AddEvent( |
| 511 new NetLogSpdyDataParameter(stream_id, len, flags)); | 515 NetLog::TYPE_SPDY_SESSION_SEND_DATA, |
| 516 make_scoped_refptr(new NetLogSpdyDataParameter(stream_id, len, flags))); |
| 517 } |
| 512 | 518 |
| 513 // TODO(mbelshe): reduce memory copies here. | 519 // TODO(mbelshe): reduce memory copies here. |
| 514 scoped_ptr<spdy::SpdyDataFrame> frame( | 520 scoped_ptr<spdy::SpdyDataFrame> frame( |
| 515 spdy_framer_.CreateDataFrame(stream_id, data->data(), len, flags)); | 521 spdy_framer_.CreateDataFrame(stream_id, data->data(), len, flags)); |
| 516 QueueFrame(frame.get(), stream->priority(), stream); | 522 QueueFrame(frame.get(), stream->priority(), stream); |
| 517 return ERR_IO_PENDING; | 523 return ERR_IO_PENDING; |
| 518 } | 524 } |
| 519 | 525 |
| 520 void SpdySession::CloseStream(spdy::SpdyStreamId stream_id, int status) { | 526 void SpdySession::CloseStream(spdy::SpdyStreamId stream_id, int status) { |
| 521 // TODO(mbelshe): We should send a RST_STREAM control frame here | 527 // TODO(mbelshe): We should send a RST_STREAM control frame here |
| 522 // so that the server can cancel a large send. | 528 // so that the server can cancel a large send. |
| 523 | 529 |
| 524 DeleteStream(stream_id, status); | 530 DeleteStream(stream_id, status); |
| 525 } | 531 } |
| 526 | 532 |
| 527 void SpdySession::ResetStream( | 533 void SpdySession::ResetStream( |
| 528 spdy::SpdyStreamId stream_id, spdy::SpdyStatusCodes status) { | 534 spdy::SpdyStreamId stream_id, spdy::SpdyStatusCodes status) { |
| 529 | 535 |
| 530 net_log().AddEvent( | 536 net_log().AddEvent( |
| 531 NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM, | 537 NetLog::TYPE_SPDY_SESSION_SEND_RST_STREAM, |
| 532 new NetLogSpdyRstParameter(stream_id, status)); | 538 make_scoped_refptr(new NetLogSpdyRstParameter(stream_id, status))); |
| 533 | 539 |
| 534 scoped_ptr<spdy::SpdyRstStreamControlFrame> rst_frame( | 540 scoped_ptr<spdy::SpdyRstStreamControlFrame> rst_frame( |
| 535 spdy_framer_.CreateRstStream(stream_id, status)); | 541 spdy_framer_.CreateRstStream(stream_id, status)); |
| 536 | 542 |
| 537 // Default to lowest priority unless we know otherwise. | 543 // Default to lowest priority unless we know otherwise. |
| 538 int priority = 3; | 544 int priority = 3; |
| 539 if(IsStreamActive(stream_id)) { | 545 if(IsStreamActive(stream_id)) { |
| 540 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 546 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
| 541 priority = stream->priority(); | 547 priority = stream->priority(); |
| 542 } | 548 } |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 | 828 |
| 823 WriteSocketLater(); | 829 WriteSocketLater(); |
| 824 } | 830 } |
| 825 | 831 |
| 826 void SpdySession::CloseSessionOnError(net::Error err, bool remove_from_pool) { | 832 void SpdySession::CloseSessionOnError(net::Error err, bool remove_from_pool) { |
| 827 // Closing all streams can have a side-effect of dropping the last reference | 833 // Closing all streams can have a side-effect of dropping the last reference |
| 828 // to |this|. Hold a reference through this function. | 834 // to |this|. Hold a reference through this function. |
| 829 scoped_refptr<SpdySession> self(this); | 835 scoped_refptr<SpdySession> self(this); |
| 830 | 836 |
| 831 DCHECK_LT(err, OK); | 837 DCHECK_LT(err, OK); |
| 832 net_log_.AddEvent(NetLog::TYPE_SPDY_SESSION_CLOSE, | 838 net_log_.AddEvent( |
| 833 new NetLogIntegerParameter("status", err)); | 839 NetLog::TYPE_SPDY_SESSION_CLOSE, |
| 840 make_scoped_refptr(new NetLogIntegerParameter("status", err))); |
| 834 | 841 |
| 835 // Don't close twice. This can occur because we can have both | 842 // Don't close twice. This can occur because we can have both |
| 836 // a read and a write outstanding, and each can complete with | 843 // a read and a write outstanding, and each can complete with |
| 837 // an error. | 844 // an error. |
| 838 if (state_ != CLOSED) { | 845 if (state_ != CLOSED) { |
| 839 state_ = CLOSED; | 846 state_ = CLOSED; |
| 840 error_ = err; | 847 error_ = err; |
| 841 if (remove_from_pool) | 848 if (remove_from_pool) |
| 842 RemoveFromPool(); | 849 RemoveFromPool(); |
| 843 CloseAllStreams(err); | 850 CloseAllStreams(err); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 // If this is an active stream, call the callback. | 912 // If this is an active stream, call the callback. |
| 906 const scoped_refptr<SpdyStream> stream(it2->second); | 913 const scoped_refptr<SpdyStream> stream(it2->second); |
| 907 active_streams_.erase(it2); | 914 active_streams_.erase(it2); |
| 908 if (stream) | 915 if (stream) |
| 909 stream->OnClose(status); | 916 stream->OnClose(status); |
| 910 ProcessPendingCreateStreams(); | 917 ProcessPendingCreateStreams(); |
| 911 } | 918 } |
| 912 | 919 |
| 913 void SpdySession::RemoveFromPool() { | 920 void SpdySession::RemoveFromPool() { |
| 914 if (spdy_session_pool_) { | 921 if (spdy_session_pool_) { |
| 915 spdy_session_pool_->Remove(this); | 922 spdy_session_pool_->Remove(make_scoped_refptr(this)); |
| 916 spdy_session_pool_ = NULL; | 923 spdy_session_pool_ = NULL; |
| 917 } | 924 } |
| 918 } | 925 } |
| 919 | 926 |
| 920 scoped_refptr<SpdyStream> SpdySession::GetActivePushStream( | 927 scoped_refptr<SpdyStream> SpdySession::GetActivePushStream( |
| 921 const std::string& path) { | 928 const std::string& path) { |
| 922 static base::StatsCounter used_push_streams("spdy.claimed_push_streams"); | 929 static base::StatsCounter used_push_streams("spdy.claimed_push_streams"); |
| 923 | 930 |
| 924 PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(path); | 931 PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(path); |
| 925 if (it != unclaimed_pushed_streams_.end()) { | 932 if (it != unclaimed_pushed_streams_.end()) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 956 return false; | 963 return false; |
| 957 } | 964 } |
| 958 | 965 |
| 959 void SpdySession::OnError(spdy::SpdyFramer* framer) { | 966 void SpdySession::OnError(spdy::SpdyFramer* framer) { |
| 960 CloseSessionOnError(net::ERR_SPDY_PROTOCOL_ERROR, true); | 967 CloseSessionOnError(net::ERR_SPDY_PROTOCOL_ERROR, true); |
| 961 } | 968 } |
| 962 | 969 |
| 963 void SpdySession::OnStreamFrameData(spdy::SpdyStreamId stream_id, | 970 void SpdySession::OnStreamFrameData(spdy::SpdyStreamId stream_id, |
| 964 const char* data, | 971 const char* data, |
| 965 size_t len) { | 972 size_t len) { |
| 966 if (net_log().IsLoggingAllEvents()) | 973 if (net_log().IsLoggingAllEvents()) { |
| 967 net_log().AddEvent(NetLog::TYPE_SPDY_SESSION_RECV_DATA, | 974 net_log().AddEvent( |
| 968 new NetLogSpdyDataParameter(stream_id, len, spdy::SpdyDataFlags())); | 975 NetLog::TYPE_SPDY_SESSION_RECV_DATA, |
| 976 make_scoped_refptr(new NetLogSpdyDataParameter( |
| 977 stream_id, len, spdy::SpdyDataFlags()))); |
| 978 } |
| 969 | 979 |
| 970 if (!IsStreamActive(stream_id)) { | 980 if (!IsStreamActive(stream_id)) { |
| 971 // NOTE: it may just be that the stream was cancelled. | 981 // NOTE: it may just be that the stream was cancelled. |
| 972 LOG(WARNING) << "Received data frame for invalid stream " << stream_id; | 982 LOG(WARNING) << "Received data frame for invalid stream " << stream_id; |
| 973 return; | 983 return; |
| 974 } | 984 } |
| 975 | 985 |
| 976 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 986 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
| 977 stream->OnDataReceived(data, len); | 987 stream->OnDataReceived(data, len); |
| 978 } | 988 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 992 } | 1002 } |
| 993 | 1003 |
| 994 void SpdySession::OnSyn(const spdy::SpdySynStreamControlFrame& frame, | 1004 void SpdySession::OnSyn(const spdy::SpdySynStreamControlFrame& frame, |
| 995 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { | 1005 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { |
| 996 spdy::SpdyStreamId stream_id = frame.stream_id(); | 1006 spdy::SpdyStreamId stream_id = frame.stream_id(); |
| 997 spdy::SpdyStreamId associated_stream_id = frame.associated_stream_id(); | 1007 spdy::SpdyStreamId associated_stream_id = frame.associated_stream_id(); |
| 998 | 1008 |
| 999 if (net_log_.IsLoggingAllEvents()) { | 1009 if (net_log_.IsLoggingAllEvents()) { |
| 1000 net_log_.AddEvent( | 1010 net_log_.AddEvent( |
| 1001 NetLog::TYPE_SPDY_SESSION_PUSHED_SYN_STREAM, | 1011 NetLog::TYPE_SPDY_SESSION_PUSHED_SYN_STREAM, |
| 1002 new NetLogSpdySynParameter( | 1012 make_scoped_refptr(new NetLogSpdySynParameter( |
| 1003 headers, static_cast<spdy::SpdyControlFlags>(frame.flags()), | 1013 headers, static_cast<spdy::SpdyControlFlags>(frame.flags()), |
| 1004 stream_id)); | 1014 stream_id))); |
| 1005 } | 1015 } |
| 1006 | 1016 |
| 1007 // Server-initiated streams should have even sequence numbers. | 1017 // Server-initiated streams should have even sequence numbers. |
| 1008 if ((stream_id & 0x1) != 0) { | 1018 if ((stream_id & 0x1) != 0) { |
| 1009 LOG(ERROR) << "Received invalid OnSyn stream id " << stream_id; | 1019 LOG(ERROR) << "Received invalid OnSyn stream id " << stream_id; |
| 1010 return; | 1020 return; |
| 1011 } | 1021 } |
| 1012 | 1022 |
| 1013 if (IsStreamActive(stream_id)) { | 1023 if (IsStreamActive(stream_id)) { |
| 1014 LOG(ERROR) << "Received OnSyn for active stream " << stream_id; | 1024 LOG(ERROR) << "Received OnSyn for active stream " << stream_id; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1090 if (stream->response_received()) { | 1100 if (stream->response_received()) { |
| 1091 LOG(WARNING) << "Received duplicate SYN_REPLY for stream " << stream_id; | 1101 LOG(WARNING) << "Received duplicate SYN_REPLY for stream " << stream_id; |
| 1092 CloseStream(stream->stream_id(), ERR_SPDY_PROTOCOL_ERROR); | 1102 CloseStream(stream->stream_id(), ERR_SPDY_PROTOCOL_ERROR); |
| 1093 return; | 1103 return; |
| 1094 } | 1104 } |
| 1095 stream->set_response_received(); | 1105 stream->set_response_received(); |
| 1096 | 1106 |
| 1097 if (net_log().IsLoggingAllEvents()) { | 1107 if (net_log().IsLoggingAllEvents()) { |
| 1098 net_log().AddEvent( | 1108 net_log().AddEvent( |
| 1099 NetLog::TYPE_SPDY_SESSION_SYN_REPLY, | 1109 NetLog::TYPE_SPDY_SESSION_SYN_REPLY, |
| 1100 new NetLogSpdySynParameter( | 1110 make_scoped_refptr(new NetLogSpdySynParameter( |
| 1101 headers, static_cast<spdy::SpdyControlFlags>(frame.flags()), | 1111 headers, static_cast<spdy::SpdyControlFlags>(frame.flags()), |
| 1102 stream_id)); | 1112 stream_id))); |
| 1103 } | 1113 } |
| 1104 | 1114 |
| 1105 Respond(*headers, stream); | 1115 Respond(*headers, stream); |
| 1106 } | 1116 } |
| 1107 | 1117 |
| 1108 void SpdySession::OnControl(const spdy::SpdyControlFrame* frame) { | 1118 void SpdySession::OnControl(const spdy::SpdyControlFrame* frame) { |
| 1109 const linked_ptr<spdy::SpdyHeaderBlock> headers(new spdy::SpdyHeaderBlock); | 1119 const linked_ptr<spdy::SpdyHeaderBlock> headers(new spdy::SpdyHeaderBlock); |
| 1110 uint32 type = frame->type(); | 1120 uint32 type = frame->type(); |
| 1111 if (type == spdy::SYN_STREAM || type == spdy::SYN_REPLY) { | 1121 if (type == spdy::SYN_STREAM || type == spdy::SYN_REPLY) { |
| 1112 if (!spdy_framer_.ParseHeaderBlock(frame, headers.get())) { | 1122 if (!spdy_framer_.ParseHeaderBlock(frame, headers.get())) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1153 default: | 1163 default: |
| 1154 DCHECK(false); // Error! | 1164 DCHECK(false); // Error! |
| 1155 } | 1165 } |
| 1156 } | 1166 } |
| 1157 | 1167 |
| 1158 void SpdySession::OnRst(const spdy::SpdyRstStreamControlFrame& frame) { | 1168 void SpdySession::OnRst(const spdy::SpdyRstStreamControlFrame& frame) { |
| 1159 spdy::SpdyStreamId stream_id = frame.stream_id(); | 1169 spdy::SpdyStreamId stream_id = frame.stream_id(); |
| 1160 | 1170 |
| 1161 net_log().AddEvent( | 1171 net_log().AddEvent( |
| 1162 NetLog::TYPE_SPDY_SESSION_RST_STREAM, | 1172 NetLog::TYPE_SPDY_SESSION_RST_STREAM, |
| 1163 new NetLogSpdyRstParameter(stream_id, frame.status())); | 1173 make_scoped_refptr( |
| 1174 new NetLogSpdyRstParameter(stream_id, frame.status()))); |
| 1164 | 1175 |
| 1165 bool valid_stream = IsStreamActive(stream_id); | 1176 bool valid_stream = IsStreamActive(stream_id); |
| 1166 if (!valid_stream) { | 1177 if (!valid_stream) { |
| 1167 // NOTE: it may just be that the stream was cancelled. | 1178 // NOTE: it may just be that the stream was cancelled. |
| 1168 LOG(WARNING) << "Received RST for invalid stream" << stream_id; | 1179 LOG(WARNING) << "Received RST for invalid stream" << stream_id; |
| 1169 return; | 1180 return; |
| 1170 } | 1181 } |
| 1171 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 1182 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
| 1172 CHECK_EQ(stream->stream_id(), stream_id); | 1183 CHECK_EQ(stream->stream_id(), stream_id); |
| 1173 CHECK(!stream->cancelled()); | 1184 CHECK(!stream->cancelled()); |
| 1174 | 1185 |
| 1175 if (frame.status() == 0) { | 1186 if (frame.status() == 0) { |
| 1176 stream->OnDataReceived(NULL, 0); | 1187 stream->OnDataReceived(NULL, 0); |
| 1177 } else { | 1188 } else { |
| 1178 LOG(ERROR) << "Spdy stream closed: " << frame.status(); | 1189 LOG(ERROR) << "Spdy stream closed: " << frame.status(); |
| 1179 // TODO(mbelshe): Map from Spdy-protocol errors to something sensical. | 1190 // TODO(mbelshe): Map from Spdy-protocol errors to something sensical. |
| 1180 // For now, it doesn't matter much - it is a protocol error. | 1191 // For now, it doesn't matter much - it is a protocol error. |
| 1181 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); | 1192 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); |
| 1182 } | 1193 } |
| 1183 } | 1194 } |
| 1184 | 1195 |
| 1185 void SpdySession::OnGoAway(const spdy::SpdyGoAwayControlFrame& frame) { | 1196 void SpdySession::OnGoAway(const spdy::SpdyGoAwayControlFrame& frame) { |
| 1186 net_log_.AddEvent( | 1197 net_log_.AddEvent( |
| 1187 NetLog::TYPE_SPDY_SESSION_GOAWAY, | 1198 NetLog::TYPE_SPDY_SESSION_GOAWAY, |
| 1188 new NetLogSpdyGoAwayParameter(frame.last_accepted_stream_id(), | 1199 make_scoped_refptr( |
| 1189 active_streams_.size(), | 1200 new NetLogSpdyGoAwayParameter(frame.last_accepted_stream_id(), |
| 1190 unclaimed_pushed_streams_.size())); | 1201 active_streams_.size(), |
| 1202 unclaimed_pushed_streams_.size()))); |
| 1191 RemoveFromPool(); | 1203 RemoveFromPool(); |
| 1192 CloseAllStreams(net::ERR_ABORTED); | 1204 CloseAllStreams(net::ERR_ABORTED); |
| 1193 | 1205 |
| 1194 // TODO(willchan): Cancel any streams that are past the GoAway frame's | 1206 // TODO(willchan): Cancel any streams that are past the GoAway frame's |
| 1195 // |last_accepted_stream_id|. | 1207 // |last_accepted_stream_id|. |
| 1196 | 1208 |
| 1197 // Don't bother killing any streams that are still reading. They'll either | 1209 // Don't bother killing any streams that are still reading. They'll either |
| 1198 // complete successfully or get an ERR_CONNECTION_CLOSED when the socket is | 1210 // complete successfully or get an ERR_CONNECTION_CLOSED when the socket is |
| 1199 // closed. | 1211 // closed. |
| 1200 } | 1212 } |
| 1201 | 1213 |
| 1202 void SpdySession::OnSettings(const spdy::SpdySettingsControlFrame& frame) { | 1214 void SpdySession::OnSettings(const spdy::SpdySettingsControlFrame& frame) { |
| 1203 spdy::SpdySettings settings; | 1215 spdy::SpdySettings settings; |
| 1204 if (spdy_framer_.ParseSettings(&frame, &settings)) { | 1216 if (spdy_framer_.ParseSettings(&frame, &settings)) { |
| 1205 HandleSettings(settings); | 1217 HandleSettings(settings); |
| 1206 spdy_settings_->Set(host_port_pair(), settings); | 1218 spdy_settings_->Set(host_port_pair(), settings); |
| 1207 } | 1219 } |
| 1208 | 1220 |
| 1209 received_settings_ = true; | 1221 received_settings_ = true; |
| 1210 | 1222 |
| 1211 net_log_.AddEvent( | 1223 net_log_.AddEvent( |
| 1212 NetLog::TYPE_SPDY_SESSION_RECV_SETTINGS, | 1224 NetLog::TYPE_SPDY_SESSION_RECV_SETTINGS, |
| 1213 new NetLogSpdySettingsParameter(settings)); | 1225 make_scoped_refptr(new NetLogSpdySettingsParameter(settings))); |
| 1214 } | 1226 } |
| 1215 | 1227 |
| 1216 void SpdySession::OnWindowUpdate( | 1228 void SpdySession::OnWindowUpdate( |
| 1217 const spdy::SpdyWindowUpdateControlFrame& frame) { | 1229 const spdy::SpdyWindowUpdateControlFrame& frame) { |
| 1218 spdy::SpdyStreamId stream_id = frame.stream_id(); | 1230 spdy::SpdyStreamId stream_id = frame.stream_id(); |
| 1219 if (!IsStreamActive(stream_id)) { | 1231 if (!IsStreamActive(stream_id)) { |
| 1220 LOG(WARNING) << "Received WINDOW_UPDATE for invalid stream " << stream_id; | 1232 LOG(WARNING) << "Received WINDOW_UPDATE for invalid stream " << stream_id; |
| 1221 return; | 1233 return; |
| 1222 } | 1234 } |
| 1223 | 1235 |
| 1224 int delta_window_size = static_cast<int>(frame.delta_window_size()); | 1236 int delta_window_size = static_cast<int>(frame.delta_window_size()); |
| 1225 if (delta_window_size < 1) { | 1237 if (delta_window_size < 1) { |
| 1226 LOG(WARNING) << "Received WINDOW_UPDATE with an invalid delta_window_size " | 1238 LOG(WARNING) << "Received WINDOW_UPDATE with an invalid delta_window_size " |
| 1227 << delta_window_size; | 1239 << delta_window_size; |
| 1228 ResetStream(stream_id, spdy::FLOW_CONTROL_ERROR); | 1240 ResetStream(stream_id, spdy::FLOW_CONTROL_ERROR); |
| 1229 return; | 1241 return; |
| 1230 } | 1242 } |
| 1231 | 1243 |
| 1232 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 1244 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
| 1233 CHECK_EQ(stream->stream_id(), stream_id); | 1245 CHECK_EQ(stream->stream_id(), stream_id); |
| 1234 CHECK(!stream->cancelled()); | 1246 CHECK(!stream->cancelled()); |
| 1235 | 1247 |
| 1236 if (use_flow_control_) | 1248 if (use_flow_control_) |
| 1237 stream->IncreaseSendWindowSize(delta_window_size); | 1249 stream->IncreaseSendWindowSize(delta_window_size); |
| 1238 | 1250 |
| 1239 net_log_.AddEvent( | 1251 net_log_.AddEvent( |
| 1240 NetLog::TYPE_SPDY_SESSION_SEND_WINDOW_UPDATE, | 1252 NetLog::TYPE_SPDY_SESSION_SEND_WINDOW_UPDATE, |
| 1241 new NetLogSpdyWindowUpdateParameter(stream_id, | 1253 make_scoped_refptr(new NetLogSpdyWindowUpdateParameter( |
| 1242 delta_window_size, | 1254 stream_id, delta_window_size, stream->send_window_size()))); |
| 1243 stream->send_window_size())); | |
| 1244 } | 1255 } |
| 1245 | 1256 |
| 1246 void SpdySession::SendWindowUpdate(spdy::SpdyStreamId stream_id, | 1257 void SpdySession::SendWindowUpdate(spdy::SpdyStreamId stream_id, |
| 1247 int delta_window_size) { | 1258 int delta_window_size) { |
| 1248 DCHECK(IsStreamActive(stream_id)); | 1259 DCHECK(IsStreamActive(stream_id)); |
| 1249 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 1260 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
| 1250 CHECK_EQ(stream->stream_id(), stream_id); | 1261 CHECK_EQ(stream->stream_id(), stream_id); |
| 1251 | 1262 |
| 1252 net_log_.AddEvent( | 1263 net_log_.AddEvent( |
| 1253 NetLog::TYPE_SPDY_SESSION_RECV_WINDOW_UPDATE, | 1264 NetLog::TYPE_SPDY_SESSION_RECV_WINDOW_UPDATE, |
| 1254 new NetLogSpdyWindowUpdateParameter(stream_id, | 1265 make_scoped_refptr(new NetLogSpdyWindowUpdateParameter( |
| 1255 delta_window_size, | 1266 stream_id, delta_window_size, stream->recv_window_size()))); |
| 1256 stream->recv_window_size())); | |
| 1257 | 1267 |
| 1258 scoped_ptr<spdy::SpdyWindowUpdateControlFrame> window_update_frame( | 1268 scoped_ptr<spdy::SpdyWindowUpdateControlFrame> window_update_frame( |
| 1259 spdy_framer_.CreateWindowUpdate(stream_id, delta_window_size)); | 1269 spdy_framer_.CreateWindowUpdate(stream_id, delta_window_size)); |
| 1260 QueueFrame(window_update_frame.get(), stream->priority(), stream); | 1270 QueueFrame(window_update_frame.get(), stream->priority(), stream); |
| 1261 } | 1271 } |
| 1262 | 1272 |
| 1263 void SpdySession::SendSettings() { | 1273 void SpdySession::SendSettings() { |
| 1264 const spdy::SpdySettings& settings = spdy_settings_->Get(host_port_pair()); | 1274 const spdy::SpdySettings& settings = spdy_settings_->Get(host_port_pair()); |
| 1265 if (settings.empty()) | 1275 if (settings.empty()) |
| 1266 return; | 1276 return; |
| 1267 HandleSettings(settings); | 1277 HandleSettings(settings); |
| 1268 | 1278 |
| 1269 net_log_.AddEvent( | 1279 net_log_.AddEvent( |
| 1270 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS, | 1280 NetLog::TYPE_SPDY_SESSION_SEND_SETTINGS, |
| 1271 new NetLogSpdySettingsParameter(settings)); | 1281 make_scoped_refptr(new NetLogSpdySettingsParameter(settings))); |
| 1272 | 1282 |
| 1273 // Create the SETTINGS frame and send it. | 1283 // Create the SETTINGS frame and send it. |
| 1274 scoped_ptr<spdy::SpdySettingsControlFrame> settings_frame( | 1284 scoped_ptr<spdy::SpdySettingsControlFrame> settings_frame( |
| 1275 spdy_framer_.CreateSettings(settings)); | 1285 spdy_framer_.CreateSettings(settings)); |
| 1276 sent_settings_ = true; | 1286 sent_settings_ = true; |
| 1277 QueueFrame(settings_frame.get(), 0, NULL); | 1287 QueueFrame(settings_frame.get(), 0, NULL); |
| 1278 } | 1288 } |
| 1279 | 1289 |
| 1280 void SpdySession::HandleSettings(const spdy::SpdySettings& settings) { | 1290 void SpdySession::HandleSettings(const spdy::SpdySettings& settings) { |
| 1281 for (spdy::SpdySettings::const_iterator i = settings.begin(), | 1291 for (spdy::SpdySettings::const_iterator i = settings.begin(), |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1337 } | 1347 } |
| 1338 } | 1348 } |
| 1339 } | 1349 } |
| 1340 | 1350 |
| 1341 void SpdySession::InvokeUserStreamCreationCallback( | 1351 void SpdySession::InvokeUserStreamCreationCallback( |
| 1342 CompletionCallback* callback, int rv) { | 1352 CompletionCallback* callback, int rv) { |
| 1343 callback->Run(rv); | 1353 callback->Run(rv); |
| 1344 } | 1354 } |
| 1345 | 1355 |
| 1346 } // namespace net | 1356 } // namespace net |
| OLD | NEW |