diff options
-rw-r--r-- | net/spdy/spdy_framer.cc | 13 | ||||
-rw-r--r-- | net/spdy/spdy_framer_test.cc | 4 | ||||
-rw-r--r-- | net/spdy/spdy_network_transaction.h | 3 | ||||
-rw-r--r-- | net/spdy/spdy_network_transaction_unittest.cc | 121 | ||||
-rw-r--r-- | net/spdy/spdy_protocol.h | 8 | ||||
-rw-r--r-- | net/spdy/spdy_session.cc | 48 | ||||
-rw-r--r-- | net/spdy/spdy_session.h | 14 | ||||
-rw-r--r-- | net/spdy/spdy_stream.cc | 17 | ||||
-rw-r--r-- | net/spdy/spdy_stream.h | 9 | ||||
-rw-r--r-- | net/spdy/spdy_test_util.cc | 16 | ||||
-rw-r--r-- | net/spdy/spdy_test_util.h | 10 |
11 files changed, 13 insertions, 250 deletions
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc index 7a0d152..bb5d0fe 100644 --- a/net/spdy/spdy_framer.cc +++ b/net/spdy/spdy_framer.cc @@ -304,11 +304,6 @@ void SpdyFramer::ProcessControlFrameHeader() { SpdySettingsControlFrame::size() - SpdyControlFrame::size()) set_error(SPDY_INVALID_CONTROL_FRAME); break; - case WINDOW_UPDATE: - if (current_control_frame.length() != - SpdyWindowUpdateControlFrame::size() - SpdyFrame::size()) - set_error(SPDY_INVALID_CONTROL_FRAME); - break; default: LOG(WARNING) << "Valid spdy control frame with unknown type: " << current_control_frame.type(); @@ -317,6 +312,12 @@ void SpdyFramer::ProcessControlFrameHeader() { break; } + // We only support version 1 of this protocol. + if (current_control_frame.version() != kSpdyProtocolVersion) { + set_error(SPDY_UNSUPPORTED_VERSION); + return; + } + remaining_control_payload_ = current_control_frame.length(); if (remaining_control_payload_ > kControlFrameBufferMaxSize) { set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); @@ -591,7 +592,7 @@ SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate( DCHECK_GT(stream_id, 0u); DCHECK_EQ(0u, stream_id & ~kStreamIdMask); DCHECK_GT(delta_window_size, 0u); - DCHECK_LT(delta_window_size, 0x80000000u); // 2^31 + DCHECK_LE(delta_window_size, 0x80000000u); // 2^31 SpdyFrameBuilder frame; frame.WriteUInt16(kControlFlagMask | kSpdyProtocolVersion); diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc index 4e976ab..5791a67 100644 --- a/net/spdy/spdy_framer_test.cc +++ b/net/spdy/spdy_framer_test.cc @@ -1173,9 +1173,9 @@ TEST_F(SpdyFramerTest, CreateWindowUpdate) { 0x80, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, - 0x7f, 0xff, 0xff, 0xff, + 0x80, 0x00, 0x00, 0x00, }; - scoped_ptr<SpdyFrame> frame(framer.CreateWindowUpdate(1, 0x7FFFFFFF)); + scoped_ptr<SpdyFrame> frame(framer.CreateWindowUpdate(1, 0x80000000)); CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData)); } } diff --git a/net/spdy/spdy_network_transaction.h b/net/spdy/spdy_network_transaction.h index a770a82..12b055c 100644 --- a/net/spdy/spdy_network_transaction.h +++ b/net/spdy/spdy_network_transaction.h @@ -53,9 +53,6 @@ class SpdyNetworkTransaction : public HttpTransaction { virtual uint64 GetUploadProgress() const; private: - FRIEND_TEST(SpdyNetworkTransactionTest, WindowUpdate); - FRIEND_TEST(SpdyNetworkTransactionTest, WindowUpdateOverflow); - enum State { STATE_INIT_CONNECTION, STATE_INIT_CONNECTION_COMPLETE, diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index 82b762d..5235427 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc @@ -21,7 +21,6 @@ #include "net/spdy/spdy_framer.h" #include "net/spdy/spdy_http_stream.h" #include "net/spdy/spdy_protocol.h" -#include "net/spdy/spdy_session.h" #include "net/spdy/spdy_test_util.h" #include "testing/platform_test.h" @@ -334,126 +333,6 @@ TEST_F(SpdyNetworkTransactionTest, ResponseWithoutSynReply) { EXPECT_EQ(ERR_SYN_REPLY_NOT_RECEIVED, out.rv); } -// Test that WINDOW_UPDATE frames change window_size correctly. -TEST_F(SpdyNetworkTransactionTest, WindowUpdate) { - SessionDependencies session_deps; - HttpNetworkSession* session = CreateSession(&session_deps); - - // We disable SSL for this test. - SpdySession::SetSSLMode(false); - - // Setup the request - static const char upload[] = { "hello!" }; - HttpRequestInfo request; - request.method = "POST"; - request.url = GURL("http://www.google.com/"); - request.upload_data = new UploadData(); - request.upload_data->AppendBytes(upload, strlen(upload)); - - scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost(NULL, 0)); - scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame()); - MockWrite writes[] = { - CreateMockWrite(*req), - CreateMockWrite(*body), - MockWrite(true, 0, 0) - }; - - // Response frames, send WINDOW_UPDATE first - static const int kDeltaWindowSize = 0xff; - scoped_ptr<spdy::SpdyFrame> window_update( - ConstructSpdyWindowUpdate(1, kDeltaWindowSize)); - scoped_ptr<spdy::SpdyFrame> reply(ConstructSpdyPostSynReply(NULL, 0)); - MockRead reads[] = { - CreateMockRead(*window_update), - CreateMockRead(*reply), - CreateMockRead(*body), - MockRead(true, 0, 0) // EOF - }; - - scoped_refptr<DelayedSocketData> data( - new DelayedSocketData(2, reads, arraysize(reads), - writes, arraysize(writes))); - session_deps.socket_factory.AddSocketDataProvider(data.get()); - - scoped_ptr<SpdyNetworkTransaction> trans( - new SpdyNetworkTransaction(session)); - - TestCompletionCallback callback; - int rv = trans->Start(&request, &callback, BoundNetLog()); - - ASSERT_TRUE(trans->stream_ != NULL); - ASSERT_TRUE(trans->stream_->stream() != NULL); - EXPECT_EQ(kInitialWindowSize, trans->stream_->stream()->window_size()); - - EXPECT_EQ(ERR_IO_PENDING, rv); - rv = callback.WaitForResult(); - EXPECT_EQ(OK, rv); - - ASSERT_TRUE(trans->stream_ != NULL); - ASSERT_TRUE(trans->stream_->stream() != NULL); - EXPECT_EQ(kInitialWindowSize + kDeltaWindowSize, - trans->stream_->stream()->window_size()); -} - -// Test that WINDOW_UPDATE frame causing overflow is handled correctly. -TEST_F(SpdyNetworkTransactionTest, WindowUpdateOverflow) { - SessionDependencies session_deps; - HttpNetworkSession* session = CreateSession(&session_deps); - - // We disable SSL for this test. - SpdySession::SetSSLMode(false); - - // Setup the request - static const char upload[] = { "hello!" }; - HttpRequestInfo request; - request.method = "POST"; - request.url = GURL("http://www.google.com/"); - request.upload_data = new UploadData(); - request.upload_data->AppendBytes(upload, strlen(upload)); - - scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyPost(NULL, 0)); - scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame()); - scoped_ptr<spdy::SpdyFrame> rst( - ConstructSpdyRstStream(1, spdy::FLOW_CONTROL_ERROR)); - MockWrite writes[] = { - CreateMockWrite(*req), - CreateMockWrite(*body), - CreateMockWrite(*rst), - }; - - // Response frames, send WINDOW_UPDATE first - static const int kDeltaWindowSize = 0x7fffffff; // cause an overflow - scoped_ptr<spdy::SpdyFrame> window_update( - ConstructSpdyWindowUpdate(1, kDeltaWindowSize)); - scoped_ptr<spdy::SpdyFrame> reply(ConstructSpdyPostSynReply(NULL, 0)); - MockRead reads[] = { - CreateMockRead(*window_update), - CreateMockRead(*reply), - CreateMockRead(*body), - MockRead(true, 0, 0) // EOF - }; - - scoped_refptr<DelayedSocketData> data( - new DelayedSocketData(2, reads, arraysize(reads), - writes, arraysize(writes))); - session_deps.socket_factory.AddSocketDataProvider(data.get()); - - scoped_ptr<SpdyNetworkTransaction> trans( - new SpdyNetworkTransaction(session)); - - TestCompletionCallback callback; - int rv = trans->Start(&request, &callback, BoundNetLog()); - - ASSERT_TRUE(trans->stream_ != NULL); - ASSERT_TRUE(trans->stream_->stream() != NULL); - EXPECT_EQ(kInitialWindowSize, trans->stream_->stream()->window_size()); - - EXPECT_EQ(ERR_IO_PENDING, rv); - rv = callback.WaitForResult(); - - EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv); -} - // Test that the transaction doesn't crash when we get two replies on the same // stream ID. See http://crbug.com/45639. TEST_F(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { diff --git a/net/spdy/spdy_protocol.h b/net/spdy/spdy_protocol.h index f02db45..49d8bdc 100644 --- a/net/spdy/spdy_protocol.h +++ b/net/spdy/spdy_protocol.h @@ -184,8 +184,7 @@ enum SpdyStatusCodes { UNSUPPORTED_VERSION = 4, CANCEL = 5, INTERNAL_ERROR = 6, - FLOW_CONTROL_ERROR = 7, - NUM_STATUS_CODES = 8 + NUM_STATUS_CODES = 7 }; // A SPDY stream id is a 31 bit entity. @@ -404,8 +403,9 @@ class SpdyControlFrame : public SpdyFrame { } void set_version(uint16 version) { - DCHECK_EQ(0u, version & kControlFlagMask); - mutable_block()->control_.version_ = htons(kControlFlagMask | version); + const uint16 kControlBit = 0x80; + DCHECK_EQ(0, version & kControlBit); + mutable_block()->control_.version_ = kControlBit | htons(version); } SpdyControlType type() const { diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index 37ceb57..13a54d5 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc @@ -163,7 +163,6 @@ SpdySession::SpdySession(const HostPortPair& host_port_pair, sent_settings_(false), received_settings_(false), in_session_pool_(true), - initial_window_size_(kInitialWindowSize), net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)) { net_log_.BeginEvent( NetLog::TYPE_SPDY_SESSION, @@ -313,7 +312,6 @@ int SpdySession::CreateStream( stream->set_priority(priority); stream->set_path(path); stream->set_net_log(stream_net_log); - stream->set_window_size(initial_window_size_); ActivateStream(stream); UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdyPriorityCount", @@ -404,21 +402,6 @@ void SpdySession::CloseStream(spdy::SpdyStreamId stream_id, int status) { DeleteStream(stream_id, status); } -void SpdySession::ResetStream( - spdy::SpdyStreamId stream_id, spdy::SpdyStatusCodes status) { - LOG(INFO) << "Resetting stream " << stream_id << " with status " << status; - - DCHECK(IsStreamActive(stream_id)); - const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id]; - CHECK_EQ(stream->stream_id(), stream_id); - - scoped_ptr<spdy::SpdyRstStreamControlFrame> rst_frame( - spdy_framer_.CreateRstStream(stream_id, status)); - QueueFrame(rst_frame.get(), stream->priority(), stream); - - DeleteStream(stream_id, ERR_SPDY_PROTOCOL_ERROR); -} - bool SpdySession::IsStreamActive(spdy::SpdyStreamId stream_id) const { return ContainsKey(active_streams_, stream_id); } @@ -1078,10 +1061,6 @@ void SpdySession::OnControl(const spdy::SpdyControlFrame* frame) { *reinterpret_cast<const spdy::SpdySynReplyControlFrame*>(frame), headers); break; - case spdy::WINDOW_UPDATE: - OnWindowUpdate( - *reinterpret_cast<const spdy::SpdyWindowUpdateControlFrame*>(frame)); - break; default: DCHECK(false); // Error! } @@ -1143,8 +1122,6 @@ void SpdySession::OnSettings(const spdy::SpdySettingsControlFrame& frame) { settings_storage->Set(host_port_pair_, settings); } - // TODO(agayev): Implement initial and per stream window size update. - received_settings_ = true; net_log_.AddEvent( @@ -1152,31 +1129,6 @@ void SpdySession::OnSettings(const spdy::SpdySettingsControlFrame& frame) { new NetLogSpdySettingsParameter(settings)); } -void SpdySession::OnWindowUpdate( - const spdy::SpdyWindowUpdateControlFrame& frame) { - spdy::SpdyStreamId stream_id = frame.stream_id(); - LOG(INFO) << "Spdy WINDOW_UPDATE for stream " << stream_id; - - if (!IsStreamActive(stream_id)) { - LOG(WARNING) << "Received WINDOW_UPDATE for invalid stream " << stream_id; - return; - } - - int delta_window_size = static_cast<int>(frame.delta_window_size()); - if (delta_window_size < 1) { - LOG(WARNING) << "Received WINDOW_UPDATE with an invalid delta_window_size " - << delta_window_size; - return; - // TODO(agayev): Send RST_STREAM with status code FLOW_CONTROL_ERROR? - } - - const scoped_refptr<SpdyStream>& stream = active_streams_[stream_id]; - CHECK_EQ(stream->stream_id(), stream_id); - CHECK(!stream->cancelled()); - - stream->UpdateWindowSize(delta_window_size); -} - void SpdySession::SendSettings() { const SpdySettingsStorage& settings_storage = session_->spdy_settings(); const spdy::SpdySettings& settings = settings_storage.Get(host_port_pair_); diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h index 41ab927..e129d57 100644 --- a/net/spdy/spdy_session.h +++ b/net/spdy/spdy_session.h @@ -36,9 +36,6 @@ class HttpNetworkSession; class BoundNetLog; class SSLInfo; -// default initial window size per SPDY protocol draft 2 -static const int kInitialWindowSize = 64 * 1024; - class SpdySession : public base::RefCounted<SpdySession>, public spdy::SpdyFramerVisitorInterface { public: @@ -97,11 +94,6 @@ class SpdySession : public base::RefCounted<SpdySession>, // Close a stream. void CloseStream(spdy::SpdyStreamId stream_id, int status); - // Reset a stream by sending a RST_STREAM frame with given status code. - // Also closes the stream. Was not piggybacked to CloseStream since not - // all of the calls to CloseStream necessitate sending a RST_STREAM. - void ResetStream(spdy::SpdyStreamId stream_id, spdy::SpdyStatusCodes status); - // Check if a stream is active. bool IsStreamActive(spdy::SpdyStreamId stream_id) const; @@ -159,7 +151,6 @@ class SpdySession : public base::RefCounted<SpdySession>, void OnFin(const spdy::SpdyRstStreamControlFrame& frame); void OnGoAway(const spdy::SpdyGoAwayControlFrame& frame); void OnSettings(const spdy::SpdySettingsControlFrame& frame); - void OnWindowUpdate(const spdy::SpdyWindowUpdateControlFrame& frame); // IO Callbacks void OnTCPConnect(int result); @@ -289,11 +280,6 @@ class SpdySession : public base::RefCounted<SpdySession>, bool in_session_pool_; // True if the session is currently in the pool. - int initial_window_size_; // Initial window size for the session; can be - // changed by an arriving SETTINGS frame; newly - // created streams use this value for the initial - // window size. - BoundNetLog net_log_; static bool use_ssl_; diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc index 29fb10a..3d68d5d 100644 --- a/net/spdy/spdy_stream.cc +++ b/net/spdy/spdy_stream.cc @@ -71,23 +71,6 @@ void SpdyStream::set_spdy_headers( request_ = headers; } -void SpdyStream::UpdateWindowSize(int delta_window_size) { - DCHECK_GE(delta_window_size, 1); - int new_window_size = window_size_ + delta_window_size; - - // it's valid for window_size_ to become negative (via an incoming - // SETTINGS frame which is handled in SpdySession::OnSettings), in which - // case incoming WINDOW_UPDATEs will eventually make it positive; - // however, if window_size_ is positive and incoming WINDOW_UPDATE makes - // it negative, we have an overflow. - if (window_size_ > 0 && new_window_size < 0) { - LOG(WARNING) << "Received WINDOW_UPDATE overflows the window size"; - session_->ResetStream(stream_id_, spdy::FLOW_CONTROL_ERROR); - return; - } - window_size_ = new_window_size; -} - base::Time SpdyStream::GetRequestTime() const { return request_time_; } diff --git a/net/spdy/spdy_stream.h b/net/spdy/spdy_stream.h index 01b867a..6183be2 100644 --- a/net/spdy/spdy_stream.h +++ b/net/spdy/spdy_stream.h @@ -100,14 +100,6 @@ class SpdyStream : public base::RefCounted<SpdyStream> { int priority() const { return priority_; } void set_priority(int priority) { priority_ = priority; } - int window_size() const { return window_size_; } - void set_window_size(int window_size) { window_size_ = window_size; } - - // Updates |window_size_| with delta extracted from a WINDOW_UPDATE - // frame; sends a RST_STREAM if delta overflows |window_size_| and - // removes the stream from the session. - void UpdateWindowSize(int delta_window_size); - const BoundNetLog& net_log() const { return net_log_; } void set_net_log(const BoundNetLog& log) { net_log_ = log; } @@ -205,7 +197,6 @@ class SpdyStream : public base::RefCounted<SpdyStream> { spdy::SpdyStreamId stream_id_; std::string path_; int priority_; - int window_size_; const bool pushed_; ScopedBandwidthMetrics metrics_; bool syn_reply_received_; diff --git a/net/spdy/spdy_test_util.cc b/net/spdy/spdy_test_util.cc index 87da61b..697a3a6 100644 --- a/net/spdy/spdy_test_util.cc +++ b/net/spdy/spdy_test_util.cc @@ -190,22 +190,6 @@ spdy::SpdyFrame* ConstructSpdyGoAway() { return framer.CreateGoAway(0); } -// Construct a SPDY WINDOW_UPDATE frame. -// Returns the constructed frame. The caller takes ownership of the frame. -spdy::SpdyFrame* ConstructSpdyWindowUpdate( - const spdy::SpdyStreamId stream_id, uint32 delta_window_size) { - spdy::SpdyFramer framer; - return framer.CreateWindowUpdate(stream_id, delta_window_size); -} - -// Construct a SPDY RST_STREAM frame. -// Returns the constructed frame. The caller takes ownership of the frame. -spdy::SpdyFrame* ConstructSpdyRstStream(spdy::SpdyStreamId stream_id, - spdy::SpdyStatusCodes status) { - spdy::SpdyFramer framer; - return framer.CreateRstStream(stream_id, status); -} - // Construct a single SPDY header entry, for validation. // |extra_headers| are the extra header-value pairs. // |buffer| is the buffer we're filling in. diff --git a/net/spdy/spdy_test_util.h b/net/spdy/spdy_test_util.h index 880c4ff..02981ce 100644 --- a/net/spdy/spdy_test_util.h +++ b/net/spdy/spdy_test_util.h @@ -120,16 +120,6 @@ spdy::SpdyFrame* ConstructSpdySettings(spdy::SpdySettings settings); // Returns the constructed frame. The caller takes ownership of the frame. spdy::SpdyFrame* ConstructSpdyGoAway(); -// Construct a SPDY WINDOW_UPDATE frame. -// Returns the constructed frame. The caller takes ownership of the frame. -spdy::SpdyFrame* ConstructSpdyWindowUpdate(spdy::SpdyStreamId, - uint32 delta_window_size); - -// Construct a SPDY RST_STREAM frame. -// Returns the constructed frame. The caller takes ownership of the frame. -spdy::SpdyFrame* ConstructSpdyRstStream(spdy::SpdyStreamId stream_id, - spdy::SpdyStatusCodes status); - // Construct a single SPDY header entry, for validation. // |extra_headers| are the extra header-value pairs. // |buffer| is the buffer we're filling in. |