| 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_session.h" | 5 #include "net/spdy/spdy_session.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1071 SpdyHeadersIR headers(stream_id); | 1071 SpdyHeadersIR headers(stream_id); |
| 1072 headers.set_priority(spdy_priority); | 1072 headers.set_priority(spdy_priority); |
| 1073 headers.set_has_priority(true); | 1073 headers.set_has_priority(true); |
| 1074 headers.set_fin((flags & CONTROL_FLAG_FIN) != 0); | 1074 headers.set_fin((flags & CONTROL_FLAG_FIN) != 0); |
| 1075 headers.set_name_value_block(block); | 1075 headers.set_name_value_block(block); |
| 1076 syn_frame.reset(buffered_spdy_framer_->SerializeFrame(headers)); | 1076 syn_frame.reset(buffered_spdy_framer_->SerializeFrame(headers)); |
| 1077 } | 1077 } |
| 1078 | 1078 |
| 1079 streams_initiated_count_++; | 1079 streams_initiated_count_++; |
| 1080 | 1080 |
| 1081 if (net_log().GetCaptureMode().enabled()) { | 1081 if (net_log().HasObservers()) { |
| 1082 const NetLog::EventType type = | 1082 const NetLog::EventType type = |
| 1083 (GetProtocolVersion() <= SPDY3) | 1083 (GetProtocolVersion() <= SPDY3) |
| 1084 ? NetLog::TYPE_HTTP2_SESSION_SYN_STREAM | 1084 ? NetLog::TYPE_HTTP2_SESSION_SYN_STREAM |
| 1085 : NetLog::TYPE_HTTP2_SESSION_SEND_HEADERS; | 1085 : NetLog::TYPE_HTTP2_SESSION_SEND_HEADERS; |
| 1086 net_log().AddEvent(type, | 1086 net_log().AddEvent(type, |
| 1087 base::Bind(&NetLogSpdySynStreamSentCallback, &block, | 1087 base::Bind(&NetLogSpdySynStreamSentCallback, &block, |
| 1088 (flags & CONTROL_FLAG_FIN) != 0, | 1088 (flags & CONTROL_FLAG_FIN) != 0, |
| 1089 (flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0, | 1089 (flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0, |
| 1090 spdy_priority, stream_id)); | 1090 spdy_priority, stream_id)); |
| 1091 } | 1091 } |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1181 effective_len = std::min(effective_len, session_send_window_size_); | 1181 effective_len = std::min(effective_len, session_send_window_size_); |
| 1182 } | 1182 } |
| 1183 | 1183 |
| 1184 DCHECK_GE(effective_len, 0); | 1184 DCHECK_GE(effective_len, 0); |
| 1185 | 1185 |
| 1186 // Clear FIN flag if only some of the data will be in the data | 1186 // Clear FIN flag if only some of the data will be in the data |
| 1187 // frame. | 1187 // frame. |
| 1188 if (effective_len < len) | 1188 if (effective_len < len) |
| 1189 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); | 1189 flags = static_cast<SpdyDataFlags>(flags & ~DATA_FLAG_FIN); |
| 1190 | 1190 |
| 1191 if (net_log().GetCaptureMode().enabled()) { | 1191 if (net_log().HasObservers()) { |
| 1192 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_SEND_DATA, | 1192 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_SEND_DATA, |
| 1193 base::Bind(&NetLogSpdyDataCallback, stream_id, | 1193 base::Bind(&NetLogSpdyDataCallback, stream_id, |
| 1194 effective_len, (flags & DATA_FLAG_FIN) != 0)); | 1194 effective_len, (flags & DATA_FLAG_FIN) != 0)); |
| 1195 } | 1195 } |
| 1196 | 1196 |
| 1197 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. | 1197 // Send PrefacePing for DATA_FRAMEs with nonzero payload size. |
| 1198 if (effective_len > 0) | 1198 if (effective_len > 0) |
| 1199 SendPrefacePingIfNoneInFlight(); | 1199 SendPrefacePingIfNoneInFlight(); |
| 1200 | 1200 |
| 1201 // TODO(mbelshe): reduce memory copies here. | 1201 // TODO(mbelshe): reduce memory copies here. |
| (...skipping 833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2035 size_t header_len = buffered_spdy_framer_->GetDataFrameMinimumSize(); | 2035 size_t header_len = buffered_spdy_framer_->GetDataFrameMinimumSize(); |
| 2036 stream->IncrementRawReceivedBytes(header_len); | 2036 stream->IncrementRawReceivedBytes(header_len); |
| 2037 } | 2037 } |
| 2038 | 2038 |
| 2039 void SpdySession::OnStreamFrameData(SpdyStreamId stream_id, | 2039 void SpdySession::OnStreamFrameData(SpdyStreamId stream_id, |
| 2040 const char* data, | 2040 const char* data, |
| 2041 size_t len, | 2041 size_t len, |
| 2042 bool fin) { | 2042 bool fin) { |
| 2043 CHECK(in_io_loop_); | 2043 CHECK(in_io_loop_); |
| 2044 DCHECK_LT(len, 1u << 24); | 2044 DCHECK_LT(len, 1u << 24); |
| 2045 if (net_log().GetCaptureMode().enabled()) { | 2045 if (net_log().HasObservers()) { |
| 2046 net_log().AddEvent( | 2046 net_log().AddEvent( |
| 2047 NetLog::TYPE_HTTP2_SESSION_RECV_DATA, | 2047 NetLog::TYPE_HTTP2_SESSION_RECV_DATA, |
| 2048 base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin)); | 2048 base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin)); |
| 2049 } | 2049 } |
| 2050 | 2050 |
| 2051 // Build the buffer as early as possible so that we go through the | 2051 // Build the buffer as early as possible so that we go through the |
| 2052 // session flow control checks and update | 2052 // session flow control checks and update |
| 2053 // |unacked_recv_window_bytes_| properly even when the stream is | 2053 // |unacked_recv_window_bytes_| properly even when the stream is |
| 2054 // inactive (since the other side has still reduced its session send | 2054 // inactive (since the other side has still reduced its session send |
| 2055 // window). | 2055 // window). |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2108 return; | 2108 return; |
| 2109 it->second.stream->OnPaddingConsumed(len); | 2109 it->second.stream->OnPaddingConsumed(len); |
| 2110 } | 2110 } |
| 2111 | 2111 |
| 2112 void SpdySession::OnSettings(bool clear_persisted) { | 2112 void SpdySession::OnSettings(bool clear_persisted) { |
| 2113 CHECK(in_io_loop_); | 2113 CHECK(in_io_loop_); |
| 2114 | 2114 |
| 2115 if (clear_persisted) | 2115 if (clear_persisted) |
| 2116 http_server_properties_->ClearSpdySettings(host_port_pair()); | 2116 http_server_properties_->ClearSpdySettings(host_port_pair()); |
| 2117 | 2117 |
| 2118 if (net_log_.GetCaptureMode().enabled()) { | 2118 if (net_log_.HasObservers()) { |
| 2119 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_SETTINGS, | 2119 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_SETTINGS, |
| 2120 base::Bind(&NetLogSpdySettingsCallback, host_port_pair(), | 2120 base::Bind(&NetLogSpdySettingsCallback, host_port_pair(), |
| 2121 clear_persisted)); | 2121 clear_persisted)); |
| 2122 } | 2122 } |
| 2123 | 2123 |
| 2124 if (GetProtocolVersion() >= SPDY4) { | 2124 if (GetProtocolVersion() >= SPDY4) { |
| 2125 // Send an acknowledgment of the setting. | 2125 // Send an acknowledgment of the setting. |
| 2126 SpdySettingsIR settings_ir; | 2126 SpdySettingsIR settings_ir; |
| 2127 settings_ir.set_is_ack(true); | 2127 settings_ir.set_is_ack(true); |
| 2128 EnqueueSessionWrite( | 2128 EnqueueSessionWrite( |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2221 bool fin, | 2221 bool fin, |
| 2222 bool unidirectional, | 2222 bool unidirectional, |
| 2223 const SpdyHeaderBlock& headers) { | 2223 const SpdyHeaderBlock& headers) { |
| 2224 CHECK(in_io_loop_); | 2224 CHECK(in_io_loop_); |
| 2225 | 2225 |
| 2226 DCHECK_LE(GetProtocolVersion(), SPDY3); | 2226 DCHECK_LE(GetProtocolVersion(), SPDY3); |
| 2227 | 2227 |
| 2228 base::Time response_time = base::Time::Now(); | 2228 base::Time response_time = base::Time::Now(); |
| 2229 base::TimeTicks recv_first_byte_time = time_func_(); | 2229 base::TimeTicks recv_first_byte_time = time_func_(); |
| 2230 | 2230 |
| 2231 if (net_log_.GetCaptureMode().enabled()) { | 2231 if (net_log_.HasObservers()) { |
| 2232 net_log_.AddEvent( | 2232 net_log_.AddEvent( |
| 2233 NetLog::TYPE_HTTP2_SESSION_PUSHED_SYN_STREAM, | 2233 NetLog::TYPE_HTTP2_SESSION_PUSHED_SYN_STREAM, |
| 2234 base::Bind(&NetLogSpdySynStreamReceivedCallback, &headers, fin, | 2234 base::Bind(&NetLogSpdySynStreamReceivedCallback, &headers, fin, |
| 2235 unidirectional, priority, stream_id, associated_stream_id)); | 2235 unidirectional, priority, stream_id, associated_stream_id)); |
| 2236 } | 2236 } |
| 2237 | 2237 |
| 2238 // Split headers to simulate push promise and response. | 2238 // Split headers to simulate push promise and response. |
| 2239 SpdyHeaderBlock request_headers; | 2239 SpdyHeaderBlock request_headers; |
| 2240 SpdyHeaderBlock response_headers; | 2240 SpdyHeaderBlock response_headers; |
| 2241 SplitPushedHeadersToRequestAndResponse( | 2241 SplitPushedHeadersToRequestAndResponse( |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2293 } | 2293 } |
| 2294 | 2294 |
| 2295 void SpdySession::OnSynReply(SpdyStreamId stream_id, | 2295 void SpdySession::OnSynReply(SpdyStreamId stream_id, |
| 2296 bool fin, | 2296 bool fin, |
| 2297 const SpdyHeaderBlock& headers) { | 2297 const SpdyHeaderBlock& headers) { |
| 2298 CHECK(in_io_loop_); | 2298 CHECK(in_io_loop_); |
| 2299 | 2299 |
| 2300 base::Time response_time = base::Time::Now(); | 2300 base::Time response_time = base::Time::Now(); |
| 2301 base::TimeTicks recv_first_byte_time = time_func_(); | 2301 base::TimeTicks recv_first_byte_time = time_func_(); |
| 2302 | 2302 |
| 2303 if (net_log().GetCaptureMode().enabled()) { | 2303 if (net_log().HasObservers()) { |
| 2304 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_SYN_REPLY, | 2304 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_SYN_REPLY, |
| 2305 base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback, | 2305 base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback, |
| 2306 &headers, fin, stream_id)); | 2306 &headers, fin, stream_id)); |
| 2307 } | 2307 } |
| 2308 | 2308 |
| 2309 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 2309 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
| 2310 if (it == active_streams_.end()) { | 2310 if (it == active_streams_.end()) { |
| 2311 // NOTE: it may just be that the stream was cancelled. | 2311 // NOTE: it may just be that the stream was cancelled. |
| 2312 return; | 2312 return; |
| 2313 } | 2313 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2338 headers, response_time, recv_first_byte_time, stream)); | 2338 headers, response_time, recv_first_byte_time, stream)); |
| 2339 } | 2339 } |
| 2340 | 2340 |
| 2341 void SpdySession::OnHeaders(SpdyStreamId stream_id, | 2341 void SpdySession::OnHeaders(SpdyStreamId stream_id, |
| 2342 bool has_priority, | 2342 bool has_priority, |
| 2343 SpdyPriority priority, | 2343 SpdyPriority priority, |
| 2344 bool fin, | 2344 bool fin, |
| 2345 const SpdyHeaderBlock& headers) { | 2345 const SpdyHeaderBlock& headers) { |
| 2346 CHECK(in_io_loop_); | 2346 CHECK(in_io_loop_); |
| 2347 | 2347 |
| 2348 if (net_log().GetCaptureMode().enabled()) { | 2348 if (net_log().HasObservers()) { |
| 2349 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_HEADERS, | 2349 net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_HEADERS, |
| 2350 base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback, | 2350 base::Bind(&NetLogSpdySynReplyOrHeadersReceivedCallback, |
| 2351 &headers, fin, stream_id)); | 2351 &headers, fin, stream_id)); |
| 2352 } | 2352 } |
| 2353 | 2353 |
| 2354 ActiveStreamMap::iterator it = active_streams_.find(stream_id); | 2354 ActiveStreamMap::iterator it = active_streams_.find(stream_id); |
| 2355 if (it == active_streams_.end()) { | 2355 if (it == active_streams_.end()) { |
| 2356 // NOTE: it may just be that the stream was cancelled. | 2356 // NOTE: it may just be that the stream was cancelled. |
| 2357 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; | 2357 LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; |
| 2358 return; | 2358 return; |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2721 DCHECK(active_it->second.stream->IsReservedRemote()); | 2721 DCHECK(active_it->second.stream->IsReservedRemote()); |
| 2722 num_pushed_streams_++; | 2722 num_pushed_streams_++; |
| 2723 return true; | 2723 return true; |
| 2724 } | 2724 } |
| 2725 | 2725 |
| 2726 void SpdySession::OnPushPromise(SpdyStreamId stream_id, | 2726 void SpdySession::OnPushPromise(SpdyStreamId stream_id, |
| 2727 SpdyStreamId promised_stream_id, | 2727 SpdyStreamId promised_stream_id, |
| 2728 const SpdyHeaderBlock& headers) { | 2728 const SpdyHeaderBlock& headers) { |
| 2729 CHECK(in_io_loop_); | 2729 CHECK(in_io_loop_); |
| 2730 | 2730 |
| 2731 if (net_log_.GetCaptureMode().enabled()) { | 2731 if (net_log_.HasObservers()) { |
| 2732 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_PUSH_PROMISE, | 2732 net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_PUSH_PROMISE, |
| 2733 base::Bind(&NetLogSpdyPushPromiseReceivedCallback, | 2733 base::Bind(&NetLogSpdyPushPromiseReceivedCallback, |
| 2734 &headers, stream_id, promised_stream_id)); | 2734 &headers, stream_id, promised_stream_id)); |
| 2735 } | 2735 } |
| 2736 | 2736 |
| 2737 // Any priority will do. | 2737 // Any priority will do. |
| 2738 // TODO(baranovich): pass parent stream id priority? | 2738 // TODO(baranovich): pass parent stream id priority? |
| 2739 if (!TryCreatePushStream(promised_stream_id, stream_id, 0, headers)) | 2739 if (!TryCreatePushStream(promised_stream_id, stream_id, 0, headers)) |
| 2740 return; | 2740 return; |
| 2741 } | 2741 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2915 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size)); | 2915 buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size)); |
| 2916 EnqueueSessionWrite(priority, WINDOW_UPDATE, window_update_frame.Pass()); | 2916 EnqueueSessionWrite(priority, WINDOW_UPDATE, window_update_frame.Pass()); |
| 2917 } | 2917 } |
| 2918 | 2918 |
| 2919 void SpdySession::WritePingFrame(SpdyPingId unique_id, bool is_ack) { | 2919 void SpdySession::WritePingFrame(SpdyPingId unique_id, bool is_ack) { |
| 2920 DCHECK(buffered_spdy_framer_.get()); | 2920 DCHECK(buffered_spdy_framer_.get()); |
| 2921 scoped_ptr<SpdyFrame> ping_frame( | 2921 scoped_ptr<SpdyFrame> ping_frame( |
| 2922 buffered_spdy_framer_->CreatePingFrame(unique_id, is_ack)); | 2922 buffered_spdy_framer_->CreatePingFrame(unique_id, is_ack)); |
| 2923 EnqueueSessionWrite(HIGHEST, PING, ping_frame.Pass()); | 2923 EnqueueSessionWrite(HIGHEST, PING, ping_frame.Pass()); |
| 2924 | 2924 |
| 2925 if (net_log().GetCaptureMode().enabled()) { | 2925 if (net_log().HasObservers()) { |
| 2926 net_log().AddEvent( | 2926 net_log().AddEvent( |
| 2927 NetLog::TYPE_HTTP2_SESSION_PING, | 2927 NetLog::TYPE_HTTP2_SESSION_PING, |
| 2928 base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "sent")); | 2928 base::Bind(&NetLogSpdyPingCallback, unique_id, is_ack, "sent")); |
| 2929 } | 2929 } |
| 2930 if (!is_ack) { | 2930 if (!is_ack) { |
| 2931 next_ping_id_ += 2; | 2931 next_ping_id_ += 2; |
| 2932 ++pings_in_flight_; | 2932 ++pings_in_flight_; |
| 2933 PlanToCheckPingStatus(); | 2933 PlanToCheckPingStatus(); |
| 2934 last_ping_sent_time_ = time_func_(); | 2934 last_ping_sent_time_ = time_func_(); |
| 2935 } | 2935 } |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3265 if (!queue->empty()) { | 3265 if (!queue->empty()) { |
| 3266 SpdyStreamId stream_id = queue->front(); | 3266 SpdyStreamId stream_id = queue->front(); |
| 3267 queue->pop_front(); | 3267 queue->pop_front(); |
| 3268 return stream_id; | 3268 return stream_id; |
| 3269 } | 3269 } |
| 3270 } | 3270 } |
| 3271 return 0; | 3271 return 0; |
| 3272 } | 3272 } |
| 3273 | 3273 |
| 3274 } // namespace net | 3274 } // namespace net |
| OLD | NEW |