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 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 } | 271 } |
272 | 272 |
273 const std::string& path = url.PathForRequest(); | 273 const std::string& path = url.PathForRequest(); |
274 | 274 |
275 *stream = GetActivePushStream(path); | 275 *stream = GetActivePushStream(path); |
276 if (stream->get()) { | 276 if (stream->get()) { |
277 DCHECK(streams_pushed_and_claimed_count_ < streams_pushed_count_); | 277 DCHECK(streams_pushed_and_claimed_count_ < streams_pushed_count_); |
278 streams_pushed_and_claimed_count_++; | 278 streams_pushed_and_claimed_count_++; |
279 return OK; | 279 return OK; |
280 } | 280 } |
281 | 281 return NULL; |
282 // Check if we have a pending push stream for this url. | |
283 // Note that we shouldn't have a pushed stream for non-GET method. | |
284 PendingStreamMap::iterator it; | |
285 it = pending_streams_.find(path); | |
286 if (it != pending_streams_.end()) { | |
287 // Server has advertised a stream, but not yet sent it. | |
288 DCHECK(!it->second); | |
289 // Server will assign a stream id when the push stream arrives. Use 0 for | |
290 // now. | |
291 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_ADOPTED_PUSH_STREAM, NULL); | |
292 *stream = new SpdyStream(this, 0, true); | |
293 (*stream)->set_path(path); | |
294 (*stream)->set_net_log(stream_net_log); | |
295 it->second = *stream; | |
296 return OK; | |
297 } | |
298 return OK; | |
299 } | 282 } |
300 | 283 |
301 int SpdySession::CreateStream( | 284 int SpdySession::CreateStream( |
302 const GURL& url, | 285 const GURL& url, |
303 RequestPriority priority, | 286 RequestPriority priority, |
304 scoped_refptr<SpdyStream>* spdy_stream, | 287 scoped_refptr<SpdyStream>* spdy_stream, |
305 const BoundNetLog& stream_net_log, | 288 const BoundNetLog& stream_net_log, |
306 CompletionCallback* callback) { | 289 CompletionCallback* callback) { |
307 if (!max_concurrent_streams_ || | 290 if (!max_concurrent_streams_ || |
308 active_streams_.size() < max_concurrent_streams_) { | 291 active_streams_.size() < max_concurrent_streams_) { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 void SpdySession::CloseStream(spdy::SpdyStreamId stream_id, int status) { | 448 void SpdySession::CloseStream(spdy::SpdyStreamId stream_id, int status) { |
466 LOG(INFO) << "Closing stream " << stream_id << " with status " << status; | 449 LOG(INFO) << "Closing stream " << stream_id << " with status " << status; |
467 // TODO(mbelshe): We should send a RST_STREAM control frame here | 450 // TODO(mbelshe): We should send a RST_STREAM control frame here |
468 // so that the server can cancel a large send. | 451 // so that the server can cancel a large send. |
469 | 452 |
470 DeleteStream(stream_id, status); | 453 DeleteStream(stream_id, status); |
471 } | 454 } |
472 | 455 |
473 void SpdySession::ResetStream( | 456 void SpdySession::ResetStream( |
474 spdy::SpdyStreamId stream_id, spdy::SpdyStatusCodes status) { | 457 spdy::SpdyStreamId stream_id, spdy::SpdyStatusCodes status) { |
475 DCHECK(IsStreamActive(stream_id)); | |
476 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | |
477 CHECK_EQ(stream->stream_id(), stream_id); | |
478 | |
479 LOG(INFO) << "Sending a RST_STREAM frame for stream " << stream_id | 458 LOG(INFO) << "Sending a RST_STREAM frame for stream " << stream_id |
480 << " with status " << status; | 459 << " with status " << status; |
481 | 460 |
482 scoped_ptr<spdy::SpdyRstStreamControlFrame> rst_frame( | 461 scoped_ptr<spdy::SpdyRstStreamControlFrame> rst_frame( |
483 spdy_framer_.CreateRstStream(stream_id, status)); | 462 spdy_framer_.CreateRstStream(stream_id, status)); |
484 QueueFrame(rst_frame.get(), stream->priority(), stream); | 463 |
| 464 // Default to lowest priority unless we know otherwise. |
| 465 int priority = 3; |
| 466 if(IsStreamActive(stream_id)) { |
| 467 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
| 468 priority = stream->priority(); |
| 469 } |
| 470 QueueFrame(rst_frame.get(), priority, NULL); |
485 | 471 |
486 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); | 472 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); |
487 } | 473 } |
488 | 474 |
489 bool SpdySession::IsStreamActive(spdy::SpdyStreamId stream_id) const { | 475 bool SpdySession::IsStreamActive(spdy::SpdyStreamId stream_id) const { |
490 return ContainsKey(active_streams_, stream_id); | 476 return ContainsKey(active_streams_, stream_id); |
491 } | 477 } |
492 | 478 |
493 LoadState SpdySession::GetLoadState() const { | 479 LoadState SpdySession::GetLoadState() const { |
494 // NOTE: The application only queries the LoadState via the | 480 // NOTE: The application only queries the LoadState via the |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 } | 764 } |
779 | 765 |
780 void SpdySession::CloseAllStreams(net::Error status) { | 766 void SpdySession::CloseAllStreams(net::Error status) { |
781 LOG(INFO) << "Closing all SPDY Streams for " << host_port_pair().ToString(); | 767 LOG(INFO) << "Closing all SPDY Streams for " << host_port_pair().ToString(); |
782 | 768 |
783 static StatsCounter abandoned_streams("spdy.abandoned_streams"); | 769 static StatsCounter abandoned_streams("spdy.abandoned_streams"); |
784 static StatsCounter abandoned_push_streams("spdy.abandoned_push_streams"); | 770 static StatsCounter abandoned_push_streams("spdy.abandoned_push_streams"); |
785 | 771 |
786 if (!active_streams_.empty()) | 772 if (!active_streams_.empty()) |
787 abandoned_streams.Add(active_streams_.size()); | 773 abandoned_streams.Add(active_streams_.size()); |
788 if (!pushed_streams_.empty()) { | 774 if (!unclaimed_pushed_streams_.empty()) { |
789 streams_abandoned_count_ += pushed_streams_.size(); | 775 streams_abandoned_count_ += unclaimed_pushed_streams_.size(); |
790 abandoned_push_streams.Add(pushed_streams_.size()); | 776 abandoned_push_streams.Add(unclaimed_pushed_streams_.size()); |
791 } | 777 } |
792 | 778 |
793 for (int i = 0;i < NUM_PRIORITIES;++i) { | 779 for (int i = 0;i < NUM_PRIORITIES;++i) { |
794 while (!create_stream_queues_[i].empty()) { | 780 while (!create_stream_queues_[i].empty()) { |
795 PendingCreateStream& pending_create = create_stream_queues_[i].front(); | 781 PendingCreateStream& pending_create = create_stream_queues_[i].front(); |
796 pending_create.callback->Run(ERR_ABORTED); | 782 pending_create.callback->Run(ERR_ABORTED); |
797 create_stream_queues_[i].pop(); | 783 create_stream_queues_[i].pop(); |
798 } | 784 } |
799 } | 785 } |
800 | 786 |
801 while (!active_streams_.empty()) { | 787 while (!active_streams_.empty()) { |
802 ActiveStreamMap::iterator it = active_streams_.begin(); | 788 ActiveStreamMap::iterator it = active_streams_.begin(); |
803 const scoped_refptr<SpdyStream>& stream = it->second; | 789 const scoped_refptr<SpdyStream>& stream = it->second; |
804 DCHECK(stream); | 790 DCHECK(stream); |
805 LOG(ERROR) << "ABANDONED (stream_id=" << stream->stream_id() | 791 LOG(ERROR) << "ABANDONED (stream_id=" << stream->stream_id() |
806 << "): " << stream->path(); | 792 << "): " << stream->path(); |
807 DeleteStream(stream->stream_id(), status); | 793 DeleteStream(stream->stream_id(), status); |
808 } | 794 } |
809 | 795 |
810 // TODO(erikchen): ideally stream->OnClose() is only ever called by | |
811 // DeleteStream, but pending streams fall into their own category for now. | |
812 PendingStreamMap::iterator it; | |
813 for (it = pending_streams_.begin(); it != pending_streams_.end(); ++it) { | |
814 const scoped_refptr<SpdyStream>& stream = it->second; | |
815 if (stream) | |
816 stream->OnClose(ERR_ABORTED); | |
817 } | |
818 pending_streams_.clear(); | |
819 | |
820 // We also need to drain the queue. | 796 // We also need to drain the queue. |
821 while (queue_.size()) | 797 while (queue_.size()) |
822 queue_.pop(); | 798 queue_.pop(); |
823 } | 799 } |
824 | 800 |
825 int SpdySession::GetNewStreamId() { | 801 int SpdySession::GetNewStreamId() { |
826 int id = stream_hi_water_mark_; | 802 int id = stream_hi_water_mark_; |
827 stream_hi_water_mark_ += 2; | 803 stream_hi_water_mark_ += 2; |
828 if (stream_hi_water_mark_ > 0x7fff) | 804 if (stream_hi_water_mark_ > 0x7fff) |
829 stream_hi_water_mark_ = 1; | 805 stream_hi_water_mark_ = 1; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
862 } | 838 } |
863 | 839 |
864 void SpdySession::ActivateStream(SpdyStream* stream) { | 840 void SpdySession::ActivateStream(SpdyStream* stream) { |
865 const spdy::SpdyStreamId id = stream->stream_id(); | 841 const spdy::SpdyStreamId id = stream->stream_id(); |
866 DCHECK(!IsStreamActive(id)); | 842 DCHECK(!IsStreamActive(id)); |
867 | 843 |
868 active_streams_[id] = stream; | 844 active_streams_[id] = stream; |
869 } | 845 } |
870 | 846 |
871 void SpdySession::DeleteStream(spdy::SpdyStreamId id, int status) { | 847 void SpdySession::DeleteStream(spdy::SpdyStreamId id, int status) { |
872 // Remove the stream from pushed_streams_ and active_streams_. | 848 // Remove the stream from unclaimed_pushed_streams_ and active_streams_. |
873 ActivePushedStreamList::iterator it; | 849 PushedStreamMap::iterator it; |
874 for (it = pushed_streams_.begin(); it != pushed_streams_.end(); ++it) { | 850 for (it = unclaimed_pushed_streams_.begin(); |
875 scoped_refptr<SpdyStream> curr = *it; | 851 it != unclaimed_pushed_streams_.end(); ++it) { |
| 852 scoped_refptr<SpdyStream> curr = it->second; |
876 if (id == curr->stream_id()) { | 853 if (id == curr->stream_id()) { |
877 pushed_streams_.erase(it); | 854 unclaimed_pushed_streams_.erase(it); |
878 break; | 855 break; |
879 } | 856 } |
880 } | 857 } |
881 | 858 |
882 // The stream might have been deleted. | 859 // The stream might have been deleted. |
883 ActiveStreamMap::iterator it2 = active_streams_.find(id); | 860 ActiveStreamMap::iterator it2 = active_streams_.find(id); |
884 if (it2 == active_streams_.end()) | 861 if (it2 == active_streams_.end()) |
885 return; | 862 return; |
886 | 863 |
887 // If this is an active stream, call the callback. | 864 // If this is an active stream, call the callback. |
(...skipping 10 matching lines...) Expand all Loading... |
898 in_session_pool_ = false; | 875 in_session_pool_ = false; |
899 } | 876 } |
900 } | 877 } |
901 | 878 |
902 scoped_refptr<SpdyStream> SpdySession::GetActivePushStream( | 879 scoped_refptr<SpdyStream> SpdySession::GetActivePushStream( |
903 const std::string& path) { | 880 const std::string& path) { |
904 static StatsCounter used_push_streams("spdy.claimed_push_streams"); | 881 static StatsCounter used_push_streams("spdy.claimed_push_streams"); |
905 | 882 |
906 LOG(INFO) << "Looking for push stream: " << path; | 883 LOG(INFO) << "Looking for push stream: " << path; |
907 | 884 |
908 scoped_refptr<SpdyStream> stream; | 885 PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(path); |
909 | 886 if (it != unclaimed_pushed_streams_.end()) { |
910 // We just walk a linear list here. | 887 LOG(INFO) << "Push stream: " << path << " found."; |
911 ActivePushedStreamList::iterator it; | 888 net_log_.AddEvent(NetLog::TYPE_SPDY_STREAM_ADOPTED_PUSH_STREAM, NULL); |
912 for (it = pushed_streams_.begin(); it != pushed_streams_.end(); ++it) { | 889 scoped_refptr<SpdyStream> stream = it->second; |
913 stream = *it; | 890 unclaimed_pushed_streams_.erase(it); |
914 if (path == stream->path()) { | 891 used_push_streams.Increment(); |
915 CHECK(stream->pushed()); | 892 return stream; |
916 pushed_streams_.erase(it); | |
917 used_push_streams.Increment(); | |
918 LOG(INFO) << "Push Stream Claim for: " << path; | |
919 return stream; | |
920 } | |
921 } | 893 } |
922 | 894 else { |
923 return NULL; | 895 LOG(INFO) << "Push stream: " << path << " not found."; |
| 896 return NULL; |
| 897 } |
924 } | 898 } |
925 | 899 |
926 bool SpdySession::GetSSLInfo(SSLInfo* ssl_info, bool* was_npn_negotiated) { | 900 bool SpdySession::GetSSLInfo(SSLInfo* ssl_info, bool* was_npn_negotiated) { |
927 if (is_secure_) { | 901 if (is_secure_) { |
928 SSLClientSocket* ssl_socket = | 902 SSLClientSocket* ssl_socket = |
929 reinterpret_cast<SSLClientSocket*>(connection_->socket()); | 903 reinterpret_cast<SSLClientSocket*>(connection_->socket()); |
930 ssl_socket->GetSSLInfo(ssl_info); | 904 ssl_socket->GetSSLInfo(ssl_info); |
931 *was_npn_negotiated = ssl_socket->wasNpnNegotiated(); | 905 *was_npn_negotiated = ssl_socket->wasNpnNegotiated(); |
932 return true; | 906 return true; |
933 } | 907 } |
(...skipping 30 matching lines...) Expand all Loading... |
964 const spdy::SpdyStreamId stream_id = stream->stream_id(); | 938 const spdy::SpdyStreamId stream_id = stream->stream_id(); |
965 DeleteStream(stream_id, rv); | 939 DeleteStream(stream_id, rv); |
966 return false; | 940 return false; |
967 } | 941 } |
968 return true; | 942 return true; |
969 } | 943 } |
970 | 944 |
971 void SpdySession::OnSyn(const spdy::SpdySynStreamControlFrame& frame, | 945 void SpdySession::OnSyn(const spdy::SpdySynStreamControlFrame& frame, |
972 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { | 946 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { |
973 spdy::SpdyStreamId stream_id = frame.stream_id(); | 947 spdy::SpdyStreamId stream_id = frame.stream_id(); |
974 | 948 spdy::SpdyStreamId associated_stream_id = frame.associated_stream_id(); |
975 LOG(INFO) << "Spdy SynStream for stream " << stream_id; | 949 LOG(INFO) << "Spdy SynStream for stream " << stream_id |
976 | 950 << " with associated stream " << associated_stream_id; |
977 // Server-initiated streams should have even sequence numbers. | 951 // Server-initiated streams should have even sequence numbers. |
978 if ((stream_id & 0x1) != 0) { | 952 if ((stream_id & 0x1) != 0) { |
979 LOG(ERROR) << "Received invalid OnSyn stream id " << stream_id; | 953 LOG(ERROR) << "Received invalid OnSyn stream id " << stream_id; |
980 return; | 954 return; |
981 } | 955 } |
982 | 956 |
983 if (IsStreamActive(stream_id)) { | 957 if (IsStreamActive(stream_id)) { |
984 LOG(ERROR) << "Received OnSyn for active stream " << stream_id; | 958 LOG(ERROR) << "Received OnSyn for active stream " << stream_id; |
985 return; | 959 return; |
986 } | 960 } |
987 | 961 |
| 962 if (associated_stream_id == 0) { |
| 963 LOG(ERROR) << "Received invalid OnSyn associated stream id " |
| 964 << associated_stream_id |
| 965 << " for stream " << stream_id; |
| 966 ResetStream(stream_id, spdy::INVALID_STREAM); |
| 967 return; |
| 968 } |
| 969 |
988 streams_pushed_count_++; | 970 streams_pushed_count_++; |
989 | 971 |
990 LOG(INFO) << "SpdySession: Syn received for stream: " << stream_id; | 972 LOG(INFO) << "SpdySession: Syn received for stream: " << stream_id; |
991 | 973 |
992 LOG(INFO) << "SPDY SYN RESPONSE HEADERS -----------------------"; | 974 LOG(INFO) << "SPDY SYN RESPONSE HEADERS -----------------------"; |
993 DumpSpdyHeaders(*headers); | 975 DumpSpdyHeaders(*headers); |
994 | 976 |
995 // TODO(mbelshe): DCHECK that this is a GET method? | 977 // TODO(mbelshe): DCHECK that this is a GET method? |
996 | 978 |
997 const std::string& path = ContainsKey(*headers, "path") ? | 979 const std::string& path = ContainsKey(*headers, "path") ? |
998 headers->find("path")->second : ""; | 980 headers->find("path")->second : ""; |
999 | 981 |
1000 // Verify that the response had a URL for us. | 982 // Verify that the response had a URL for us. |
1001 DCHECK(!path.empty()); | |
1002 if (path.empty()) { | 983 if (path.empty()) { |
| 984 ResetStream(stream_id, spdy::PROTOCOL_ERROR); |
1003 LOG(WARNING) << "Pushed stream did not contain a path."; | 985 LOG(WARNING) << "Pushed stream did not contain a path."; |
1004 return; | 986 return; |
1005 } | 987 } |
1006 | 988 |
1007 // Only HTTP push a stream. | 989 if (!IsStreamActive(associated_stream_id)) { |
| 990 LOG(ERROR) << "Received OnSyn with inactive associated stream " |
| 991 << associated_stream_id; |
| 992 ResetStream(stream_id, spdy::INVALID_ASSOCIATED_STREAM); |
| 993 return; |
| 994 } |
| 995 |
1008 scoped_refptr<SpdyStream> stream; | 996 scoped_refptr<SpdyStream> stream; |
1009 | 997 |
1010 // Check if we already have a delegate awaiting this stream. | 998 stream = new SpdyStream(this, stream_id, true); |
1011 PendingStreamMap::iterator it; | 999 |
1012 it = pending_streams_.find(path); | 1000 if (net_log_.HasListener()) { |
1013 if (it != pending_streams_.end()) { | 1001 net_log_.AddEvent( |
1014 stream = it->second; | 1002 NetLog::TYPE_SPDY_SESSION_PUSHED_SYN_STREAM, |
1015 pending_streams_.erase(it); | 1003 new NetLogSpdySynParameter( |
| 1004 headers, static_cast<spdy::SpdyControlFlags>(frame.flags()), |
| 1005 stream_id)); |
1016 } | 1006 } |
1017 | 1007 |
1018 if (stream) { | 1008 // TODO(erikchen): Actually do something with the associated id. |
1019 CHECK(stream->pushed()); | |
1020 CHECK_EQ(0u, stream->stream_id()); | |
1021 stream->set_stream_id(stream_id); | |
1022 const BoundNetLog& log = stream->net_log(); | |
1023 if (log.HasListener()) { | |
1024 log.AddEvent( | |
1025 NetLog::TYPE_SPDY_STREAM_PUSHED_SYN_STREAM, | |
1026 new NetLogSpdySynParameter( | |
1027 headers, static_cast<spdy::SpdyControlFlags>(frame.flags()), | |
1028 stream_id)); | |
1029 } | |
1030 } else { | |
1031 stream = new SpdyStream(this, stream_id, true); | |
1032 | 1009 |
1033 if (net_log_.HasListener()) { | 1010 stream->set_path(path); |
1034 net_log_.AddEvent( | 1011 |
1035 NetLog::TYPE_SPDY_SESSION_PUSHED_SYN_STREAM, | 1012 // There should not be an existing pushed stream with the same path. |
1036 new NetLogSpdySynParameter( | 1013 PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(path); |
1037 headers, static_cast<spdy::SpdyControlFlags>(frame.flags()), | 1014 if (it != unclaimed_pushed_streams_.end()) { |
1038 stream_id)); | 1015 LOG(ERROR) << "Received duplicate pushed stream with path: " << path; |
1039 } | 1016 ResetStream(stream_id, spdy::PROTOCOL_ERROR); |
1040 } | 1017 } |
1041 | 1018 unclaimed_pushed_streams_[path] = stream; |
1042 pushed_streams_.push_back(stream); | |
1043 | 1019 |
1044 // Activate a stream and parse the headers. | 1020 // Activate a stream and parse the headers. |
1045 ActivateStream(stream); | 1021 ActivateStream(stream); |
1046 | 1022 |
1047 stream->set_path(path); | 1023 // Parse the headers. |
1048 | |
1049 if (!Respond(*headers, stream)) | 1024 if (!Respond(*headers, stream)) |
1050 return; | 1025 return; |
1051 | 1026 |
1052 LOG(INFO) << "Got pushed stream for " << stream->path(); | 1027 LOG(INFO) << "Got pushed stream for " << stream->path(); |
1053 | 1028 |
1054 static StatsCounter push_requests("spdy.pushed_streams"); | 1029 static StatsCounter push_requests("spdy.pushed_streams"); |
1055 push_requests.Increment(); | 1030 push_requests.Increment(); |
1056 } | 1031 } |
1057 | 1032 |
1058 void SpdySession::OnSynReply(const spdy::SpdySynReplyControlFrame& frame, | 1033 void SpdySession::OnSynReply(const spdy::SpdySynReplyControlFrame& frame, |
(...skipping 15 matching lines...) Expand all Loading... |
1074 CHECK_EQ(stream->stream_id(), stream_id); | 1049 CHECK_EQ(stream->stream_id(), stream_id); |
1075 CHECK(!stream->cancelled()); | 1050 CHECK(!stream->cancelled()); |
1076 | 1051 |
1077 if (stream->syn_reply_received()) { | 1052 if (stream->syn_reply_received()) { |
1078 LOG(WARNING) << "Received duplicate SYN_REPLY for stream " << stream_id; | 1053 LOG(WARNING) << "Received duplicate SYN_REPLY for stream " << stream_id; |
1079 CloseStream(stream->stream_id(), ERR_SPDY_PROTOCOL_ERROR); | 1054 CloseStream(stream->stream_id(), ERR_SPDY_PROTOCOL_ERROR); |
1080 return; | 1055 return; |
1081 } | 1056 } |
1082 stream->set_syn_reply_received(); | 1057 stream->set_syn_reply_received(); |
1083 | 1058 |
1084 // We record content declared as being pushed so that we don't | |
1085 // request a duplicate stream which is already scheduled to be | |
1086 // sent to us. | |
1087 spdy::SpdyHeaderBlock::const_iterator it; | |
1088 it = headers->find("x-associated-content"); | |
1089 if (it != headers->end()) { | |
1090 const std::string& content = it->second; | |
1091 std::string::size_type start = 0; | |
1092 std::string::size_type end = 0; | |
1093 do { | |
1094 end = content.find("||", start); | |
1095 if (end == std::string::npos) | |
1096 end = content.length(); | |
1097 std::string url = content.substr(start, end - start); | |
1098 std::string::size_type pos = url.find("??"); | |
1099 if (pos == std::string::npos) | |
1100 break; | |
1101 url = url.substr(pos + 2); | |
1102 GURL gurl(url); | |
1103 std::string path = gurl.PathForRequest(); | |
1104 if (path.length()) | |
1105 pending_streams_[path] = NULL; | |
1106 else | |
1107 LOG(INFO) << "Invalid X-Associated-Content path: " << url; | |
1108 start = end + 2; | |
1109 } while (start < content.length()); | |
1110 } | |
1111 | |
1112 const BoundNetLog& log = stream->net_log(); | 1059 const BoundNetLog& log = stream->net_log(); |
1113 if (log.HasListener()) { | 1060 if (log.HasListener()) { |
1114 log.AddEvent( | 1061 log.AddEvent( |
1115 NetLog::TYPE_SPDY_STREAM_SYN_REPLY, | 1062 NetLog::TYPE_SPDY_STREAM_SYN_REPLY, |
1116 new NetLogSpdySynParameter( | 1063 new NetLogSpdySynParameter( |
1117 headers, static_cast<spdy::SpdyControlFlags>(frame.flags()), | 1064 headers, static_cast<spdy::SpdyControlFlags>(frame.flags()), |
1118 stream_id)); | 1065 stream_id)); |
1119 } | 1066 } |
1120 | 1067 |
1121 Respond(*headers, stream); | 1068 Respond(*headers, stream); |
(...skipping 22 matching lines...) Expand all Loading... |
1144 | 1091 |
1145 switch (type) { | 1092 switch (type) { |
1146 case spdy::GOAWAY: | 1093 case spdy::GOAWAY: |
1147 OnGoAway(*reinterpret_cast<const spdy::SpdyGoAwayControlFrame*>(frame)); | 1094 OnGoAway(*reinterpret_cast<const spdy::SpdyGoAwayControlFrame*>(frame)); |
1148 break; | 1095 break; |
1149 case spdy::SETTINGS: | 1096 case spdy::SETTINGS: |
1150 OnSettings( | 1097 OnSettings( |
1151 *reinterpret_cast<const spdy::SpdySettingsControlFrame*>(frame)); | 1098 *reinterpret_cast<const spdy::SpdySettingsControlFrame*>(frame)); |
1152 break; | 1099 break; |
1153 case spdy::RST_STREAM: | 1100 case spdy::RST_STREAM: |
1154 OnFin(*reinterpret_cast<const spdy::SpdyRstStreamControlFrame*>(frame)); | 1101 OnRst(*reinterpret_cast<const spdy::SpdyRstStreamControlFrame*>(frame)); |
1155 break; | 1102 break; |
1156 case spdy::SYN_STREAM: | 1103 case spdy::SYN_STREAM: |
1157 OnSyn(*reinterpret_cast<const spdy::SpdySynStreamControlFrame*>(frame), | 1104 OnSyn(*reinterpret_cast<const spdy::SpdySynStreamControlFrame*>(frame), |
1158 headers); | 1105 headers); |
1159 break; | 1106 break; |
1160 case spdy::SYN_REPLY: | 1107 case spdy::SYN_REPLY: |
1161 OnSynReply( | 1108 OnSynReply( |
1162 *reinterpret_cast<const spdy::SpdySynReplyControlFrame*>(frame), | 1109 *reinterpret_cast<const spdy::SpdySynReplyControlFrame*>(frame), |
1163 headers); | 1110 headers); |
1164 break; | 1111 break; |
1165 case spdy::WINDOW_UPDATE: | 1112 case spdy::WINDOW_UPDATE: |
1166 OnWindowUpdate( | 1113 OnWindowUpdate( |
1167 *reinterpret_cast<const spdy::SpdyWindowUpdateControlFrame*>(frame)); | 1114 *reinterpret_cast<const spdy::SpdyWindowUpdateControlFrame*>(frame)); |
1168 break; | 1115 break; |
1169 default: | 1116 default: |
1170 DCHECK(false); // Error! | 1117 DCHECK(false); // Error! |
1171 } | 1118 } |
1172 } | 1119 } |
1173 | 1120 |
1174 void SpdySession::OnFin(const spdy::SpdyRstStreamControlFrame& frame) { | 1121 void SpdySession::OnRst(const spdy::SpdyRstStreamControlFrame& frame) { |
1175 spdy::SpdyStreamId stream_id = frame.stream_id(); | 1122 spdy::SpdyStreamId stream_id = frame.stream_id(); |
1176 LOG(INFO) << "Spdy Fin for stream " << stream_id; | 1123 LOG(INFO) << "Spdy Fin for stream " << stream_id; |
1177 | 1124 |
1178 bool valid_stream = IsStreamActive(stream_id); | 1125 bool valid_stream = IsStreamActive(stream_id); |
1179 if (!valid_stream) { | 1126 if (!valid_stream) { |
1180 // NOTE: it may just be that the stream was cancelled. | 1127 // NOTE: it may just be that the stream was cancelled. |
1181 LOG(WARNING) << "Received FIN for invalid stream" << stream_id; | 1128 LOG(WARNING) << "Received FIN for invalid stream" << stream_id; |
1182 return; | 1129 return; |
1183 } | 1130 } |
1184 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 1131 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1334 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRetransRate", | 1281 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRetransRate", |
1335 setting.second, | 1282 setting.second, |
1336 1, 100, 50); | 1283 1, 100, 50); |
1337 break; | 1284 break; |
1338 } | 1285 } |
1339 } | 1286 } |
1340 } | 1287 } |
1341 } | 1288 } |
1342 | 1289 |
1343 } // namespace net | 1290 } // namespace net |
OLD | NEW |