Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: net/spdy/spdy_session.cc

Issue 2675593002: Spdy{RstStream,GoAway}Status -> SpdyErrorCode. (Closed)
Patch Set: Merged master, which includes 145087791. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_session_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 NetLogCaptureMode /* capture_mode */) { 221 NetLogCaptureMode /* capture_mode */) {
222 auto dict = base::MakeUnique<base::DictionaryValue>(); 222 auto dict = base::MakeUnique<base::DictionaryValue>();
223 dict->SetInteger("stream_id", static_cast<int>(stream_id)); 223 dict->SetInteger("stream_id", static_cast<int>(stream_id));
224 dict->SetInteger("size", size); 224 dict->SetInteger("size", size);
225 dict->SetBoolean("fin", fin); 225 dict->SetBoolean("fin", fin);
226 return std::move(dict); 226 return std::move(dict);
227 } 227 }
228 228
229 std::unique_ptr<base::Value> NetLogSpdyRstCallback( 229 std::unique_ptr<base::Value> NetLogSpdyRstCallback(
230 SpdyStreamId stream_id, 230 SpdyStreamId stream_id,
231 int status, 231 int error_code,
232 const std::string* description, 232 const std::string* description,
233 NetLogCaptureMode /* capture_mode */) { 233 NetLogCaptureMode /* capture_mode */) {
234 auto dict = base::MakeUnique<base::DictionaryValue>(); 234 auto dict = base::MakeUnique<base::DictionaryValue>();
235 dict->SetInteger("stream_id", static_cast<int>(stream_id)); 235 dict->SetInteger("stream_id", static_cast<int>(stream_id));
236 dict->SetInteger("status", status); 236 dict->SetInteger("error_code", error_code);
237 dict->SetString("description", *description); 237 dict->SetString("description", *description);
238 return std::move(dict); 238 return std::move(dict);
239 } 239 }
240 240
241 std::unique_ptr<base::Value> NetLogSpdyPingCallback( 241 std::unique_ptr<base::Value> NetLogSpdyPingCallback(
242 SpdyPingId unique_id, 242 SpdyPingId unique_id,
243 bool is_ack, 243 bool is_ack,
244 const char* type, 244 const char* type,
245 NetLogCaptureMode /* capture_mode */) { 245 NetLogCaptureMode /* capture_mode */) {
246 auto dict = base::MakeUnique<base::DictionaryValue>(); 246 auto dict = base::MakeUnique<base::DictionaryValue>();
247 dict->SetInteger("unique_id", static_cast<int>(unique_id)); 247 dict->SetInteger("unique_id", static_cast<int>(unique_id));
248 dict->SetString("type", type); 248 dict->SetString("type", type);
249 dict->SetBoolean("is_ack", is_ack); 249 dict->SetBoolean("is_ack", is_ack);
250 return std::move(dict); 250 return std::move(dict);
251 } 251 }
252 252
253 std::unique_ptr<base::Value> NetLogSpdyGoAwayCallback( 253 std::unique_ptr<base::Value> NetLogSpdyGoAwayCallback(
254 SpdyStreamId last_stream_id, 254 SpdyStreamId last_stream_id,
255 int active_streams, 255 int active_streams,
256 int unclaimed_streams, 256 int unclaimed_streams,
257 SpdyGoAwayStatus status, 257 SpdyErrorCode error_code,
258 base::StringPiece debug_data, 258 base::StringPiece debug_data,
259 NetLogCaptureMode capture_mode) { 259 NetLogCaptureMode capture_mode) {
260 auto dict = base::MakeUnique<base::DictionaryValue>(); 260 auto dict = base::MakeUnique<base::DictionaryValue>();
261 dict->SetInteger("last_accepted_stream_id", 261 dict->SetInteger("last_accepted_stream_id",
262 static_cast<int>(last_stream_id)); 262 static_cast<int>(last_stream_id));
263 dict->SetInteger("active_streams", active_streams); 263 dict->SetInteger("active_streams", active_streams);
264 dict->SetInteger("unclaimed_streams", unclaimed_streams); 264 dict->SetInteger("unclaimed_streams", unclaimed_streams);
265 dict->SetInteger("status", static_cast<int>(status)); 265 dict->SetInteger("error_code", static_cast<int>(error_code));
266 dict->SetString("debug_data", 266 dict->SetString("debug_data",
267 ElideGoAwayDebugDataForNetLog(capture_mode, debug_data)); 267 ElideGoAwayDebugDataForNetLog(capture_mode, debug_data));
268 return std::move(dict); 268 return std::move(dict);
269 } 269 }
270 270
271 std::unique_ptr<base::Value> NetLogSpdyPushPromiseReceivedCallback( 271 std::unique_ptr<base::Value> NetLogSpdyPushPromiseReceivedCallback(
272 const SpdyHeaderBlock* headers, 272 const SpdyHeaderBlock* headers,
273 SpdyStreamId stream_id, 273 SpdyStreamId stream_id,
274 SpdyStreamId promised_stream_id, 274 SpdyStreamId promised_stream_id,
275 NetLogCaptureMode capture_mode) { 275 NetLogCaptureMode capture_mode) {
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 return ERR_SPDY_FRAME_SIZE_ERROR; 446 return ERR_SPDY_FRAME_SIZE_ERROR;
447 case SpdyFramer::SPDY_INVALID_STREAM_ID: 447 case SpdyFramer::SPDY_INVALID_STREAM_ID:
448 return ERR_SPDY_PROTOCOL_ERROR; 448 return ERR_SPDY_PROTOCOL_ERROR;
449 default: 449 default:
450 NOTREACHED(); 450 NOTREACHED();
451 return ERR_SPDY_PROTOCOL_ERROR; 451 return ERR_SPDY_PROTOCOL_ERROR;
452 } 452 }
453 } 453 }
454 454
455 SpdyProtocolErrorDetails MapRstStreamStatusToProtocolError( 455 SpdyProtocolErrorDetails MapRstStreamStatusToProtocolError(
456 SpdyRstStreamStatus status) { 456 SpdyErrorCode error_code) {
457 switch (status) { 457 switch (error_code) {
458 case RST_STREAM_NO_ERROR: 458 case ERROR_CODE_NO_ERROR:
459 return STATUS_CODE_NO_ERROR; 459 return STATUS_CODE_NO_ERROR;
460 case RST_STREAM_PROTOCOL_ERROR: 460 case ERROR_CODE_PROTOCOL_ERROR:
461 return STATUS_CODE_PROTOCOL_ERROR; 461 return STATUS_CODE_PROTOCOL_ERROR;
462 case RST_STREAM_INTERNAL_ERROR: 462 case ERROR_CODE_INTERNAL_ERROR:
463 return STATUS_CODE_INTERNAL_ERROR; 463 return STATUS_CODE_INTERNAL_ERROR;
464 case RST_STREAM_FLOW_CONTROL_ERROR: 464 case ERROR_CODE_FLOW_CONTROL_ERROR:
465 return STATUS_CODE_FLOW_CONTROL_ERROR; 465 return STATUS_CODE_FLOW_CONTROL_ERROR;
466 case RST_STREAM_SETTINGS_TIMEOUT: 466 case ERROR_CODE_SETTINGS_TIMEOUT:
467 return STATUS_CODE_SETTINGS_TIMEOUT; 467 return STATUS_CODE_SETTINGS_TIMEOUT;
468 case RST_STREAM_STREAM_CLOSED: 468 case ERROR_CODE_STREAM_CLOSED:
469 return STATUS_CODE_STREAM_CLOSED; 469 return STATUS_CODE_STREAM_CLOSED;
470 case RST_STREAM_FRAME_SIZE_ERROR: 470 case ERROR_CODE_FRAME_SIZE_ERROR:
471 return STATUS_CODE_FRAME_SIZE_ERROR; 471 return STATUS_CODE_FRAME_SIZE_ERROR;
472 case RST_STREAM_REFUSED_STREAM: 472 case ERROR_CODE_REFUSED_STREAM:
473 return STATUS_CODE_REFUSED_STREAM; 473 return STATUS_CODE_REFUSED_STREAM;
474 case RST_STREAM_CANCEL: 474 case ERROR_CODE_CANCEL:
475 return STATUS_CODE_CANCEL; 475 return STATUS_CODE_CANCEL;
476 case RST_STREAM_COMPRESSION_ERROR: 476 case ERROR_CODE_COMPRESSION_ERROR:
477 return STATUS_CODE_COMPRESSION_ERROR; 477 return STATUS_CODE_COMPRESSION_ERROR;
478 case RST_STREAM_CONNECT_ERROR: 478 case ERROR_CODE_CONNECT_ERROR:
479 return STATUS_CODE_CONNECT_ERROR; 479 return STATUS_CODE_CONNECT_ERROR;
480 case RST_STREAM_ENHANCE_YOUR_CALM: 480 case ERROR_CODE_ENHANCE_YOUR_CALM:
481 return STATUS_CODE_ENHANCE_YOUR_CALM; 481 return STATUS_CODE_ENHANCE_YOUR_CALM;
482 case RST_STREAM_INADEQUATE_SECURITY: 482 case ERROR_CODE_INADEQUATE_SECURITY:
483 return STATUS_CODE_INADEQUATE_SECURITY; 483 return STATUS_CODE_INADEQUATE_SECURITY;
484 case RST_STREAM_HTTP_1_1_REQUIRED: 484 case ERROR_CODE_HTTP_1_1_REQUIRED:
485 return STATUS_CODE_HTTP_1_1_REQUIRED; 485 return STATUS_CODE_HTTP_1_1_REQUIRED;
486 default: 486 default:
487 NOTREACHED(); 487 NOTREACHED();
488 return static_cast<SpdyProtocolErrorDetails>(-1); 488 return static_cast<SpdyProtocolErrorDetails>(-1);
489 } 489 }
490 } 490 }
491 491
492 SpdyGoAwayStatus MapNetErrorToGoAwayStatus(Error err) { 492 SpdyErrorCode MapNetErrorToGoAwayStatus(Error err) {
493 switch (err) { 493 switch (err) {
494 case OK: 494 case OK:
495 return GOAWAY_NO_ERROR; 495 return ERROR_CODE_NO_ERROR;
496 case ERR_SPDY_PROTOCOL_ERROR: 496 case ERR_SPDY_PROTOCOL_ERROR:
497 return GOAWAY_PROTOCOL_ERROR; 497 return ERROR_CODE_PROTOCOL_ERROR;
498 case ERR_SPDY_FLOW_CONTROL_ERROR: 498 case ERR_SPDY_FLOW_CONTROL_ERROR:
499 return GOAWAY_FLOW_CONTROL_ERROR; 499 return ERROR_CODE_FLOW_CONTROL_ERROR;
500 case ERR_SPDY_FRAME_SIZE_ERROR: 500 case ERR_SPDY_FRAME_SIZE_ERROR:
501 return GOAWAY_FRAME_SIZE_ERROR; 501 return ERROR_CODE_FRAME_SIZE_ERROR;
502 case ERR_SPDY_COMPRESSION_ERROR: 502 case ERR_SPDY_COMPRESSION_ERROR:
503 return GOAWAY_COMPRESSION_ERROR; 503 return ERROR_CODE_COMPRESSION_ERROR;
504 case ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY: 504 case ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY:
505 return GOAWAY_INADEQUATE_SECURITY; 505 return ERROR_CODE_INADEQUATE_SECURITY;
506 default: 506 default:
507 return GOAWAY_PROTOCOL_ERROR; 507 return ERROR_CODE_PROTOCOL_ERROR;
508 } 508 }
509 } 509 }
510 510
511 SpdyStreamRequest::SpdyStreamRequest() : weak_ptr_factory_(this) { 511 SpdyStreamRequest::SpdyStreamRequest() : weak_ptr_factory_(this) {
512 Reset(); 512 Reset();
513 } 513 }
514 514
515 SpdyStreamRequest::~SpdyStreamRequest() { 515 SpdyStreamRequest::~SpdyStreamRequest() {
516 CancelRequest(); 516 CancelRequest();
517 } 517 }
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 872
873 void SpdySession::CancelPush(const GURL& url) { 873 void SpdySession::CancelPush(const GURL& url) {
874 UnclaimedPushedStreamContainer::const_iterator unclaimed_it = 874 UnclaimedPushedStreamContainer::const_iterator unclaimed_it =
875 unclaimed_pushed_streams_.find(url); 875 unclaimed_pushed_streams_.find(url);
876 if (unclaimed_it == unclaimed_pushed_streams_.end()) 876 if (unclaimed_it == unclaimed_pushed_streams_.end())
877 return; 877 return;
878 878
879 SpdyStreamId stream_id = unclaimed_it->second.stream_id; 879 SpdyStreamId stream_id = unclaimed_it->second.stream_id;
880 880
881 if (active_streams_.find(stream_id) == active_streams_.end()) { 881 if (active_streams_.find(stream_id) == active_streams_.end()) {
882 ResetStream(stream_id, RST_STREAM_CANCEL, 882 ResetStream(stream_id, ERROR_CODE_CANCEL,
883 "Cancelled push stream with url: " + url.spec()); 883 "Cancelled push stream with url: " + url.spec());
884 } 884 }
885 unclaimed_pushed_streams_.erase(unclaimed_it); 885 unclaimed_pushed_streams_.erase(unclaimed_it);
886 } 886 }
887 887
888 // {,Try}CreateStream() can be called with |in_io_loop_| set if a stream is 888 // {,Try}CreateStream() can be called with |in_io_loop_| set if a stream is
889 // being created in response to another being closed due to received data. 889 // being created in response to another being closed due to received data.
890 890
891 int SpdySession::TryCreateStream( 891 int SpdySession::TryCreateStream(
892 const base::WeakPtr<SpdyStreamRequest>& request, 892 const base::WeakPtr<SpdyStreamRequest>& request,
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 CreatedStreamSet::iterator it = created_streams_.find(stream.get()); 1249 CreatedStreamSet::iterator it = created_streams_.find(stream.get());
1250 if (it == created_streams_.end()) { 1250 if (it == created_streams_.end()) {
1251 NOTREACHED(); 1251 NOTREACHED();
1252 return; 1252 return;
1253 } 1253 }
1254 1254
1255 CloseCreatedStreamIterator(it, status); 1255 CloseCreatedStreamIterator(it, status);
1256 } 1256 }
1257 1257
1258 void SpdySession::ResetStream(SpdyStreamId stream_id, 1258 void SpdySession::ResetStream(SpdyStreamId stream_id,
1259 SpdyRstStreamStatus status, 1259 SpdyErrorCode error_code,
1260 const std::string& description) { 1260 const std::string& description) {
1261 DCHECK_NE(stream_id, 0u); 1261 DCHECK_NE(stream_id, 0u);
1262 1262
1263 ActiveStreamMap::iterator it = active_streams_.find(stream_id); 1263 ActiveStreamMap::iterator it = active_streams_.find(stream_id);
1264 if (it == active_streams_.end()) { 1264 if (it == active_streams_.end()) {
1265 NOTREACHED(); 1265 NOTREACHED();
1266 return; 1266 return;
1267 } 1267 }
1268 1268
1269 ResetStreamIterator(it, status, description); 1269 ResetStreamIterator(it, error_code, description);
1270 } 1270 }
1271 1271
1272 bool SpdySession::IsStreamActive(SpdyStreamId stream_id) const { 1272 bool SpdySession::IsStreamActive(SpdyStreamId stream_id) const {
1273 return base::ContainsKey(active_streams_, stream_id); 1273 return base::ContainsKey(active_streams_, stream_id);
1274 } 1274 }
1275 1275
1276 LoadState SpdySession::GetLoadState() const { 1276 LoadState SpdySession::GetLoadState() const {
1277 // Just report that we're idle since the session could be doing 1277 // Just report that we're idle since the session could be doing
1278 // many things concurrently. 1278 // many things concurrently.
1279 return LOAD_STATE_IDLE; 1279 return LOAD_STATE_IDLE;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 } 1314 }
1315 1315
1316 void SpdySession::CloseCreatedStreamIterator(CreatedStreamSet::iterator it, 1316 void SpdySession::CloseCreatedStreamIterator(CreatedStreamSet::iterator it,
1317 int status) { 1317 int status) {
1318 std::unique_ptr<SpdyStream> owned_stream(*it); 1318 std::unique_ptr<SpdyStream> owned_stream(*it);
1319 created_streams_.erase(it); 1319 created_streams_.erase(it);
1320 DeleteStream(std::move(owned_stream), status); 1320 DeleteStream(std::move(owned_stream), status);
1321 } 1321 }
1322 1322
1323 void SpdySession::ResetStreamIterator(ActiveStreamMap::iterator it, 1323 void SpdySession::ResetStreamIterator(ActiveStreamMap::iterator it,
1324 SpdyRstStreamStatus status, 1324 SpdyErrorCode error_code,
1325 const std::string& description) { 1325 const std::string& description) {
1326 // Send the RST_STREAM frame first as CloseActiveStreamIterator() 1326 // Send the RST_STREAM frame first as CloseActiveStreamIterator()
1327 // may close us. 1327 // may close us.
1328 SpdyStreamId stream_id = it->first; 1328 SpdyStreamId stream_id = it->first;
1329 RequestPriority priority = it->second->priority(); 1329 RequestPriority priority = it->second->priority();
1330 EnqueueResetStreamFrame(stream_id, priority, status, description); 1330 EnqueueResetStreamFrame(stream_id, priority, error_code, description);
1331 1331
1332 // Removes any pending writes for the stream except for possibly an 1332 // Removes any pending writes for the stream except for possibly an
1333 // in-flight one. 1333 // in-flight one.
1334 CloseActiveStreamIterator(it, ERR_SPDY_PROTOCOL_ERROR); 1334 CloseActiveStreamIterator(it, ERR_SPDY_PROTOCOL_ERROR);
1335 } 1335 }
1336 1336
1337 void SpdySession::EnqueueResetStreamFrame(SpdyStreamId stream_id, 1337 void SpdySession::EnqueueResetStreamFrame(SpdyStreamId stream_id,
1338 RequestPriority priority, 1338 RequestPriority priority,
1339 SpdyRstStreamStatus status, 1339 SpdyErrorCode error_code,
1340 const std::string& description) { 1340 const std::string& description) {
1341 DCHECK_NE(stream_id, 0u); 1341 DCHECK_NE(stream_id, 0u);
1342 1342
1343 net_log().AddEvent( 1343 net_log().AddEvent(
1344 NetLogEventType::HTTP2_SESSION_SEND_RST_STREAM, 1344 NetLogEventType::HTTP2_SESSION_SEND_RST_STREAM,
1345 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description)); 1345 base::Bind(&NetLogSpdyRstCallback, stream_id, error_code, &description));
1346 1346
1347 DCHECK(buffered_spdy_framer_.get()); 1347 DCHECK(buffered_spdy_framer_.get());
1348 std::unique_ptr<SpdySerializedFrame> rst_frame( 1348 std::unique_ptr<SpdySerializedFrame> rst_frame(
1349 buffered_spdy_framer_->CreateRstStream(stream_id, status)); 1349 buffered_spdy_framer_->CreateRstStream(stream_id, error_code));
1350 1350
1351 EnqueueSessionWrite(priority, RST_STREAM, std::move(rst_frame)); 1351 EnqueueSessionWrite(priority, RST_STREAM, std::move(rst_frame));
1352 RecordProtocolErrorHistogram(MapRstStreamStatusToProtocolError(status)); 1352 RecordProtocolErrorHistogram(MapRstStreamStatusToProtocolError(error_code));
1353 } 1353 }
1354 1354
1355 void SpdySession::EnqueuePriorityFrame(SpdyStreamId stream_id, 1355 void SpdySession::EnqueuePriorityFrame(SpdyStreamId stream_id,
1356 SpdyStreamId dependency_id, 1356 SpdyStreamId dependency_id,
1357 int weight, 1357 int weight,
1358 bool exclusive) { 1358 bool exclusive) {
1359 net_log().AddEvent(NetLogEventType::HTTP2_STREAM_SEND_PRIORITY, 1359 net_log().AddEvent(NetLogEventType::HTTP2_STREAM_SEND_PRIORITY,
1360 base::Bind(&NetLogSpdyPriorityCallback, stream_id, 1360 base::Bind(&NetLogSpdyPriorityCallback, stream_id,
1361 dependency_id, weight, exclusive)); 1361 dependency_id, weight, exclusive));
1362 1362
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after
2052 } 2052 }
2053 2053
2054 void SpdySession::OnStreamError(SpdyStreamId stream_id, 2054 void SpdySession::OnStreamError(SpdyStreamId stream_id,
2055 const std::string& description) { 2055 const std::string& description) {
2056 CHECK(in_io_loop_); 2056 CHECK(in_io_loop_);
2057 2057
2058 ActiveStreamMap::iterator it = active_streams_.find(stream_id); 2058 ActiveStreamMap::iterator it = active_streams_.find(stream_id);
2059 if (it == active_streams_.end()) { 2059 if (it == active_streams_.end()) {
2060 // We still want to send a frame to reset the stream even if we 2060 // We still want to send a frame to reset the stream even if we
2061 // don't know anything about it. 2061 // don't know anything about it.
2062 EnqueueResetStreamFrame( 2062 EnqueueResetStreamFrame(stream_id, IDLE, ERROR_CODE_PROTOCOL_ERROR,
2063 stream_id, IDLE, RST_STREAM_PROTOCOL_ERROR, description); 2063 description);
2064 return; 2064 return;
2065 } 2065 }
2066 2066
2067 ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, description); 2067 ResetStreamIterator(it, ERROR_CODE_PROTOCOL_ERROR, description);
2068 } 2068 }
2069 2069
2070 void SpdySession::OnDataFrameHeader(SpdyStreamId stream_id, 2070 void SpdySession::OnDataFrameHeader(SpdyStreamId stream_id,
2071 size_t length, 2071 size_t length,
2072 bool fin) { 2072 bool fin) {
2073 CHECK(in_io_loop_); 2073 CHECK(in_io_loop_);
2074 2074
2075 ActiveStreamMap::iterator it = active_streams_.find(stream_id); 2075 ActiveStreamMap::iterator it = active_streams_.find(stream_id);
2076 2076
2077 // By the time data comes in, the stream may already be inactive. 2077 // By the time data comes in, the stream may already be inactive.
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2241 streams_to_close.begin(); 2241 streams_to_close.begin();
2242 to_close_it != streams_to_close.end(); ++to_close_it) { 2242 to_close_it != streams_to_close.end(); ++to_close_it) {
2243 ActiveStreamMap::iterator active_it = active_streams_.find(*to_close_it); 2243 ActiveStreamMap::iterator active_it = active_streams_.find(*to_close_it);
2244 if (active_it == active_streams_.end()) 2244 if (active_it == active_streams_.end())
2245 continue; 2245 continue;
2246 bytes_pushed_and_unclaimed_count_ += active_it->second->recv_bytes(); 2246 bytes_pushed_and_unclaimed_count_ += active_it->second->recv_bytes();
2247 2247
2248 LogAbandonedActiveStream(active_it, ERR_INVALID_SPDY_STREAM); 2248 LogAbandonedActiveStream(active_it, ERR_INVALID_SPDY_STREAM);
2249 // CloseActiveStreamIterator() will remove the stream from 2249 // CloseActiveStreamIterator() will remove the stream from
2250 // |unclaimed_pushed_streams_|. 2250 // |unclaimed_pushed_streams_|.
2251 ResetStreamIterator( 2251 ResetStreamIterator(active_it, ERROR_CODE_REFUSED_STREAM,
2252 active_it, RST_STREAM_REFUSED_STREAM, "Stream not claimed."); 2252 "Stream not claimed.");
2253 } 2253 }
2254 2254
2255 next_unclaimed_push_stream_sweep_time_ = time_func_() + 2255 next_unclaimed_push_stream_sweep_time_ = time_func_() +
2256 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); 2256 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds);
2257 } 2257 }
2258 2258
2259 void SpdySession::OnHeaders(SpdyStreamId stream_id, 2259 void SpdySession::OnHeaders(SpdyStreamId stream_id,
2260 bool has_priority, 2260 bool has_priority,
2261 int weight, 2261 int weight,
2262 SpdyStreamId parent_stream_id, 2262 SpdyStreamId parent_stream_id,
(...skipping 18 matching lines...) Expand all
2281 SpdyStream* stream = it->second; 2281 SpdyStream* stream = it->second;
2282 CHECK_EQ(stream->stream_id(), stream_id); 2282 CHECK_EQ(stream->stream_id(), stream_id);
2283 2283
2284 stream->AddRawReceivedBytes(last_compressed_frame_len_); 2284 stream->AddRawReceivedBytes(last_compressed_frame_len_);
2285 last_compressed_frame_len_ = 0; 2285 last_compressed_frame_len_ = 0;
2286 2286
2287 if (it->second->IsReservedRemote()) { 2287 if (it->second->IsReservedRemote()) {
2288 DCHECK_EQ(SPDY_PUSH_STREAM, stream->type()); 2288 DCHECK_EQ(SPDY_PUSH_STREAM, stream->type());
2289 if (max_concurrent_pushed_streams_ && 2289 if (max_concurrent_pushed_streams_ &&
2290 num_active_pushed_streams_ >= max_concurrent_pushed_streams_) { 2290 num_active_pushed_streams_ >= max_concurrent_pushed_streams_) {
2291 ResetStream(stream_id, RST_STREAM_REFUSED_STREAM, 2291 ResetStream(stream_id, ERROR_CODE_REFUSED_STREAM,
2292 "Stream concurrency limit reached."); 2292 "Stream concurrency limit reached.");
2293 return; 2293 return;
2294 } 2294 }
2295 2295
2296 // Will be balanced in DeleteStream. 2296 // Will be balanced in DeleteStream.
2297 num_active_pushed_streams_++; 2297 num_active_pushed_streams_++;
2298 } 2298 }
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_();
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2361 if (stream_id % 2 == 1 && stream_id > stream_hi_water_mark_) 2361 if (stream_id % 2 == 1 && stream_id > stream_hi_water_mark_)
2362 return false; 2362 return false;
2363 2363
2364 if (stream_id % 2 == 0 && stream_id > last_accepted_push_stream_id_) 2364 if (stream_id % 2 == 0 && stream_id > last_accepted_push_stream_id_)
2365 return false; 2365 return false;
2366 2366
2367 return true; 2367 return true;
2368 } 2368 }
2369 2369
2370 void SpdySession::OnRstStream(SpdyStreamId stream_id, 2370 void SpdySession::OnRstStream(SpdyStreamId stream_id,
2371 SpdyRstStreamStatus status) { 2371 SpdyErrorCode error_code) {
2372 CHECK(in_io_loop_); 2372 CHECK(in_io_loop_);
2373 2373
2374 std::string description; 2374 std::string description;
2375 net_log().AddEvent( 2375 net_log().AddEvent(
2376 NetLogEventType::HTTP2_SESSION_RST_STREAM, 2376 NetLogEventType::HTTP2_SESSION_RST_STREAM,
2377 base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description)); 2377 base::Bind(&NetLogSpdyRstCallback, stream_id, error_code, &description));
2378 2378
2379 ActiveStreamMap::iterator it = active_streams_.find(stream_id); 2379 ActiveStreamMap::iterator it = active_streams_.find(stream_id);
2380 if (it == active_streams_.end()) { 2380 if (it == active_streams_.end()) {
2381 // NOTE: it may just be that the stream was cancelled. 2381 // NOTE: it may just be that the stream was cancelled.
2382 LOG(WARNING) << "Received RST for invalid stream" << stream_id; 2382 LOG(WARNING) << "Received RST for invalid stream" << stream_id;
2383 return; 2383 return;
2384 } 2384 }
2385 2385
2386 CHECK_EQ(it->second->stream_id(), stream_id); 2386 CHECK_EQ(it->second->stream_id(), stream_id);
2387 2387
2388 if (status == RST_STREAM_NO_ERROR) { 2388 if (error_code == ERROR_CODE_NO_ERROR) {
2389 CloseActiveStreamIterator(it, ERR_SPDY_RST_STREAM_NO_ERROR_RECEIVED); 2389 CloseActiveStreamIterator(it, ERR_SPDY_RST_STREAM_NO_ERROR_RECEIVED);
2390 } else if (status == RST_STREAM_REFUSED_STREAM) { 2390 } else if (error_code == ERROR_CODE_REFUSED_STREAM) {
2391 CloseActiveStreamIterator(it, ERR_SPDY_SERVER_REFUSED_STREAM); 2391 CloseActiveStreamIterator(it, ERR_SPDY_SERVER_REFUSED_STREAM);
2392 } else if (status == RST_STREAM_HTTP_1_1_REQUIRED) { 2392 } else if (error_code == ERROR_CODE_HTTP_1_1_REQUIRED) {
2393 // TODO(bnc): Record histogram with number of open streams capped at 50. 2393 // TODO(bnc): Record histogram with number of open streams capped at 50.
2394 it->second->LogStreamError( 2394 it->second->LogStreamError(
2395 ERR_HTTP_1_1_REQUIRED, 2395 ERR_HTTP_1_1_REQUIRED,
2396 base::StringPrintf( 2396 base::StringPrintf(
2397 "SPDY session closed because of stream with status: %d", status)); 2397 "SPDY session closed because of stream with error_code: %d",
2398 error_code));
2398 DoDrainSession(ERR_HTTP_1_1_REQUIRED, "HTTP_1_1_REQUIRED for stream."); 2399 DoDrainSession(ERR_HTTP_1_1_REQUIRED, "HTTP_1_1_REQUIRED for stream.");
2399 } else { 2400 } else {
2400 RecordProtocolErrorHistogram( 2401 RecordProtocolErrorHistogram(
2401 PROTOCOL_ERROR_RST_STREAM_FOR_NON_ACTIVE_STREAM); 2402 PROTOCOL_ERROR_RST_STREAM_FOR_NON_ACTIVE_STREAM);
2402 it->second->LogStreamError( 2403 it->second->LogStreamError(
2403 ERR_SPDY_PROTOCOL_ERROR, 2404 ERR_SPDY_PROTOCOL_ERROR,
2404 base::StringPrintf("SPDY stream closed with status: %d", status)); 2405 base::StringPrintf("SPDY stream closed with error_code: %d",
2406 error_code));
2405 // TODO(mbelshe): Map from Spdy-protocol errors to something sensical. 2407 // TODO(mbelshe): Map from Spdy-protocol errors to something sensical.
2406 // For now, it doesn't matter much - it is a protocol error. 2408 // For now, it doesn't matter much - it is a protocol error.
2407 CloseActiveStreamIterator(it, ERR_SPDY_PROTOCOL_ERROR); 2409 CloseActiveStreamIterator(it, ERR_SPDY_PROTOCOL_ERROR);
2408 } 2410 }
2409 } 2411 }
2410 2412
2411 void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id, 2413 void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id,
2412 SpdyGoAwayStatus status, 2414 SpdyErrorCode error_code,
2413 base::StringPiece debug_data) { 2415 base::StringPiece debug_data) {
2414 CHECK(in_io_loop_); 2416 CHECK(in_io_loop_);
2415 2417
2416 // TODO(jgraettinger): UMA histogram on |status|. 2418 // TODO(jgraettinger): UMA histogram on |error_code|.
2417 2419
2418 net_log_.AddEvent( 2420 net_log_.AddEvent(
2419 NetLogEventType::HTTP2_SESSION_GOAWAY, 2421 NetLogEventType::HTTP2_SESSION_GOAWAY,
2420 base::Bind(&NetLogSpdyGoAwayCallback, last_accepted_stream_id, 2422 base::Bind(&NetLogSpdyGoAwayCallback, last_accepted_stream_id,
2421 active_streams_.size(), unclaimed_pushed_streams_.size(), 2423 active_streams_.size(), unclaimed_pushed_streams_.size(),
2422 status, debug_data)); 2424 error_code, debug_data));
2423 MakeUnavailable(); 2425 MakeUnavailable();
2424 if (status == GOAWAY_HTTP_1_1_REQUIRED) { 2426 if (error_code == ERROR_CODE_HTTP_1_1_REQUIRED) {
2425 // TODO(bnc): Record histogram with number of open streams capped at 50. 2427 // TODO(bnc): Record histogram with number of open streams capped at 50.
2426 DoDrainSession(ERR_HTTP_1_1_REQUIRED, "HTTP_1_1_REQUIRED for stream."); 2428 DoDrainSession(ERR_HTTP_1_1_REQUIRED, "HTTP_1_1_REQUIRED for stream.");
2427 } else { 2429 } else {
2428 StartGoingAway(last_accepted_stream_id, ERR_ABORTED); 2430 StartGoingAway(last_accepted_stream_id, ERR_ABORTED);
2429 } 2431 }
2430 // This is to handle the case when we already don't have any active 2432 // This is to handle the case when we already don't have any active
2431 // streams (i.e., StartGoingAway() did nothing). Otherwise, we have 2433 // streams (i.e., StartGoingAway() did nothing). Otherwise, we have
2432 // active streams and so the last one being closed will finish the 2434 // active streams and so the last one being closed will finish the
2433 // going away process (see DeleteStream()). 2435 // going away process (see DeleteStream()).
2434 MaybeFinishGoingAway(); 2436 MaybeFinishGoingAway();
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2490 if (it == active_streams_.end()) { 2492 if (it == active_streams_.end()) {
2491 // NOTE: it may just be that the stream was cancelled. 2493 // NOTE: it may just be that the stream was cancelled.
2492 LOG(WARNING) << "Received WINDOW_UPDATE for invalid stream " << stream_id; 2494 LOG(WARNING) << "Received WINDOW_UPDATE for invalid stream " << stream_id;
2493 return; 2495 return;
2494 } 2496 }
2495 2497
2496 SpdyStream* stream = it->second; 2498 SpdyStream* stream = it->second;
2497 CHECK_EQ(stream->stream_id(), stream_id); 2499 CHECK_EQ(stream->stream_id(), stream_id);
2498 2500
2499 if (delta_window_size < 1) { 2501 if (delta_window_size < 1) {
2500 ResetStreamIterator(it, RST_STREAM_FLOW_CONTROL_ERROR, 2502 ResetStreamIterator(
2501 base::StringPrintf( 2503 it, ERROR_CODE_FLOW_CONTROL_ERROR,
2502 "Received WINDOW_UPDATE with an invalid " 2504 base::StringPrintf("Received WINDOW_UPDATE with an invalid "
2503 "delta_window_size %d", 2505 "delta_window_size %d",
2504 delta_window_size)); 2506 delta_window_size));
2505 return; 2507 return;
2506 } 2508 }
2507 2509
2508 CHECK_EQ(it->second->stream_id(), stream_id); 2510 CHECK_EQ(it->second->stream_id(), stream_id);
2509 it->second->IncreaseSendWindowSize(delta_window_size); 2511 it->second->IncreaseSendWindowSize(delta_window_size);
2510 } 2512 }
2511 } 2513 }
2512 2514
2513 void SpdySession::TryCreatePushStream(SpdyStreamId stream_id, 2515 void SpdySession::TryCreatePushStream(SpdyStreamId stream_id,
2514 SpdyStreamId associated_stream_id, 2516 SpdyStreamId associated_stream_id,
(...skipping 30 matching lines...) Expand all
2545 } 2547 }
2546 2548
2547 last_accepted_push_stream_id_ = stream_id; 2549 last_accepted_push_stream_id_ = stream_id;
2548 2550
2549 // Pushed streams are speculative, so they start at an IDLE priority. 2551 // Pushed streams are speculative, so they start at an IDLE priority.
2550 const RequestPriority request_priority = IDLE; 2552 const RequestPriority request_priority = IDLE;
2551 2553
2552 if (availability_state_ == STATE_GOING_AWAY) { 2554 if (availability_state_ == STATE_GOING_AWAY) {
2553 // TODO(akalin): This behavior isn't in the SPDY spec, although it 2555 // TODO(akalin): This behavior isn't in the SPDY spec, although it
2554 // probably should be. 2556 // probably should be.
2555 EnqueueResetStreamFrame(stream_id, 2557 EnqueueResetStreamFrame(stream_id, request_priority,
2556 request_priority, 2558 ERROR_CODE_REFUSED_STREAM,
2557 RST_STREAM_REFUSED_STREAM,
2558 "push stream request received when going away"); 2559 "push stream request received when going away");
2559 return; 2560 return;
2560 } 2561 }
2561 2562
2562 if (associated_stream_id == 0) { 2563 if (associated_stream_id == 0) {
2563 // In HTTP/2 0 stream id in PUSH_PROMISE frame leads to framer error and 2564 // In HTTP/2 0 stream id in PUSH_PROMISE frame leads to framer error and
2564 // session going away. We should never get here. 2565 // session going away. We should never get here.
2565 std::string description = base::StringPrintf( 2566 std::string description = base::StringPrintf(
2566 "Received invalid associated stream id %d for pushed stream %d", 2567 "Received invalid associated stream id %d for pushed stream %d",
2567 associated_stream_id, 2568 associated_stream_id,
2568 stream_id); 2569 stream_id);
2569 EnqueueResetStreamFrame( 2570 EnqueueResetStreamFrame(stream_id, request_priority,
2570 stream_id, request_priority, RST_STREAM_REFUSED_STREAM, description); 2571 ERROR_CODE_REFUSED_STREAM, description);
2571 return; 2572 return;
2572 } 2573 }
2573 2574
2574 streams_pushed_count_++; 2575 streams_pushed_count_++;
2575 2576
2576 // TODO(mbelshe): DCHECK that this is a GET method? 2577 // TODO(mbelshe): DCHECK that this is a GET method?
2577 2578
2578 // Verify that the response had a URL for us. 2579 // Verify that the response had a URL for us.
2579 GURL gurl = GetUrlFromHeaderBlock(headers); 2580 GURL gurl = GetUrlFromHeaderBlock(headers);
2580 if (!gurl.is_valid()) { 2581 if (!gurl.is_valid()) {
2581 EnqueueResetStreamFrame(stream_id, 2582 EnqueueResetStreamFrame(stream_id, request_priority,
2582 request_priority, 2583 ERROR_CODE_PROTOCOL_ERROR,
2583 RST_STREAM_PROTOCOL_ERROR,
2584 "Pushed stream url was invalid: " + gurl.spec()); 2584 "Pushed stream url was invalid: " + gurl.spec());
2585 return; 2585 return;
2586 } 2586 }
2587 2587
2588 // Verify we have a valid stream association. 2588 // Verify we have a valid stream association.
2589 ActiveStreamMap::iterator associated_it = 2589 ActiveStreamMap::iterator associated_it =
2590 active_streams_.find(associated_stream_id); 2590 active_streams_.find(associated_stream_id);
2591 if (associated_it == active_streams_.end()) { 2591 if (associated_it == active_streams_.end()) {
2592 EnqueueResetStreamFrame( 2592 EnqueueResetStreamFrame(
2593 stream_id, request_priority, RST_STREAM_STREAM_CLOSED, 2593 stream_id, request_priority, ERROR_CODE_STREAM_CLOSED,
2594 base::StringPrintf("Received push for inactive associated stream %d", 2594 base::StringPrintf("Received push for inactive associated stream %d",
2595 associated_stream_id)); 2595 associated_stream_id));
2596 return; 2596 return;
2597 } 2597 }
2598 2598
2599 DCHECK(gurl.is_valid()); 2599 DCHECK(gurl.is_valid());
2600 2600
2601 // Check that the pushed stream advertises the same origin as its associated 2601 // Check that the pushed stream advertises the same origin as its associated
2602 // stream. Bypass this check if and only if this session is with a SPDY proxy 2602 // stream. Bypass this check if and only if this session is with a SPDY proxy
2603 // that is trusted explicitly as determined by the |proxy_delegate_| or if the 2603 // that is trusted explicitly as determined by the |proxy_delegate_| or if the
2604 // proxy is pushing same-origin resources. 2604 // proxy is pushing same-origin resources.
2605 if (!HostPortPair::FromURL(gurl).Equals(host_port_pair())) { 2605 if (!HostPortPair::FromURL(gurl).Equals(host_port_pair())) {
2606 if (proxy_delegate_ && 2606 if (proxy_delegate_ &&
2607 proxy_delegate_->IsTrustedSpdyProxy( 2607 proxy_delegate_->IsTrustedSpdyProxy(
2608 ProxyServer(ProxyServer::SCHEME_HTTPS, host_port_pair()))) { 2608 ProxyServer(ProxyServer::SCHEME_HTTPS, host_port_pair()))) {
2609 // Disallow pushing of HTTPS content. 2609 // Disallow pushing of HTTPS content.
2610 if (gurl.SchemeIs("https")) { 2610 if (gurl.SchemeIs("https")) {
2611 EnqueueResetStreamFrame( 2611 EnqueueResetStreamFrame(
2612 stream_id, request_priority, RST_STREAM_REFUSED_STREAM, 2612 stream_id, request_priority, ERROR_CODE_REFUSED_STREAM,
2613 base::StringPrintf("Rejected push of cross origin HTTPS content %d " 2613 base::StringPrintf("Rejected push of cross origin HTTPS content %d "
2614 "from trusted proxy", 2614 "from trusted proxy",
2615 associated_stream_id)); 2615 associated_stream_id));
2616 return; 2616 return;
2617 } 2617 }
2618 } else { 2618 } else {
2619 GURL associated_url(associated_it->second->GetUrlFromHeaders()); 2619 GURL associated_url(associated_it->second->GetUrlFromHeaders());
2620 if (associated_url.SchemeIs("https")) { 2620 if (associated_url.SchemeIs("https")) {
2621 SSLInfo ssl_info; 2621 SSLInfo ssl_info;
2622 CHECK(GetSSLInfo(&ssl_info)); 2622 CHECK(GetSSLInfo(&ssl_info));
2623 if (!gurl.SchemeIs("https") || 2623 if (!gurl.SchemeIs("https") ||
2624 !CanPool(transport_security_state_, ssl_info, associated_url.host(), 2624 !CanPool(transport_security_state_, ssl_info, associated_url.host(),
2625 gurl.host())) { 2625 gurl.host())) {
2626 EnqueueResetStreamFrame( 2626 EnqueueResetStreamFrame(
2627 stream_id, request_priority, RST_STREAM_REFUSED_STREAM, 2627 stream_id, request_priority, ERROR_CODE_REFUSED_STREAM,
2628 base::StringPrintf("Rejected push stream %d on secure connection", 2628 base::StringPrintf("Rejected push stream %d on secure connection",
2629 associated_stream_id)); 2629 associated_stream_id));
2630 return; 2630 return;
2631 } 2631 }
2632 } else { 2632 } else {
2633 // TODO(bnc): Change SpdyNetworkTransactionTests to use secure sockets. 2633 // TODO(bnc): Change SpdyNetworkTransactionTests to use secure sockets.
2634 if (associated_url.GetOrigin() != gurl.GetOrigin()) { 2634 if (associated_url.GetOrigin() != gurl.GetOrigin()) {
2635 EnqueueResetStreamFrame( 2635 EnqueueResetStreamFrame(
2636 stream_id, request_priority, RST_STREAM_REFUSED_STREAM, 2636 stream_id, request_priority, ERROR_CODE_REFUSED_STREAM,
2637 base::StringPrintf( 2637 base::StringPrintf(
2638 "Rejected cross origin push stream %d on insecure connection", 2638 "Rejected cross origin push stream %d on insecure connection",
2639 associated_stream_id)); 2639 associated_stream_id));
2640 return; 2640 return;
2641 } 2641 }
2642 } 2642 }
2643 } 2643 }
2644 } 2644 }
2645 2645
2646 // There should not be an existing pushed stream with the same path. 2646 // There should not be an existing pushed stream with the same path.
2647 UnclaimedPushedStreamContainer::const_iterator pushed_it = 2647 UnclaimedPushedStreamContainer::const_iterator pushed_it =
2648 unclaimed_pushed_streams_.lower_bound(gurl); 2648 unclaimed_pushed_streams_.lower_bound(gurl);
2649 if (pushed_it != unclaimed_pushed_streams_.end() && 2649 if (pushed_it != unclaimed_pushed_streams_.end() &&
2650 pushed_it->first == gurl) { 2650 pushed_it->first == gurl) {
2651 EnqueueResetStreamFrame( 2651 EnqueueResetStreamFrame(
2652 stream_id, 2652 stream_id, request_priority, ERROR_CODE_PROTOCOL_ERROR,
2653 request_priority,
2654 RST_STREAM_PROTOCOL_ERROR,
2655 "Received duplicate pushed stream with url: " + gurl.spec()); 2653 "Received duplicate pushed stream with url: " + gurl.spec());
2656 return; 2654 return;
2657 } 2655 }
2658 2656
2659 std::unique_ptr<SpdyStream> stream( 2657 std::unique_ptr<SpdyStream> stream(
2660 new SpdyStream(SPDY_PUSH_STREAM, GetWeakPtr(), gurl, request_priority, 2658 new SpdyStream(SPDY_PUSH_STREAM, GetWeakPtr(), gurl, request_priority,
2661 stream_initial_send_window_size_, 2659 stream_initial_send_window_size_,
2662 stream_max_recv_window_size_, net_log_)); 2660 stream_max_recv_window_size_, net_log_));
2663 stream->set_stream_id(stream_id); 2661 stream->set_stream_id(stream_id);
2664 2662
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
3119 if (!queue->empty()) { 3117 if (!queue->empty()) {
3120 SpdyStreamId stream_id = queue->front(); 3118 SpdyStreamId stream_id = queue->front();
3121 queue->pop_front(); 3119 queue->pop_front();
3122 return stream_id; 3120 return stream_id;
3123 } 3121 }
3124 } 3122 }
3125 return 0; 3123 return 0;
3126 } 3124 }
3127 3125
3128 } // namespace net 3126 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_session_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698