| 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 <limits> | 8 #include <limits> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 | 100 |
| 101 std::unique_ptr<base::Value> NetLogSpdyHeadersSentCallback( | 101 std::unique_ptr<base::Value> NetLogSpdyHeadersSentCallback( |
| 102 const SpdyHeaderBlock* headers, | 102 const SpdyHeaderBlock* headers, |
| 103 bool fin, | 103 bool fin, |
| 104 SpdyStreamId stream_id, | 104 SpdyStreamId stream_id, |
| 105 bool has_priority, | 105 bool has_priority, |
| 106 int weight, | 106 int weight, |
| 107 SpdyStreamId parent_stream_id, | 107 SpdyStreamId parent_stream_id, |
| 108 bool exclusive, | 108 bool exclusive, |
| 109 NetLogCaptureMode capture_mode) { | 109 NetLogCaptureMode capture_mode) { |
| 110 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 110 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 111 dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode)); | 111 dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode)); |
| 112 dict->SetBoolean("fin", fin); | 112 dict->SetBoolean("fin", fin); |
| 113 dict->SetInteger("stream_id", stream_id); | 113 dict->SetInteger("stream_id", stream_id); |
| 114 dict->SetBoolean("has_priority", has_priority); | 114 dict->SetBoolean("has_priority", has_priority); |
| 115 if (has_priority) { | 115 if (has_priority) { |
| 116 dict->SetInteger("parent_stream_id", parent_stream_id); | 116 dict->SetInteger("parent_stream_id", parent_stream_id); |
| 117 dict->SetInteger("weight", weight); | 117 dict->SetInteger("weight", weight); |
| 118 dict->SetBoolean("exclusive", exclusive); | 118 dict->SetBoolean("exclusive", exclusive); |
| 119 } | 119 } |
| 120 return std::move(dict); | 120 return std::move(dict); |
| 121 } | 121 } |
| 122 | 122 |
| 123 std::unique_ptr<base::Value> NetLogSpdyHeadersReceivedCallback( | 123 std::unique_ptr<base::Value> NetLogSpdyHeadersReceivedCallback( |
| 124 const SpdyHeaderBlock* headers, | 124 const SpdyHeaderBlock* headers, |
| 125 bool fin, | 125 bool fin, |
| 126 SpdyStreamId stream_id, | 126 SpdyStreamId stream_id, |
| 127 NetLogCaptureMode capture_mode) { | 127 NetLogCaptureMode capture_mode) { |
| 128 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 128 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 129 dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode)); | 129 dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode)); |
| 130 dict->SetBoolean("fin", fin); | 130 dict->SetBoolean("fin", fin); |
| 131 dict->SetInteger("stream_id", stream_id); | 131 dict->SetInteger("stream_id", stream_id); |
| 132 return std::move(dict); | 132 return std::move(dict); |
| 133 } | 133 } |
| 134 | 134 |
| 135 std::unique_ptr<base::Value> NetLogSpdySessionCloseCallback( | 135 std::unique_ptr<base::Value> NetLogSpdySessionCloseCallback( |
| 136 int net_error, | 136 int net_error, |
| 137 const std::string* description, | 137 const std::string* description, |
| 138 NetLogCaptureMode /* capture_mode */) { | 138 NetLogCaptureMode /* capture_mode */) { |
| 139 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 139 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 140 dict->SetInteger("net_error", net_error); | 140 dict->SetInteger("net_error", net_error); |
| 141 dict->SetString("description", *description); | 141 dict->SetString("description", *description); |
| 142 return std::move(dict); | 142 return std::move(dict); |
| 143 } | 143 } |
| 144 | 144 |
| 145 std::unique_ptr<base::Value> NetLogSpdySessionCallback( | 145 std::unique_ptr<base::Value> NetLogSpdySessionCallback( |
| 146 const HostPortProxyPair* host_pair, | 146 const HostPortProxyPair* host_pair, |
| 147 NetLogCaptureMode /* capture_mode */) { | 147 NetLogCaptureMode /* capture_mode */) { |
| 148 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 148 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 149 dict->SetString("host", host_pair->first.ToString()); | 149 dict->SetString("host", host_pair->first.ToString()); |
| 150 dict->SetString("proxy", host_pair->second.ToPacString()); | 150 dict->SetString("proxy", host_pair->second.ToPacString()); |
| 151 return std::move(dict); | 151 return std::move(dict); |
| 152 } | 152 } |
| 153 | 153 |
| 154 std::unique_ptr<base::Value> NetLogSpdyInitializedCallback( | 154 std::unique_ptr<base::Value> NetLogSpdyInitializedCallback( |
| 155 NetLogSource source, | 155 NetLogSource source, |
| 156 NetLogCaptureMode /* capture_mode */) { | 156 NetLogCaptureMode /* capture_mode */) { |
| 157 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 157 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 158 if (source.IsValid()) { | 158 if (source.IsValid()) { |
| 159 source.AddToEventParameters(dict.get()); | 159 source.AddToEventParameters(dict.get()); |
| 160 } | 160 } |
| 161 dict->SetString("protocol", NextProtoToString(kProtoHTTP2)); | 161 dict->SetString("protocol", NextProtoToString(kProtoHTTP2)); |
| 162 return std::move(dict); | 162 return std::move(dict); |
| 163 } | 163 } |
| 164 | 164 |
| 165 std::unique_ptr<base::Value> NetLogSpdySettingsCallback( | 165 std::unique_ptr<base::Value> NetLogSpdySettingsCallback( |
| 166 const HostPortPair& host_port_pair, | 166 const HostPortPair& host_port_pair, |
| 167 NetLogCaptureMode /* capture_mode */) { | 167 NetLogCaptureMode /* capture_mode */) { |
| 168 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 168 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 169 dict->SetString("host", host_port_pair.ToString()); | 169 dict->SetString("host", host_port_pair.ToString()); |
| 170 return std::move(dict); | 170 return std::move(dict); |
| 171 } | 171 } |
| 172 | 172 |
| 173 std::unique_ptr<base::Value> NetLogSpdySettingCallback( | 173 std::unique_ptr<base::Value> NetLogSpdySettingCallback( |
| 174 SpdySettingsIds id, | 174 SpdySettingsIds id, |
| 175 uint32_t value, | 175 uint32_t value, |
| 176 NetLogCaptureMode /* capture_mode */) { | 176 NetLogCaptureMode /* capture_mode */) { |
| 177 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 177 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 178 dict->SetInteger("id", id); | 178 dict->SetInteger("id", id); |
| 179 dict->SetInteger("value", value); | 179 dict->SetInteger("value", value); |
| 180 return std::move(dict); | 180 return std::move(dict); |
| 181 } | 181 } |
| 182 | 182 |
| 183 std::unique_ptr<base::Value> NetLogSpdySendSettingsCallback( | 183 std::unique_ptr<base::Value> NetLogSpdySendSettingsCallback( |
| 184 const SettingsMap* settings, | 184 const SettingsMap* settings, |
| 185 NetLogCaptureMode /* capture_mode */) { | 185 NetLogCaptureMode /* capture_mode */) { |
| 186 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 186 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 187 std::unique_ptr<base::ListValue> settings_list(new base::ListValue()); | 187 auto settings_list = base::MakeUnique<base::ListValue>(); |
| 188 for (SettingsMap::const_iterator it = settings->begin(); | 188 for (SettingsMap::const_iterator it = settings->begin(); |
| 189 it != settings->end(); ++it) { | 189 it != settings->end(); ++it) { |
| 190 const SpdySettingsIds id = it->first; | 190 const SpdySettingsIds id = it->first; |
| 191 const uint32_t value = it->second; | 191 const uint32_t value = it->second; |
| 192 settings_list->AppendString( | 192 settings_list->AppendString( |
| 193 base::StringPrintf("[id:%u value:%u]", id, value)); | 193 base::StringPrintf("[id:%u value:%u]", id, value)); |
| 194 } | 194 } |
| 195 dict->Set("settings", std::move(settings_list)); | 195 dict->Set("settings", std::move(settings_list)); |
| 196 return std::move(dict); | 196 return std::move(dict); |
| 197 } | 197 } |
| 198 | 198 |
| 199 std::unique_ptr<base::Value> NetLogSpdyWindowUpdateFrameCallback( | 199 std::unique_ptr<base::Value> NetLogSpdyWindowUpdateFrameCallback( |
| 200 SpdyStreamId stream_id, | 200 SpdyStreamId stream_id, |
| 201 uint32_t delta, | 201 uint32_t delta, |
| 202 NetLogCaptureMode /* capture_mode */) { | 202 NetLogCaptureMode /* capture_mode */) { |
| 203 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 203 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 204 dict->SetInteger("stream_id", static_cast<int>(stream_id)); | 204 dict->SetInteger("stream_id", static_cast<int>(stream_id)); |
| 205 dict->SetInteger("delta", delta); | 205 dict->SetInteger("delta", delta); |
| 206 return std::move(dict); | 206 return std::move(dict); |
| 207 } | 207 } |
| 208 | 208 |
| 209 std::unique_ptr<base::Value> NetLogSpdySessionWindowUpdateCallback( | 209 std::unique_ptr<base::Value> NetLogSpdySessionWindowUpdateCallback( |
| 210 int32_t delta, | 210 int32_t delta, |
| 211 int32_t window_size, | 211 int32_t window_size, |
| 212 NetLogCaptureMode /* capture_mode */) { | 212 NetLogCaptureMode /* capture_mode */) { |
| 213 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 213 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 214 dict->SetInteger("delta", delta); | 214 dict->SetInteger("delta", delta); |
| 215 dict->SetInteger("window_size", window_size); | 215 dict->SetInteger("window_size", window_size); |
| 216 return std::move(dict); | 216 return std::move(dict); |
| 217 } | 217 } |
| 218 | 218 |
| 219 std::unique_ptr<base::Value> NetLogSpdyDataCallback( | 219 std::unique_ptr<base::Value> NetLogSpdyDataCallback( |
| 220 SpdyStreamId stream_id, | 220 SpdyStreamId stream_id, |
| 221 int size, | 221 int size, |
| 222 bool fin, | 222 bool fin, |
| 223 NetLogCaptureMode /* capture_mode */) { | 223 NetLogCaptureMode /* capture_mode */) { |
| 224 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 224 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 225 dict->SetInteger("stream_id", static_cast<int>(stream_id)); | 225 dict->SetInteger("stream_id", static_cast<int>(stream_id)); |
| 226 dict->SetInteger("size", size); | 226 dict->SetInteger("size", size); |
| 227 dict->SetBoolean("fin", fin); | 227 dict->SetBoolean("fin", fin); |
| 228 return std::move(dict); | 228 return std::move(dict); |
| 229 } | 229 } |
| 230 | 230 |
| 231 std::unique_ptr<base::Value> NetLogSpdyRstCallback( | 231 std::unique_ptr<base::Value> NetLogSpdyRstCallback( |
| 232 SpdyStreamId stream_id, | 232 SpdyStreamId stream_id, |
| 233 int status, | 233 int status, |
| 234 const std::string* description, | 234 const std::string* description, |
| 235 NetLogCaptureMode /* capture_mode */) { | 235 NetLogCaptureMode /* capture_mode */) { |
| 236 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 236 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 237 dict->SetInteger("stream_id", static_cast<int>(stream_id)); | 237 dict->SetInteger("stream_id", static_cast<int>(stream_id)); |
| 238 dict->SetInteger("status", status); | 238 dict->SetInteger("status", status); |
| 239 dict->SetString("description", *description); | 239 dict->SetString("description", *description); |
| 240 return std::move(dict); | 240 return std::move(dict); |
| 241 } | 241 } |
| 242 | 242 |
| 243 std::unique_ptr<base::Value> NetLogSpdyPingCallback( | 243 std::unique_ptr<base::Value> NetLogSpdyPingCallback( |
| 244 SpdyPingId unique_id, | 244 SpdyPingId unique_id, |
| 245 bool is_ack, | 245 bool is_ack, |
| 246 const char* type, | 246 const char* type, |
| 247 NetLogCaptureMode /* capture_mode */) { | 247 NetLogCaptureMode /* capture_mode */) { |
| 248 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 248 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 249 dict->SetInteger("unique_id", static_cast<int>(unique_id)); | 249 dict->SetInteger("unique_id", static_cast<int>(unique_id)); |
| 250 dict->SetString("type", type); | 250 dict->SetString("type", type); |
| 251 dict->SetBoolean("is_ack", is_ack); | 251 dict->SetBoolean("is_ack", is_ack); |
| 252 return std::move(dict); | 252 return std::move(dict); |
| 253 } | 253 } |
| 254 | 254 |
| 255 std::unique_ptr<base::Value> NetLogSpdyGoAwayCallback( | 255 std::unique_ptr<base::Value> NetLogSpdyGoAwayCallback( |
| 256 SpdyStreamId last_stream_id, | 256 SpdyStreamId last_stream_id, |
| 257 int active_streams, | 257 int active_streams, |
| 258 int unclaimed_streams, | 258 int unclaimed_streams, |
| 259 SpdyGoAwayStatus status, | 259 SpdyGoAwayStatus status, |
| 260 base::StringPiece debug_data, | 260 base::StringPiece debug_data, |
| 261 NetLogCaptureMode capture_mode) { | 261 NetLogCaptureMode capture_mode) { |
| 262 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 262 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 263 dict->SetInteger("last_accepted_stream_id", | 263 dict->SetInteger("last_accepted_stream_id", |
| 264 static_cast<int>(last_stream_id)); | 264 static_cast<int>(last_stream_id)); |
| 265 dict->SetInteger("active_streams", active_streams); | 265 dict->SetInteger("active_streams", active_streams); |
| 266 dict->SetInteger("unclaimed_streams", unclaimed_streams); | 266 dict->SetInteger("unclaimed_streams", unclaimed_streams); |
| 267 dict->SetInteger("status", static_cast<int>(status)); | 267 dict->SetInteger("status", static_cast<int>(status)); |
| 268 dict->SetString("debug_data", | 268 dict->SetString("debug_data", |
| 269 ElideGoAwayDebugDataForNetLog(capture_mode, debug_data)); | 269 ElideGoAwayDebugDataForNetLog(capture_mode, debug_data)); |
| 270 return std::move(dict); | 270 return std::move(dict); |
| 271 } | 271 } |
| 272 | 272 |
| 273 std::unique_ptr<base::Value> NetLogSpdyPushPromiseReceivedCallback( | 273 std::unique_ptr<base::Value> NetLogSpdyPushPromiseReceivedCallback( |
| 274 const SpdyHeaderBlock* headers, | 274 const SpdyHeaderBlock* headers, |
| 275 SpdyStreamId stream_id, | 275 SpdyStreamId stream_id, |
| 276 SpdyStreamId promised_stream_id, | 276 SpdyStreamId promised_stream_id, |
| 277 NetLogCaptureMode capture_mode) { | 277 NetLogCaptureMode capture_mode) { |
| 278 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 278 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 279 dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode)); | 279 dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode)); |
| 280 dict->SetInteger("id", stream_id); | 280 dict->SetInteger("id", stream_id); |
| 281 dict->SetInteger("promised_stream_id", promised_stream_id); | 281 dict->SetInteger("promised_stream_id", promised_stream_id); |
| 282 return std::move(dict); | 282 return std::move(dict); |
| 283 } | 283 } |
| 284 | 284 |
| 285 std::unique_ptr<base::Value> NetLogSpdyAdoptedPushStreamCallback( | 285 std::unique_ptr<base::Value> NetLogSpdyAdoptedPushStreamCallback( |
| 286 SpdyStreamId stream_id, | 286 SpdyStreamId stream_id, |
| 287 const GURL* url, | 287 const GURL* url, |
| 288 NetLogCaptureMode capture_mode) { | 288 NetLogCaptureMode capture_mode) { |
| 289 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 289 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 290 dict->SetInteger("stream_id", stream_id); | 290 dict->SetInteger("stream_id", stream_id); |
| 291 dict->SetString("url", url->spec()); | 291 dict->SetString("url", url->spec()); |
| 292 return std::move(dict); | 292 return std::move(dict); |
| 293 } | 293 } |
| 294 | 294 |
| 295 std::unique_ptr<base::Value> NetLogSpdySessionStalledCallback( | 295 std::unique_ptr<base::Value> NetLogSpdySessionStalledCallback( |
| 296 size_t num_active_streams, | 296 size_t num_active_streams, |
| 297 size_t num_created_streams, | 297 size_t num_created_streams, |
| 298 size_t num_pushed_streams, | 298 size_t num_pushed_streams, |
| 299 size_t max_concurrent_streams, | 299 size_t max_concurrent_streams, |
| 300 const std::string& url, | 300 const std::string& url, |
| 301 NetLogCaptureMode capture_mode) { | 301 NetLogCaptureMode capture_mode) { |
| 302 auto dict = base::MakeUnique<base::DictionaryValue>(); | 302 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 303 dict->SetInteger("num_active_streams", num_active_streams); | 303 dict->SetInteger("num_active_streams", num_active_streams); |
| 304 dict->SetInteger("num_created_streams", num_created_streams); | 304 dict->SetInteger("num_created_streams", num_created_streams); |
| 305 dict->SetInteger("num_pushed_streams", num_pushed_streams); | 305 dict->SetInteger("num_pushed_streams", num_pushed_streams); |
| 306 dict->SetInteger("max_concurrent_streams", max_concurrent_streams); | 306 dict->SetInteger("max_concurrent_streams", max_concurrent_streams); |
| 307 dict->SetString("url", url); | 307 dict->SetString("url", url); |
| 308 return std::move(dict); | 308 return std::move(dict); |
| 309 } | 309 } |
| 310 | 310 |
| 311 std::unique_ptr<base::Value> NetLogSpdyPriorityCallback( |
| 312 SpdyStreamId stream_id, |
| 313 SpdyStreamId parent_stream_id, |
| 314 int weight, |
| 315 bool exclusive, |
| 316 NetLogCaptureMode capture_mode) { |
| 317 auto dict = base::MakeUnique<base::DictionaryValue>(); |
| 318 dict->SetInteger("stream_id", stream_id); |
| 319 dict->SetInteger("parent_stream_id", parent_stream_id); |
| 320 dict->SetInteger("weight", weight); |
| 321 dict->SetBoolean("exclusive", exclusive); |
| 322 return std::move(dict); |
| 323 } |
| 324 |
| 311 // Helper function to return the total size of an array of objects | 325 // Helper function to return the total size of an array of objects |
| 312 // with .size() member functions. | 326 // with .size() member functions. |
| 313 template <typename T, size_t N> size_t GetTotalSize(const T (&arr)[N]) { | 327 template <typename T, size_t N> size_t GetTotalSize(const T (&arr)[N]) { |
| 314 size_t total_size = 0; | 328 size_t total_size = 0; |
| 315 for (size_t i = 0; i < N; ++i) { | 329 for (size_t i = 0; i < N; ++i) { |
| 316 total_size += arr[i].size(); | 330 total_size += arr[i].size(); |
| 317 } | 331 } |
| 318 return total_size; | 332 return total_size; |
| 319 } | 333 } |
| 320 | 334 |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 | 832 |
| 819 SSLInfo ssl_info; | 833 SSLInfo ssl_info; |
| 820 if (!GetSSLInfo(&ssl_info)) | 834 if (!GetSSLInfo(&ssl_info)) |
| 821 return true; // This is not a secure session, so all domains are okay. | 835 return true; // This is not a secure session, so all domains are okay. |
| 822 | 836 |
| 823 return CanPool(transport_security_state_, ssl_info, | 837 return CanPool(transport_security_state_, ssl_info, |
| 824 host_port_pair().host(), domain); | 838 host_port_pair().host(), domain); |
| 825 } | 839 } |
| 826 | 840 |
| 827 int SpdySession::GetPushStream(const GURL& url, | 841 int SpdySession::GetPushStream(const GURL& url, |
| 842 RequestPriority priority, |
| 828 base::WeakPtr<SpdyStream>* stream, | 843 base::WeakPtr<SpdyStream>* stream, |
| 829 const NetLogWithSource& stream_net_log) { | 844 const NetLogWithSource& stream_net_log) { |
| 830 CHECK(!in_io_loop_); | 845 CHECK(!in_io_loop_); |
| 831 | 846 |
| 832 stream->reset(); | 847 stream->reset(); |
| 833 | 848 |
| 834 if (availability_state_ == STATE_DRAINING) | 849 if (availability_state_ == STATE_DRAINING) |
| 835 return ERR_CONNECTION_CLOSED; | 850 return ERR_CONNECTION_CLOSED; |
| 836 | 851 |
| 837 *stream = GetActivePushStream(url); | 852 *stream = GetActivePushStream(url); |
| 838 if (*stream) { | 853 if (*stream) { |
| 839 DCHECK_LT(streams_pushed_and_claimed_count_, streams_pushed_count_); | 854 DCHECK_LT(streams_pushed_and_claimed_count_, streams_pushed_count_); |
| 840 streams_pushed_and_claimed_count_++; | 855 streams_pushed_and_claimed_count_++; |
| 856 |
| 857 // If the stream is still open, update its priority to match |
| 858 // the priority of the matching request. |
| 859 if (!(*stream)->IsClosed() && (*stream)->priority() != priority) { |
| 860 (*stream)->set_priority(priority); |
| 861 |
| 862 // Send PRIORITY updates. |
| 863 auto updates = priority_dependency_state_.OnStreamUpdate( |
| 864 (*stream)->stream_id(), |
| 865 ConvertRequestPriorityToSpdyPriority(priority)); |
| 866 for (auto u : updates) { |
| 867 ActiveStreamMap::iterator it = active_streams_.find(u.id); |
| 868 DCHECK(it != active_streams_.end()); |
| 869 int weight = Spdy3PriorityToHttp2Weight( |
| 870 ConvertRequestPriorityToSpdyPriority(it->second->priority())); |
| 871 EnqueuePriorityFrame(u.id, u.dependent_stream_id, weight, u.exclusive); |
| 872 } |
| 873 } |
| 841 } | 874 } |
| 875 |
| 842 return OK; | 876 return OK; |
| 843 } | 877 } |
| 844 | 878 |
| 845 void SpdySession::CancelPush(const GURL& url) { | 879 void SpdySession::CancelPush(const GURL& url) { |
| 846 UnclaimedPushedStreamContainer::const_iterator unclaimed_it = | 880 UnclaimedPushedStreamContainer::const_iterator unclaimed_it = |
| 847 unclaimed_pushed_streams_.find(url); | 881 unclaimed_pushed_streams_.find(url); |
| 848 if (unclaimed_it == unclaimed_pushed_streams_.end()) | 882 if (unclaimed_it == unclaimed_pushed_streams_.end()) |
| 849 return; | 883 return; |
| 850 | 884 |
| 851 SpdyStreamId stream_id = unclaimed_it->second.stream_id; | 885 SpdyStreamId stream_id = unclaimed_it->second.stream_id; |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1063 | 1097 |
| 1064 DCHECK(buffered_spdy_framer_.get()); | 1098 DCHECK(buffered_spdy_framer_.get()); |
| 1065 SpdyPriority spdy_priority = ConvertRequestPriorityToSpdyPriority(priority); | 1099 SpdyPriority spdy_priority = ConvertRequestPriorityToSpdyPriority(priority); |
| 1066 | 1100 |
| 1067 std::unique_ptr<SpdySerializedFrame> syn_frame; | 1101 std::unique_ptr<SpdySerializedFrame> syn_frame; |
| 1068 bool has_priority = true; | 1102 bool has_priority = true; |
| 1069 int weight = Spdy3PriorityToHttp2Weight(spdy_priority); | 1103 int weight = Spdy3PriorityToHttp2Weight(spdy_priority); |
| 1070 SpdyStreamId dependent_stream_id = 0; | 1104 SpdyStreamId dependent_stream_id = 0; |
| 1071 bool exclusive = false; | 1105 bool exclusive = false; |
| 1072 | 1106 |
| 1073 priority_dependency_state_.OnStreamSynSent(stream_id, spdy_priority, | 1107 priority_dependency_state_.OnStreamCreation(stream_id, spdy_priority, |
| 1074 &dependent_stream_id, &exclusive); | 1108 &dependent_stream_id, &exclusive); |
| 1075 | 1109 |
| 1076 if (net_log().IsCapturing()) { | 1110 if (net_log().IsCapturing()) { |
| 1077 net_log().AddEvent( | 1111 net_log().AddEvent( |
| 1078 NetLogEventType::HTTP2_SESSION_SEND_HEADERS, | 1112 NetLogEventType::HTTP2_SESSION_SEND_HEADERS, |
| 1079 base::Bind(&NetLogSpdyHeadersSentCallback, &block, | 1113 base::Bind(&NetLogSpdyHeadersSentCallback, &block, |
| 1080 (flags & CONTROL_FLAG_FIN) != 0, stream_id, has_priority, | 1114 (flags & CONTROL_FLAG_FIN) != 0, stream_id, has_priority, |
| 1081 weight, dependent_stream_id, exclusive)); | 1115 weight, dependent_stream_id, exclusive)); |
| 1082 } | 1116 } |
| 1083 | 1117 |
| 1084 SpdyHeadersIR headers(stream_id, std::move(block)); | 1118 SpdyHeadersIR headers(stream_id, std::move(block)); |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1322 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description)); | 1356 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description)); |
| 1323 | 1357 |
| 1324 DCHECK(buffered_spdy_framer_.get()); | 1358 DCHECK(buffered_spdy_framer_.get()); |
| 1325 std::unique_ptr<SpdySerializedFrame> rst_frame( | 1359 std::unique_ptr<SpdySerializedFrame> rst_frame( |
| 1326 buffered_spdy_framer_->CreateRstStream(stream_id, status)); | 1360 buffered_spdy_framer_->CreateRstStream(stream_id, status)); |
| 1327 | 1361 |
| 1328 EnqueueSessionWrite(priority, RST_STREAM, std::move(rst_frame)); | 1362 EnqueueSessionWrite(priority, RST_STREAM, std::move(rst_frame)); |
| 1329 RecordProtocolErrorHistogram(MapRstStreamStatusToProtocolError(status)); | 1363 RecordProtocolErrorHistogram(MapRstStreamStatusToProtocolError(status)); |
| 1330 } | 1364 } |
| 1331 | 1365 |
| 1366 void SpdySession::EnqueuePriorityFrame(SpdyStreamId stream_id, |
| 1367 SpdyStreamId dependency_id, |
| 1368 int weight, |
| 1369 bool exclusive) { |
| 1370 net_log().AddEvent(NetLogEventType::HTTP2_STREAM_SEND_PRIORITY, |
| 1371 base::Bind(&NetLogSpdyPriorityCallback, stream_id, |
| 1372 dependency_id, weight, exclusive)); |
| 1373 |
| 1374 DCHECK(buffered_spdy_framer_.get()); |
| 1375 std::unique_ptr<SpdySerializedFrame> frame( |
| 1376 buffered_spdy_framer_->CreatePriority(stream_id, dependency_id, weight, |
| 1377 exclusive)); |
| 1378 |
| 1379 // PRIORITY frames describe sequenced updates to the tree, so they must |
| 1380 // be serialized. We do this by queueing all PRIORITY frames at HIGHEST |
| 1381 // priority. |
| 1382 EnqueueWrite(HIGHEST, PRIORITY, |
| 1383 base::MakeUnique<SimpleBufferProducer>( |
| 1384 base::MakeUnique<SpdyBuffer>(std::move(frame))), |
| 1385 base::WeakPtr<SpdyStream>()); |
| 1386 } |
| 1387 |
| 1332 void SpdySession::PumpReadLoop(ReadState expected_read_state, int result) { | 1388 void SpdySession::PumpReadLoop(ReadState expected_read_state, int result) { |
| 1333 CHECK(!in_io_loop_); | 1389 CHECK(!in_io_loop_); |
| 1334 if (availability_state_ == STATE_DRAINING) { | 1390 if (availability_state_ == STATE_DRAINING) { |
| 1335 return; | 1391 return; |
| 1336 } | 1392 } |
| 1337 ignore_result(DoReadLoop(expected_read_state, result)); | 1393 ignore_result(DoReadLoop(expected_read_state, result)); |
| 1338 } | 1394 } |
| 1339 | 1395 |
| 1340 int SpdySession::DoReadLoop(ReadState expected_read_state, int result) { | 1396 int SpdySession::DoReadLoop(ReadState expected_read_state, int result) { |
| 1341 CHECK(!in_io_loop_); | 1397 CHECK(!in_io_loop_); |
| (...skipping 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2459 return; | 2515 return; |
| 2460 } | 2516 } |
| 2461 | 2517 |
| 2462 CHECK_EQ(it->second->stream_id(), stream_id); | 2518 CHECK_EQ(it->second->stream_id(), stream_id); |
| 2463 it->second->IncreaseSendWindowSize(delta_window_size); | 2519 it->second->IncreaseSendWindowSize(delta_window_size); |
| 2464 } | 2520 } |
| 2465 } | 2521 } |
| 2466 | 2522 |
| 2467 void SpdySession::TryCreatePushStream(SpdyStreamId stream_id, | 2523 void SpdySession::TryCreatePushStream(SpdyStreamId stream_id, |
| 2468 SpdyStreamId associated_stream_id, | 2524 SpdyStreamId associated_stream_id, |
| 2469 SpdyPriority priority, | |
| 2470 SpdyHeaderBlock headers) { | 2525 SpdyHeaderBlock headers) { |
| 2471 // Server-initiated streams should have even sequence numbers. | 2526 // Server-initiated streams should have even sequence numbers. |
| 2472 if ((stream_id & 0x1) != 0) { | 2527 if ((stream_id & 0x1) != 0) { |
| 2473 LOG(WARNING) << "Received invalid push stream id " << stream_id; | 2528 LOG(WARNING) << "Received invalid push stream id " << stream_id; |
| 2474 CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, "Odd push stream id."); | 2529 CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, "Odd push stream id."); |
| 2475 return; | 2530 return; |
| 2476 } | 2531 } |
| 2477 | 2532 |
| 2478 // Server-initiated streams must be associated with client-initiated streams. | 2533 // Server-initiated streams must be associated with client-initiated streams. |
| 2479 if ((associated_stream_id & 0x1) != 1) { | 2534 if ((associated_stream_id & 0x1) != 1) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2494 | 2549 |
| 2495 if (IsStreamActive(stream_id)) { | 2550 if (IsStreamActive(stream_id)) { |
| 2496 // We should not get here, we'll start going away earlier on | 2551 // We should not get here, we'll start going away earlier on |
| 2497 // |last_seen_push_stream_id_| check. | 2552 // |last_seen_push_stream_id_| check. |
| 2498 LOG(WARNING) << "Received push for active stream " << stream_id; | 2553 LOG(WARNING) << "Received push for active stream " << stream_id; |
| 2499 return; | 2554 return; |
| 2500 } | 2555 } |
| 2501 | 2556 |
| 2502 last_accepted_push_stream_id_ = stream_id; | 2557 last_accepted_push_stream_id_ = stream_id; |
| 2503 | 2558 |
| 2504 RequestPriority request_priority = | 2559 // Pushed streams are speculative, so they start at an IDLE priority. |
| 2505 ConvertSpdyPriorityToRequestPriority(priority); | 2560 const RequestPriority request_priority = IDLE; |
| 2506 | 2561 |
| 2507 if (availability_state_ == STATE_GOING_AWAY) { | 2562 if (availability_state_ == STATE_GOING_AWAY) { |
| 2508 // TODO(akalin): This behavior isn't in the SPDY spec, although it | 2563 // TODO(akalin): This behavior isn't in the SPDY spec, although it |
| 2509 // probably should be. | 2564 // probably should be. |
| 2510 EnqueueResetStreamFrame(stream_id, | 2565 EnqueueResetStreamFrame(stream_id, |
| 2511 request_priority, | 2566 request_priority, |
| 2512 RST_STREAM_REFUSED_STREAM, | 2567 RST_STREAM_REFUSED_STREAM, |
| 2513 "push stream request received when going away"); | 2568 "push stream request received when going away"); |
| 2514 return; | 2569 return; |
| 2515 } | 2570 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2612 "Received duplicate pushed stream with url: " + gurl.spec()); | 2667 "Received duplicate pushed stream with url: " + gurl.spec()); |
| 2613 return; | 2668 return; |
| 2614 } | 2669 } |
| 2615 | 2670 |
| 2616 std::unique_ptr<SpdyStream> stream( | 2671 std::unique_ptr<SpdyStream> stream( |
| 2617 new SpdyStream(SPDY_PUSH_STREAM, GetWeakPtr(), gurl, request_priority, | 2672 new SpdyStream(SPDY_PUSH_STREAM, GetWeakPtr(), gurl, request_priority, |
| 2618 stream_initial_send_window_size_, | 2673 stream_initial_send_window_size_, |
| 2619 stream_max_recv_window_size_, net_log_)); | 2674 stream_max_recv_window_size_, net_log_)); |
| 2620 stream->set_stream_id(stream_id); | 2675 stream->set_stream_id(stream_id); |
| 2621 | 2676 |
| 2677 // Convert RequestPriority to a SpdyPriority to send in a PRIORITY frame. |
| 2678 SpdyPriority spdy_priority = |
| 2679 ConvertRequestPriorityToSpdyPriority(request_priority); |
| 2680 SpdyStreamId dependency_id = 0; |
| 2681 bool exclusive = false; |
| 2682 priority_dependency_state_.OnStreamCreation(stream_id, spdy_priority, |
| 2683 &dependency_id, &exclusive); |
| 2684 EnqueuePriorityFrame(stream_id, dependency_id, |
| 2685 Spdy3PriorityToHttp2Weight(spdy_priority), exclusive); |
| 2686 |
| 2622 // PUSH_PROMISE arrives on associated stream. | 2687 // PUSH_PROMISE arrives on associated stream. |
| 2623 associated_it->second->AddRawReceivedBytes(last_compressed_frame_len_); | 2688 associated_it->second->AddRawReceivedBytes(last_compressed_frame_len_); |
| 2624 last_compressed_frame_len_ = 0; | 2689 last_compressed_frame_len_ = 0; |
| 2625 | 2690 |
| 2626 UnclaimedPushedStreamContainer::const_iterator inserted_pushed_it = | 2691 UnclaimedPushedStreamContainer::const_iterator inserted_pushed_it = |
| 2627 unclaimed_pushed_streams_.insert(pushed_it, gurl, stream_id, | 2692 unclaimed_pushed_streams_.insert(pushed_it, gurl, stream_id, |
| 2628 time_func_()); | 2693 time_func_()); |
| 2629 DCHECK(inserted_pushed_it != pushed_it); | 2694 DCHECK(inserted_pushed_it != pushed_it); |
| 2630 DeleteExpiredPushedStreams(); | 2695 DeleteExpiredPushedStreams(); |
| 2631 | 2696 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2653 SpdyStreamId promised_stream_id, | 2718 SpdyStreamId promised_stream_id, |
| 2654 SpdyHeaderBlock headers) { | 2719 SpdyHeaderBlock headers) { |
| 2655 CHECK(in_io_loop_); | 2720 CHECK(in_io_loop_); |
| 2656 | 2721 |
| 2657 if (net_log_.IsCapturing()) { | 2722 if (net_log_.IsCapturing()) { |
| 2658 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_PUSH_PROMISE, | 2723 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_RECV_PUSH_PROMISE, |
| 2659 base::Bind(&NetLogSpdyPushPromiseReceivedCallback, | 2724 base::Bind(&NetLogSpdyPushPromiseReceivedCallback, |
| 2660 &headers, stream_id, promised_stream_id)); | 2725 &headers, stream_id, promised_stream_id)); |
| 2661 } | 2726 } |
| 2662 | 2727 |
| 2663 // Any priority will do. TODO(baranovich): Pass parent stream id priority? | 2728 TryCreatePushStream(promised_stream_id, stream_id, std::move(headers)); |
| 2664 TryCreatePushStream(promised_stream_id, stream_id, 0, std::move(headers)); | |
| 2665 } | 2729 } |
| 2666 | 2730 |
| 2667 void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id, | 2731 void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id, |
| 2668 uint32_t delta_window_size) { | 2732 uint32_t delta_window_size) { |
| 2669 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 2733 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
| 2670 CHECK(it != active_streams_.end()); | 2734 CHECK(it != active_streams_.end()); |
| 2671 CHECK_EQ(it->second->stream_id(), stream_id); | 2735 CHECK_EQ(it->second->stream_id(), stream_id); |
| 2672 SendWindowUpdateFrame(stream_id, delta_window_size, it->second->priority()); | 2736 SendWindowUpdateFrame(stream_id, delta_window_size, it->second->priority()); |
| 2673 } | 2737 } |
| 2674 | 2738 |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3067 if (!queue->empty()) { | 3131 if (!queue->empty()) { |
| 3068 SpdyStreamId stream_id = queue->front(); | 3132 SpdyStreamId stream_id = queue->front(); |
| 3069 queue->pop_front(); | 3133 queue->pop_front(); |
| 3070 return stream_id; | 3134 return stream_id; |
| 3071 } | 3135 } |
| 3072 } | 3136 } |
| 3073 return 0; | 3137 return 0; |
| 3074 } | 3138 } |
| 3075 | 3139 |
| 3076 } // namespace net | 3140 } // namespace net |
| OLD | NEW |