| 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 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 return net::OK; | 223 return net::OK; |
| 224 | 224 |
| 225 state_ = CONNECTING; | 225 state_ = CONNECTING; |
| 226 | 226 |
| 227 static StatsCounter spdy_sessions("spdy.sessions"); | 227 static StatsCounter spdy_sessions("spdy.sessions"); |
| 228 spdy_sessions.Increment(); | 228 spdy_sessions.Increment(); |
| 229 | 229 |
| 230 int rv = connection_->Init(group_name, destination, priority, | 230 int rv = connection_->Init(group_name, destination, priority, |
| 231 &connect_callback_, session_->tcp_socket_pool(), | 231 &connect_callback_, session_->tcp_socket_pool(), |
| 232 net_log_); | 232 net_log_); |
| 233 DCHECK_LE(rv, 0); | 233 DCHECK(rv <= 0); |
| 234 | 234 |
| 235 // If the connect is pending, we still return ok. The APIs enqueue | 235 // If the connect is pending, we still return ok. The APIs enqueue |
| 236 // work until after the connect completes asynchronously later. | 236 // work until after the connect completes asynchronously later. |
| 237 if (rv == net::ERR_IO_PENDING) | 237 if (rv == net::ERR_IO_PENDING) |
| 238 return net::OK; | 238 return net::OK; |
| 239 OnTCPConnect(rv); | 239 OnTCPConnect(rv); |
| 240 return static_cast<net::Error>(rv); | 240 return static_cast<net::Error>(rv); |
| 241 } | 241 } |
| 242 | 242 |
| 243 int SpdySession::GetPushStream( | 243 int SpdySession::GetPushStream( |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 LOG(INFO) << "Writing Stream Data for stream " << stream_id << " (" << len | 361 LOG(INFO) << "Writing Stream Data for stream " << stream_id << " (" << len |
| 362 << " bytes)"; | 362 << " bytes)"; |
| 363 const int kMss = 1430; // This is somewhat arbitrary and not really fixed, | 363 const int kMss = 1430; // This is somewhat arbitrary and not really fixed, |
| 364 // but it will always work reasonably with ethernet. | 364 // but it will always work reasonably with ethernet. |
| 365 // Chop the world into 2-packet chunks. This is somewhat arbitrary, but | 365 // Chop the world into 2-packet chunks. This is somewhat arbitrary, but |
| 366 // is reasonably small and ensures that we elicit ACKs quickly from TCP | 366 // is reasonably small and ensures that we elicit ACKs quickly from TCP |
| 367 // (because TCP tries to only ACK every other packet). | 367 // (because TCP tries to only ACK every other packet). |
| 368 const int kMaxSpdyFrameChunkSize = (2 * kMss) - spdy::SpdyFrame::size(); | 368 const int kMaxSpdyFrameChunkSize = (2 * kMss) - spdy::SpdyFrame::size(); |
| 369 | 369 |
| 370 // Find our stream | 370 // Find our stream |
| 371 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 371 DCHECK(IsStreamActive(stream_id)); |
| 372 if (it == active_streams_.end()) { | 372 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
| 373 LOG(DFATAL) << "Attempting to write to stream " << stream_id | 373 CHECK_EQ(stream->stream_id(), stream_id); |
| 374 << ", which does not exist!"; | 374 if (!stream) |
| 375 return ERR_INVALID_SPDY_STREAM; | 375 return ERR_INVALID_SPDY_STREAM; |
| 376 } | |
| 377 | |
| 378 const scoped_refptr<SpdyStream>& stream = it->second; | |
| 379 if (!stream) { | |
| 380 LOG(DFATAL) << "Attempting to write to stream " << stream_id | |
| 381 << ", which does not exist!"; | |
| 382 return ERR_INVALID_SPDY_STREAM; | |
| 383 } | |
| 384 | |
| 385 CHECK_EQ(stream->stream_id(), stream_id); | |
| 386 | 376 |
| 387 // TODO(mbelshe): Setting of the FIN is assuming that the caller will pass | 377 // TODO(mbelshe): Setting of the FIN is assuming that the caller will pass |
| 388 // all data to write in a single chunk. Is this always true? | 378 // all data to write in a single chunk. Is this always true? |
| 389 | 379 |
| 390 // Set the flags on the upload. | 380 // Set the flags on the upload. |
| 391 spdy::SpdyDataFlags flags = spdy::DATA_FLAG_FIN; | 381 spdy::SpdyDataFlags flags = spdy::DATA_FLAG_FIN; |
| 392 if (len > kMaxSpdyFrameChunkSize) { | 382 if (len > kMaxSpdyFrameChunkSize) { |
| 393 len = kMaxSpdyFrameChunkSize; | 383 len = kMaxSpdyFrameChunkSize; |
| 394 flags = spdy::DATA_FLAG_NONE; | 384 flags = spdy::DATA_FLAG_NONE; |
| 395 } | 385 } |
| 396 | 386 |
| 397 // TODO(mbelshe): reduce memory copies here. | 387 // TODO(mbelshe): reduce memory copies here. |
| 398 scoped_ptr<spdy::SpdyDataFrame> frame( | 388 scoped_ptr<spdy::SpdyDataFrame> frame( |
| 399 spdy_framer_.CreateDataFrame(stream_id, data->data(), len, flags)); | 389 spdy_framer_.CreateDataFrame(stream_id, data->data(), len, flags)); |
| 400 QueueFrame(frame.get(), stream->priority(), stream); | 390 QueueFrame(frame.get(), stream->priority(), stream); |
| 401 return ERR_IO_PENDING; | 391 return ERR_IO_PENDING; |
| 402 } | 392 } |
| 403 | 393 |
| 404 void SpdySession::CloseStreamAndSendRst(spdy::SpdyStreamId stream_id, | 394 void SpdySession::CloseStream(spdy::SpdyStreamId stream_id, int status) { |
| 405 int status) { | 395 LOG(INFO) << "Closing stream " << stream_id << " with status " << status; |
| 406 LOG(INFO) << "Closing stream " << stream_id << " with status " << status | 396 // TODO(mbelshe): We should send a RST_STREAM control frame here |
| 407 << " and sending RST_STREAM frame."; | 397 // so that the server can cancel a large send. |
| 408 | 398 |
| 409 DCHECK(IsStreamActive(stream_id)); | 399 DeleteStream(stream_id, status); |
| 410 const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id]; | |
| 411 // We send a RST_STREAM control frame here so that the server can cancel a | |
| 412 // large send. | |
| 413 scoped_ptr<spdy::SpdyRstStreamControlFrame> rst_frame( | |
| 414 spdy_framer_.CreateRstStream(stream_id, spdy::CANCEL)); | |
| 415 QueueFrame(rst_frame.get(), stream->priority(), stream); | |
| 416 | |
| 417 CloseStream(stream_id, status); | |
| 418 } | 400 } |
| 419 | 401 |
| 420 bool SpdySession::IsStreamActive(spdy::SpdyStreamId stream_id) const { | 402 bool SpdySession::IsStreamActive(spdy::SpdyStreamId stream_id) const { |
| 421 return ContainsKey(active_streams_, stream_id); | 403 return ContainsKey(active_streams_, stream_id); |
| 422 } | 404 } |
| 423 | 405 |
| 424 LoadState SpdySession::GetLoadState() const { | 406 LoadState SpdySession::GetLoadState() const { |
| 425 // NOTE: The application only queries the LoadState via the | 407 // NOTE: The application only queries the LoadState via the |
| 426 // SpdyNetworkTransaction, and details are only needed when | 408 // SpdyNetworkTransaction, and details are only needed when |
| 427 // we're in the process of connecting. | 409 // we're in the process of connecting. |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 spdy_framer_.Reset(); | 516 spdy_framer_.Reset(); |
| 535 } | 517 } |
| 536 | 518 |
| 537 if (state_ != CLOSED) | 519 if (state_ != CLOSED) |
| 538 ReadSocket(); | 520 ReadSocket(); |
| 539 } | 521 } |
| 540 | 522 |
| 541 void SpdySession::OnWriteComplete(int result) { | 523 void SpdySession::OnWriteComplete(int result) { |
| 542 DCHECK(write_pending_); | 524 DCHECK(write_pending_); |
| 543 DCHECK(in_flight_write_.size()); | 525 DCHECK(in_flight_write_.size()); |
| 526 DCHECK_NE(result, 0); // This shouldn't happen for write. |
| 544 | 527 |
| 545 write_pending_ = false; | 528 write_pending_ = false; |
| 546 | 529 |
| 547 scoped_refptr<SpdyStream> stream = in_flight_write_.stream(); | 530 scoped_refptr<SpdyStream> stream = in_flight_write_.stream(); |
| 548 | 531 |
| 549 LOG(INFO) << "Spdy write complete (result=" << result << ")" | 532 LOG(INFO) << "Spdy write complete (result=" << result << ")" |
| 550 << (stream ? std::string(" for stream ") + | 533 << (stream ? std::string(" for stream ") + |
| 551 IntToString(stream->stream_id()) : ""); | 534 IntToString(stream->stream_id()) : ""); |
| 552 | 535 |
| 553 if (result >= 0) { | 536 if (result >= 0) { |
| 554 // It should not be possible to have written more bytes than our | 537 // It should not be possible to have written more bytes than our |
| 555 // in_flight_write_. | 538 // in_flight_write_. |
| 556 DCHECK_LE(result, in_flight_write_.buffer()->BytesRemaining()); | 539 DCHECK_LE(result, in_flight_write_.buffer()->BytesRemaining()); |
| 557 | 540 |
| 558 in_flight_write_.buffer()->DidConsume(result); | 541 in_flight_write_.buffer()->DidConsume(result); |
| 559 | 542 |
| 560 // We only notify the stream when we've fully written the pending frame. | 543 // We only notify the stream when we've fully written the pending frame. |
| 561 if (!in_flight_write_.buffer()->BytesRemaining()) { | 544 if (!in_flight_write_.buffer()->BytesRemaining()) { |
| 562 if (stream) { | 545 if (stream) { |
| 563 // If we finished writing all the data from the buffer, it should not be | |
| 564 // the case that we wrote nothing. | |
| 565 DCHECK_NE(result, 0); | |
| 566 | |
| 567 // Report the number of bytes written to the caller, but exclude the | 546 // Report the number of bytes written to the caller, but exclude the |
| 568 // frame size overhead. NOTE: if this frame was compressed the | 547 // frame size overhead. NOTE: if this frame was compressed the |
| 569 // reported bytes written is the compressed size, not the original | 548 // reported bytes written is the compressed size, not the original |
| 570 // size. | 549 // size. |
| 571 result = in_flight_write_.buffer()->size(); | 550 if (result > 0) { |
| 572 DCHECK_GT(result, static_cast<int>(spdy::SpdyFrame::size())); | 551 result = in_flight_write_.buffer()->size(); |
| 573 result -= static_cast<int>(spdy::SpdyFrame::size()); | 552 DCHECK_GT(result, static_cast<int>(spdy::SpdyFrame::size())); |
| 553 result -= static_cast<int>(spdy::SpdyFrame::size()); |
| 554 } |
| 574 | 555 |
| 575 // It is possible that the stream was cancelled while we were writing | 556 // It is possible that the stream was cancelled while we were writing |
| 576 // to the socket. | 557 // to the socket. |
| 577 if (!stream->cancelled()) | 558 if (!stream->cancelled()) |
| 578 stream->OnWriteComplete(result); | 559 stream->OnWriteComplete(result); |
| 579 } | 560 } |
| 580 | 561 |
| 581 // Cleanup the write which just completed. | 562 // Cleanup the write which just completed. |
| 582 in_flight_write_.release(); | 563 in_flight_write_.release(); |
| 583 } | 564 } |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 streams_abandoned_count_ += pushed_streams_.size(); | 703 streams_abandoned_count_ += pushed_streams_.size(); |
| 723 abandoned_push_streams.Add(pushed_streams_.size()); | 704 abandoned_push_streams.Add(pushed_streams_.size()); |
| 724 } | 705 } |
| 725 | 706 |
| 726 while (!active_streams_.empty()) { | 707 while (!active_streams_.empty()) { |
| 727 ActiveStreamMap::iterator it = active_streams_.begin(); | 708 ActiveStreamMap::iterator it = active_streams_.begin(); |
| 728 const scoped_refptr<SpdyStream>& stream = it->second; | 709 const scoped_refptr<SpdyStream>& stream = it->second; |
| 729 DCHECK(stream); | 710 DCHECK(stream); |
| 730 LOG(ERROR) << "ABANDONED (stream_id=" << stream->stream_id() | 711 LOG(ERROR) << "ABANDONED (stream_id=" << stream->stream_id() |
| 731 << "): " << stream->path(); | 712 << "): " << stream->path(); |
| 732 CloseStream(stream->stream_id(), status); | 713 DeleteStream(stream->stream_id(), status); |
| 733 } | 714 } |
| 734 | 715 |
| 735 // TODO(erikchen): ideally stream->OnClose() is only ever called by | 716 // TODO(erikchen): ideally stream->OnClose() is only ever called by |
| 736 // CloseStream, but pending streams fall into their own category for now. | 717 // DeleteStream, but pending streams fall into their own category for now. |
| 737 PendingStreamMap::iterator it; | 718 PendingStreamMap::iterator it; |
| 738 for (it = pending_streams_.begin(); it != pending_streams_.end(); ++it) | 719 for (it = pending_streams_.begin(); it != pending_streams_.end(); ++it) |
| 739 { | 720 { |
| 740 const scoped_refptr<SpdyStream>& stream = it->second; | 721 const scoped_refptr<SpdyStream>& stream = it->second; |
| 741 if (stream) | 722 if (stream) |
| 742 stream->OnClose(ERR_ABORTED); | 723 stream->OnClose(ERR_ABORTED); |
| 743 } | 724 } |
| 744 pending_streams_.clear(); | 725 pending_streams_.clear(); |
| 745 | 726 |
| 746 // We also need to drain the queue. | 727 // We also need to drain the queue. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 787 } | 768 } |
| 788 } | 769 } |
| 789 | 770 |
| 790 void SpdySession::ActivateStream(SpdyStream* stream) { | 771 void SpdySession::ActivateStream(SpdyStream* stream) { |
| 791 const spdy::SpdyStreamId id = stream->stream_id(); | 772 const spdy::SpdyStreamId id = stream->stream_id(); |
| 792 DCHECK(!IsStreamActive(id)); | 773 DCHECK(!IsStreamActive(id)); |
| 793 | 774 |
| 794 active_streams_[id] = stream; | 775 active_streams_[id] = stream; |
| 795 } | 776 } |
| 796 | 777 |
| 797 void SpdySession::CloseStream(spdy::SpdyStreamId id, int status) { | 778 void SpdySession::DeleteStream(spdy::SpdyStreamId id, int status) { |
| 798 // Remove the stream from pushed_streams_ and active_streams_. | 779 // Remove the stream from pushed_streams_ and active_streams_. |
| 799 ActivePushedStreamList::iterator it; | 780 ActivePushedStreamList::iterator it; |
| 800 for (it = pushed_streams_.begin(); it != pushed_streams_.end(); ++it) { | 781 for (it = pushed_streams_.begin(); it != pushed_streams_.end(); ++it) { |
| 801 scoped_refptr<SpdyStream> curr = *it; | 782 scoped_refptr<SpdyStream> curr = *it; |
| 802 if (id == curr->stream_id()) { | 783 if (id == curr->stream_id()) { |
| 803 pushed_streams_.erase(it); | 784 pushed_streams_.erase(it); |
| 804 break; | 785 break; |
| 805 } | 786 } |
| 806 } | 787 } |
| 807 | 788 |
| 808 // The stream might have been deleted. | 789 // The stream might have been deleted. |
| 809 ActiveStreamMap::iterator it2 = active_streams_.find(id); | 790 ActiveStreamMap::iterator it2 = active_streams_.find(id); |
| 810 if (it2 == active_streams_.end()) | 791 if (it2 == active_streams_.end()) |
| 811 return; | 792 return; |
| 812 | 793 |
| 813 // If this is an active stream, call the callback. | 794 // If this is an active stream, call the callback. |
| 814 const scoped_refptr<SpdyStream> stream(it2->second); | 795 const scoped_refptr<SpdyStream> stream(it2->second); |
| 815 active_streams_.erase(it2); | 796 active_streams_.erase(it2); |
| 816 if (stream) { | 797 if (stream) |
| 817 // This is the only place that should set the half_closed flag on the | |
| 818 // stream, and it should only be done once. | |
| 819 DCHECK(!stream->half_closed_client_side()); | |
| 820 stream->HalfCloseClientSide(); | |
| 821 stream->OnClose(status); | 798 stream->OnClose(status); |
| 822 } | |
| 823 } | 799 } |
| 824 | 800 |
| 825 void SpdySession::RemoveFromPool() { | 801 void SpdySession::RemoveFromPool() { |
| 826 if (in_session_pool_) { | 802 if (in_session_pool_) { |
| 827 session_->spdy_session_pool()->Remove(this); | 803 session_->spdy_session_pool()->Remove(this); |
| 828 in_session_pool_ = false; | 804 in_session_pool_ = false; |
| 829 } | 805 } |
| 830 } | 806 } |
| 831 | 807 |
| 832 scoped_refptr<SpdyStream> SpdySession::GetActivePushStream( | 808 scoped_refptr<SpdyStream> SpdySession::GetActivePushStream( |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 885 } | 861 } |
| 886 | 862 |
| 887 bool SpdySession::Respond(const spdy::SpdyHeaderBlock& headers, | 863 bool SpdySession::Respond(const spdy::SpdyHeaderBlock& headers, |
| 888 const scoped_refptr<SpdyStream> stream) { | 864 const scoped_refptr<SpdyStream> stream) { |
| 889 int rv = OK; | 865 int rv = OK; |
| 890 | 866 |
| 891 rv = stream->OnResponseReceived(headers); | 867 rv = stream->OnResponseReceived(headers); |
| 892 if (rv < 0) { | 868 if (rv < 0) { |
| 893 DCHECK_NE(rv, ERR_IO_PENDING); | 869 DCHECK_NE(rv, ERR_IO_PENDING); |
| 894 const spdy::SpdyStreamId stream_id = stream->stream_id(); | 870 const spdy::SpdyStreamId stream_id = stream->stream_id(); |
| 895 CloseStream(stream_id, rv); | 871 DeleteStream(stream_id, rv); |
| 896 return false; | 872 return false; |
| 897 } | 873 } |
| 898 return true; | 874 return true; |
| 899 } | 875 } |
| 900 | 876 |
| 901 void SpdySession::OnSyn(const spdy::SpdySynStreamControlFrame& frame, | 877 void SpdySession::OnSyn(const spdy::SpdySynStreamControlFrame& frame, |
| 902 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { | 878 const linked_ptr<spdy::SpdyHeaderBlock>& headers) { |
| 903 spdy::SpdyStreamId stream_id = frame.stream_id(); | 879 spdy::SpdyStreamId stream_id = frame.stream_id(); |
| 904 | 880 |
| 905 LOG(INFO) << "Spdy SynStream for stream " << stream_id; | 881 LOG(INFO) << "Spdy SynStream for stream " << stream_id; |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1064 | 1040 |
| 1065 switch (type) { | 1041 switch (type) { |
| 1066 case spdy::GOAWAY: | 1042 case spdy::GOAWAY: |
| 1067 OnGoAway(*reinterpret_cast<const spdy::SpdyGoAwayControlFrame*>(frame)); | 1043 OnGoAway(*reinterpret_cast<const spdy::SpdyGoAwayControlFrame*>(frame)); |
| 1068 break; | 1044 break; |
| 1069 case spdy::SETTINGS: | 1045 case spdy::SETTINGS: |
| 1070 OnSettings( | 1046 OnSettings( |
| 1071 *reinterpret_cast<const spdy::SpdySettingsControlFrame*>(frame)); | 1047 *reinterpret_cast<const spdy::SpdySettingsControlFrame*>(frame)); |
| 1072 break; | 1048 break; |
| 1073 case spdy::RST_STREAM: | 1049 case spdy::RST_STREAM: |
| 1074 OnRst(*reinterpret_cast<const spdy::SpdyRstStreamControlFrame*>(frame)); | 1050 OnFin(*reinterpret_cast<const spdy::SpdyRstStreamControlFrame*>(frame)); |
| 1075 break; | 1051 break; |
| 1076 case spdy::SYN_STREAM: | 1052 case spdy::SYN_STREAM: |
| 1077 OnSyn(*reinterpret_cast<const spdy::SpdySynStreamControlFrame*>(frame), | 1053 OnSyn(*reinterpret_cast<const spdy::SpdySynStreamControlFrame*>(frame), |
| 1078 headers); | 1054 headers); |
| 1079 break; | 1055 break; |
| 1080 case spdy::SYN_REPLY: | 1056 case spdy::SYN_REPLY: |
| 1081 OnSynReply( | 1057 OnSynReply( |
| 1082 *reinterpret_cast<const spdy::SpdySynReplyControlFrame*>(frame), | 1058 *reinterpret_cast<const spdy::SpdySynReplyControlFrame*>(frame), |
| 1083 headers); | 1059 headers); |
| 1084 break; | 1060 break; |
| 1085 default: | 1061 default: |
| 1086 DCHECK(false); // Error! | 1062 DCHECK(false); // Error! |
| 1087 } | 1063 } |
| 1088 } | 1064 } |
| 1089 | 1065 |
| 1090 void SpdySession::OnRst(const spdy::SpdyRstStreamControlFrame& frame) { | 1066 void SpdySession::OnFin(const spdy::SpdyRstStreamControlFrame& frame) { |
| 1091 spdy::SpdyStreamId stream_id = frame.stream_id(); | 1067 spdy::SpdyStreamId stream_id = frame.stream_id(); |
| 1092 LOG(INFO) << "Spdy Fin for stream " << stream_id; | 1068 LOG(INFO) << "Spdy Fin for stream " << stream_id; |
| 1093 | 1069 |
| 1094 bool valid_stream = IsStreamActive(stream_id); | 1070 bool valid_stream = IsStreamActive(stream_id); |
| 1095 if (!valid_stream) { | 1071 if (!valid_stream) { |
| 1096 // NOTE: it may just be that the stream was cancelled. | 1072 // NOTE: it may just be that the stream was cancelled. |
| 1097 LOG(WARNING) << "Received FIN for invalid stream" << stream_id; | 1073 LOG(WARNING) << "Received FIN for invalid stream" << stream_id; |
| 1098 return; | 1074 return; |
| 1099 } | 1075 } |
| 1100 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 1076 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
| 1101 CHECK_EQ(stream->stream_id(), stream_id); | 1077 CHECK_EQ(stream->stream_id(), stream_id); |
| 1102 CHECK(!stream->cancelled()); | 1078 CHECK(!stream->cancelled()); |
| 1103 | 1079 |
| 1104 const BoundNetLog& log = stream->net_log(); | 1080 const BoundNetLog& log = stream->net_log(); |
| 1105 log.AddEvent( | 1081 log.AddEvent( |
| 1106 NetLog::TYPE_SPDY_STREAM_RST_STREAM, | 1082 NetLog::TYPE_SPDY_STREAM_RST_STREAM, |
| 1107 new NetLogIntegerParameter("status", frame.status())); | 1083 new NetLogIntegerParameter("status", frame.status())); |
| 1108 | 1084 |
| 1109 if (frame.status() == 0) { | 1085 if (frame.status() == 0) { |
| 1110 stream->OnDataReceived(NULL, 0); | 1086 stream->OnDataReceived(NULL, 0); |
| 1111 } else { | 1087 } else { |
| 1112 LOG(ERROR) << "Spdy stream closed: " << frame.status(); | 1088 LOG(ERROR) << "Spdy stream closed: " << frame.status(); |
| 1113 // TODO(mbelshe): Map from Spdy-protocol errors to something sensical. | 1089 // TODO(mbelshe): Map from Spdy-protocol errors to something sensical. |
| 1114 // For now, it doesn't matter much - it is a protocol error. | 1090 // For now, it doesn't matter much - it is a protocol error. |
| 1115 CloseStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); | 1091 DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); |
| 1116 } | 1092 } |
| 1117 } | 1093 } |
| 1118 | 1094 |
| 1119 void SpdySession::OnGoAway(const spdy::SpdyGoAwayControlFrame& frame) { | 1095 void SpdySession::OnGoAway(const spdy::SpdyGoAwayControlFrame& frame) { |
| 1120 LOG(INFO) << "Spdy GOAWAY for session[" << this << "] for " << | 1096 LOG(INFO) << "Spdy GOAWAY for session[" << this << "] for " << |
| 1121 host_port_pair().ToString(); | 1097 host_port_pair().ToString(); |
| 1122 | 1098 |
| 1123 net_log_.AddEvent( | 1099 net_log_.AddEvent( |
| 1124 NetLog::TYPE_SPDY_SESSION_GOAWAY, | 1100 NetLog::TYPE_SPDY_SESSION_GOAWAY, |
| 1125 new NetLogIntegerParameter( | 1101 new NetLogIntegerParameter( |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1212 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRetransRate", | 1188 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRetransRate", |
| 1213 setting.second, | 1189 setting.second, |
| 1214 1, 100, 50); | 1190 1, 100, 50); |
| 1215 break; | 1191 break; |
| 1216 } | 1192 } |
| 1217 } | 1193 } |
| 1218 } | 1194 } |
| 1219 } | 1195 } |
| 1220 | 1196 |
| 1221 } // namespace net | 1197 } // namespace net |
| OLD | NEW |