summaryrefslogtreecommitdiffstats
path: root/net/spdy
diff options
context:
space:
mode:
Diffstat (limited to 'net/spdy')
-rw-r--r--net/spdy/buffered_spdy_framer.cc48
-rw-r--r--net/spdy/buffered_spdy_framer.h65
-rw-r--r--net/spdy/buffered_spdy_framer_unittest.cc54
-rw-r--r--net/spdy/spdy_session.cc77
-rw-r--r--net/spdy/spdy_session.h37
5 files changed, 140 insertions, 141 deletions
diff --git a/net/spdy/buffered_spdy_framer.cc b/net/spdy/buffered_spdy_framer.cc
index cd10038..f2c037a 100644
--- a/net/spdy/buffered_spdy_framer.cc
+++ b/net/spdy/buffered_spdy_framer.cc
@@ -22,22 +22,52 @@ BufferedSpdyFramer::~BufferedSpdyFramer() {
void BufferedSpdyFramer::set_visitor(
BufferedSpdyFramerVisitorInterface* visitor) {
visitor_ = visitor;
- spdy_framer_.set_visitor(visitor);
+ spdy_framer_.set_visitor(this);
+}
+
+void BufferedSpdyFramer::OnError(spdy::SpdyFramer* /*framer*/) {
+ visitor_->OnError();
}
void BufferedSpdyFramer::OnControl(const SpdyControlFrame* frame) {
+ frames_received_++;
switch (frame->type()) {
case SYN_STREAM:
case SYN_REPLY:
case HEADERS:
InitHeaderStreaming(frame);
break;
- default:
- DCHECK(false); // Error!
+ case spdy::GOAWAY:
+ visitor_->OnGoAway(
+ *reinterpret_cast<const spdy::SpdyGoAwayControlFrame*>(frame));
+ break;
+ case spdy::PING:
+ visitor_->OnPing(
+ *reinterpret_cast<const spdy::SpdyPingControlFrame*>(frame));
+ break;
+ case spdy::SETTINGS:
+ visitor_->OnSettings(
+ *reinterpret_cast<const spdy::SpdySettingsControlFrame*>(frame));
+ break;
+ case spdy::RST_STREAM:
+ visitor_->OnRstStream(
+ *reinterpret_cast<const spdy::SpdyRstStreamControlFrame*>(frame));
break;
+ case spdy::WINDOW_UPDATE:
+ visitor_->OnWindowUpdate(
+ *reinterpret_cast<const spdy::SpdyWindowUpdateControlFrame*>(frame));
+ break;
+ default:
+ NOTREACHED(); // Error!
}
}
+bool BufferedSpdyFramer::OnCredentialFrameData(const char* frame_data,
+ size_t len) {
+ DCHECK(false);
+ return false;
+}
+
bool BufferedSpdyFramer::OnControlFrameHeaderData(SpdyStreamId stream_id,
const char* header_data,
size_t len) {
@@ -52,13 +82,14 @@ bool BufferedSpdyFramer::OnControlFrameHeaderData(SpdyStreamId stream_id,
header_buffer_, header_buffer_used_, headers.get());
if (!parsed_headers) {
LOG(WARNING) << "Could not parse Spdy Control Frame Header.";
+ visitor_->OnStreamError(stream_id);
return false;
}
SpdyControlFrame* control_frame =
reinterpret_cast<SpdyControlFrame*>(control_frame_.get());
switch (control_frame->type()) {
case SYN_STREAM:
- visitor_->OnSyn(
+ visitor_->OnSynStream(
*reinterpret_cast<const SpdySynStreamControlFrame*>(
control_frame), headers);
break;
@@ -82,6 +113,7 @@ bool BufferedSpdyFramer::OnControlFrameHeaderData(SpdyStreamId stream_id,
const size_t available = kHeaderBufferSize - header_buffer_used_;
if (len > available) {
header_buffer_valid_ = false;
+ visitor_->OnStreamError(stream_id);
return false;
}
memcpy(header_buffer_ + header_buffer_used_, header_data, len);
@@ -90,9 +122,17 @@ bool BufferedSpdyFramer::OnControlFrameHeaderData(SpdyStreamId stream_id,
}
void BufferedSpdyFramer::OnDataFrameHeader(const SpdyDataFrame* frame) {
+ frames_received_++;
header_stream_id_ = frame->stream_id();
}
+void BufferedSpdyFramer::OnStreamFrameData(SpdyStreamId stream_id,
+ const char* data,
+ size_t len) {
+ visitor_->OnStreamFrameData(stream_id, data, len);
+}
+
+
size_t BufferedSpdyFramer::ProcessInput(const char* data, size_t len) {
return spdy_framer_.ProcessInput(data, len);
}
diff --git a/net/spdy/buffered_spdy_framer.h b/net/spdy/buffered_spdy_framer.h
index be1069df5..b4f819d 100644
--- a/net/spdy/buffered_spdy_framer.h
+++ b/net/spdy/buffered_spdy_framer.h
@@ -16,15 +16,20 @@
namespace spdy {
-class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface
- : public SpdyFramerVisitorInterface {
+class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface {
public:
BufferedSpdyFramerVisitorInterface() {}
virtual ~BufferedSpdyFramerVisitorInterface() {}
+ // Called if an error is detected in the SpdyFrame protocol.
+ virtual void OnError() = 0;
+
+ // Called if an error is detected in a SPDY stream.
+ virtual void OnStreamError(spdy::SpdyStreamId stream_id) = 0;
+
// Called after all the header data for SYN_STREAM control frame is received.
- virtual void OnSyn(const SpdySynStreamControlFrame& frame,
- const linked_ptr<SpdyHeaderBlock>& headers) = 0;
+ virtual void OnSynStream(const SpdySynStreamControlFrame& frame,
+ const linked_ptr<SpdyHeaderBlock>& headers) = 0;
// Called after all the header data for SYN_REPLY control frame is received.
virtual void OnSynReply(const SpdySynReplyControlFrame& frame,
@@ -34,11 +39,37 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface
virtual void OnHeaders(const SpdyHeadersControlFrame& frame,
const linked_ptr<SpdyHeaderBlock>& headers) = 0;
+ // Called after a RST_STREAM frame is received.
+ virtual void OnRstStream(const spdy::SpdyRstStreamControlFrame& frame) = 0;
+
+ // Called after a GOAWAY frame is received.
+ virtual void OnGoAway(const spdy::SpdyGoAwayControlFrame& frame) = 0;
+
+ // Called after a PING frame is received.
+ virtual void OnPing(const spdy::SpdyPingControlFrame& frame) = 0;
+
+ // Called after a SETTINGS frame is received.
+ virtual void OnSettings(const spdy::SpdySettingsControlFrame& frame) = 0;
+
+ // Called after a WINDOW_UPDATE frame is received.
+ virtual void OnWindowUpdate(
+ const spdy::SpdyWindowUpdateControlFrame& frame) = 0;
+
+ // Called when data is received.
+ // |stream_id| The stream receiving data.
+ // |data| A buffer containing the data received.
+ // |len| The length of the data buffer.
+ // When the other side has finished sending data on this stream,
+ // this method will be called with a zero-length buffer.
+ virtual void OnStreamFrameData(SpdyStreamId stream_id,
+ const char* data,
+ size_t len) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramerVisitorInterface);
};
-class NET_EXPORT_PRIVATE BufferedSpdyFramer {
+class NET_EXPORT_PRIVATE BufferedSpdyFramer
+ : public SpdyFramerVisitorInterface {
public:
BufferedSpdyFramer();
virtual ~BufferedSpdyFramer();
@@ -49,15 +80,20 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer {
// visitor will be used.
void set_visitor(BufferedSpdyFramerVisitorInterface* visitor);
- void OnControl(const SpdyControlFrame* frame);
-
- bool OnControlFrameHeaderData(SpdyStreamId stream_id,
- const char* header_data,
- size_t len);
-
- void OnDataFrameHeader(const SpdyDataFrame* frame);
+ // SpdyFramerVisitorInterface
+ virtual void OnError(SpdyFramer* /*framer*/) OVERRIDE;
+ virtual void OnControl(const SpdyControlFrame* frame) OVERRIDE;
+ virtual bool OnCredentialFrameData(const char* frame_data,
+ size_t len) OVERRIDE;
+ virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id,
+ const char* header_data,
+ size_t len) OVERRIDE;
+ virtual void OnStreamFrameData(SpdyStreamId stream_id,
+ const char* data,
+ size_t len) OVERRIDE;
+ virtual void OnDataFrameHeader(const SpdyDataFrame* frame) OVERRIDE;
- // spdy_framer_ methods.
+ // SpdyFramer methods.
size_t ProcessInput(const char* data, size_t len);
void Reset();
SpdyFramer::SpdyError error_code() const;
@@ -86,6 +122,8 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer {
SpdyFrame* CompressFrame(const SpdyFrame& frame);
bool IsCompressible(const SpdyFrame& frame) const;
+ int frames_received() const { return frames_received_; }
+
private:
// The size of the header_buffer_.
enum { kHeaderBufferSize = 32 * 1024 };
@@ -101,6 +139,7 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer {
bool header_buffer_valid_;
SpdyStreamId header_stream_id_;
scoped_ptr<SpdyFrame> control_frame_;
+ int frames_received_;
DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramer);
};
diff --git a/net/spdy/buffered_spdy_framer_unittest.cc b/net/spdy/buffered_spdy_framer_unittest.cc
index d4cfb52..16b3d0b 100644
--- a/net/spdy/buffered_spdy_framer_unittest.cc
+++ b/net/spdy/buffered_spdy_framer_unittest.cc
@@ -18,34 +18,39 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface {
syn_frame_count_(0),
syn_reply_frame_count_(0),
headers_frame_count_(0),
- control_frame_header_data_count_(0),
- zero_length_control_frame_header_data_count_(0),
header_stream_id_(-1) {
}
- void OnError(SpdyFramer* f) {
- LOG(INFO) << "SpdyFramer Error: "
- << SpdyFramer::ErrorCodeToString(f->error_code());
+ void OnError() {
+ LOG(INFO) << "SpdyFramer Error";
error_count_++;
}
- void OnSyn(const SpdySynStreamControlFrame& frame,
+ void OnStreamError(spdy::SpdyStreamId stream_id) {
+ LOG(INFO) << "SpdyFramer Error on stream: " << stream_id;
+ error_count_++;
+ }
+
+ void OnSynStream(const SpdySynStreamControlFrame& frame,
const linked_ptr<SpdyHeaderBlock>& headers) {
- EXPECT_EQ(header_stream_id_, frame.stream_id());
+ header_stream_id_ = frame.stream_id();
+ EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
syn_frame_count_++;
headers_ = *headers;
}
void OnSynReply(const SpdySynReplyControlFrame& frame,
const linked_ptr<SpdyHeaderBlock>& headers) {
- EXPECT_EQ(header_stream_id_, frame.stream_id());
+ header_stream_id_ = frame.stream_id();
+ EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
syn_reply_frame_count_++;
headers_ = *headers;
}
void OnHeaders(const SpdyHeadersControlFrame& frame,
const linked_ptr<SpdyHeaderBlock>& headers) {
- EXPECT_EQ(header_stream_id_, frame.stream_id());
+ header_stream_id_ = frame.stream_id();
+ EXPECT_NE(header_stream_id_, SpdyFramer::kInvalidStream);
headers_frame_count_++;
headers_ = *headers;
}
@@ -80,22 +85,12 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface {
}
}
- bool OnControlFrameHeaderData(SpdyStreamId stream_id,
- const char* header_data,
- size_t len) {
- EXPECT_EQ(header_stream_id_, stream_id);
-
- bool result = buffered_spdy_framer_.OnControlFrameHeaderData(
- stream_id, header_data, len);
- EXPECT_TRUE(result);
-
- ++control_frame_header_data_count_;
-
- if (len == 0)
- ++zero_length_control_frame_header_data_count_;
-
- return true;
- }
+ void OnRstStream(const spdy::SpdyRstStreamControlFrame& frame) {}
+ void OnGoAway(const spdy::SpdyGoAwayControlFrame& frame) {}
+ void OnPing(const spdy::SpdyPingControlFrame& frame) {}
+ void OnSettings(const spdy::SpdySettingsControlFrame& frame) {}
+ void OnWindowUpdate(const spdy::SpdyWindowUpdateControlFrame& frame) {}
+ void OnCredential(const spdy::SpdyCredentialControlFrame& frame) {}
// Convenience function which runs a framer simulation with particular input.
void SimulateInFramer(const unsigned char* input, size_t size) {
@@ -126,9 +121,6 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface {
int syn_frame_count_;
int syn_reply_frame_count_;
int headers_frame_count_;
- int control_frame_header_data_count_; // The count of chunks received.
- // The count of zero-length control frame header data chunks received.
- int zero_length_control_frame_header_data_count_;
// Header block streaming state:
SpdyStreamId header_stream_id_;
@@ -200,8 +192,6 @@ TEST_F(BufferedSpdyFramerTest, ReadSynStreamHeaderBlock) {
reinterpret_cast<unsigned char*>(control_frame.get()->data()),
control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
EXPECT_EQ(0, visitor.error_count_);
- EXPECT_GT(visitor.control_frame_header_data_count_, 0);
- EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
EXPECT_EQ(1, visitor.syn_frame_count_);
EXPECT_EQ(0, visitor.syn_reply_frame_count_);
EXPECT_EQ(0, visitor.headers_frame_count_);
@@ -227,8 +217,6 @@ TEST_F(BufferedSpdyFramerTest, ReadSynReplyHeaderBlock) {
reinterpret_cast<unsigned char*>(control_frame.get()->data()),
control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
EXPECT_EQ(0, visitor.error_count_);
- EXPECT_GT(visitor.control_frame_header_data_count_, 0);
- EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
EXPECT_EQ(0, visitor.syn_frame_count_);
EXPECT_EQ(1, visitor.syn_reply_frame_count_);
EXPECT_EQ(0, visitor.headers_frame_count_);
@@ -254,8 +242,6 @@ TEST_F(BufferedSpdyFramerTest, ReadHeadersHeaderBlock) {
reinterpret_cast<unsigned char*>(control_frame.get()->data()),
control_frame.get()->length() + SpdyControlFrame::kHeaderSize);
EXPECT_EQ(0, visitor.error_count_);
- EXPECT_GT(visitor.control_frame_header_data_count_, 0);
- EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
EXPECT_EQ(0, visitor.syn_frame_count_);
EXPECT_EQ(0, visitor.syn_reply_frame_count_);
EXPECT_EQ(1, visitor.headers_frame_count_);
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index c16de27..61a2c15 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -295,7 +295,6 @@ SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair,
streams_pushed_count_(0),
streams_pushed_and_claimed_count_(0),
streams_abandoned_count_(0),
- frames_received_(0),
bytes_received_(0),
sent_settings_(false),
received_settings_(false),
@@ -1105,7 +1104,7 @@ Value* SpdySession::GetInfoAsValue() const {
dict->SetInteger("streams_pushed_and_claimed_count",
streams_pushed_and_claimed_count_);
dict->SetInteger("streams_abandoned_count", streams_abandoned_count_);
- dict->SetInteger("frames_received", frames_received_);
+ dict->SetInteger("frames_received", buffered_spdy_framer_.frames_received());
dict->SetBoolean("sent_settings", sent_settings_);
dict->SetBoolean("received_settings", received_settings_);
@@ -1230,10 +1229,15 @@ SSLClientCertType SpdySession::GetOriginBoundCertType() const {
return ssl_socket->origin_bound_cert_type();
}
-void SpdySession::OnError(spdy::SpdyFramer* framer) {
+void SpdySession::OnError() {
CloseSessionOnError(net::ERR_SPDY_PROTOCOL_ERROR, true);
}
+void SpdySession::OnStreamError(spdy::SpdyStreamId stream_id) {
+ if (IsStreamActive(stream_id))
+ ResetStream(stream_id, spdy::PROTOCOL_ERROR, "");
+}
+
void SpdySession::OnStreamFrameData(spdy::SpdyStreamId stream_id,
const char* data,
size_t len) {
@@ -1267,8 +1271,9 @@ bool SpdySession::Respond(const spdy::SpdyHeaderBlock& headers,
return true;
}
-void SpdySession::OnSyn(const spdy::SpdySynStreamControlFrame& frame,
- const linked_ptr<spdy::SpdyHeaderBlock>& headers) {
+void SpdySession::OnSynStream(
+ const spdy::SpdySynStreamControlFrame& frame,
+ const linked_ptr<spdy::SpdyHeaderBlock>& headers) {
spdy::SpdyStreamId stream_id = frame.stream_id();
spdy::SpdyStreamId associated_stream_id = frame.associated_stream_id();
@@ -1438,67 +1443,7 @@ void SpdySession::OnHeaders(const spdy::SpdyHeadersControlFrame& frame,
}
}
-void SpdySession::OnControl(const spdy::SpdyControlFrame* frame) {
- uint32 type = frame->type();
- if (type == spdy::SYN_STREAM ||
- type == spdy::SYN_REPLY ||
- type == spdy::HEADERS) {
- buffered_spdy_framer_.OnControl(frame);
- return;
- }
-
- frames_received_++;
-
- switch (type) {
- case spdy::GOAWAY:
- OnGoAway(*reinterpret_cast<const spdy::SpdyGoAwayControlFrame*>(frame));
- break;
- case spdy::PING:
- OnPing(*reinterpret_cast<const spdy::SpdyPingControlFrame*>(frame));
- break;
- case spdy::SETTINGS:
- OnSettings(
- *reinterpret_cast<const spdy::SpdySettingsControlFrame*>(frame));
- break;
- case spdy::RST_STREAM:
- OnRst(*reinterpret_cast<const spdy::SpdyRstStreamControlFrame*>(frame));
- break;
- case spdy::WINDOW_UPDATE:
- OnWindowUpdate(
- *reinterpret_cast<const spdy::SpdyWindowUpdateControlFrame*>(frame));
- break;
- default:
- DCHECK(false); // Error!
- }
-}
-
-bool SpdySession::OnControlFrameHeaderData(spdy::SpdyStreamId stream_id,
- const char* header_data,
- size_t len) {
- if (!buffered_spdy_framer_.OnControlFrameHeaderData(
- stream_id, header_data, len)) {
- if (IsStreamActive(stream_id))
- ResetStream(stream_id, spdy::PROTOCOL_ERROR, "");
- return false;
- }
- if (len == 0) {
- // Indicates end-of-header-block.
- frames_received_++;
- }
- return true;
-}
-
-bool SpdySession::OnCredentialFrameData(const char* frame_data,
- size_t len) {
- DCHECK(false);
- return false;
-}
-
-void SpdySession::OnDataFrameHeader(const spdy::SpdyDataFrame* frame) {
- buffered_spdy_framer_.OnDataFrameHeader(frame);
-}
-
-void SpdySession::OnRst(const spdy::SpdyRstStreamControlFrame& frame) {
+void SpdySession::OnRstStream(const spdy::SpdyRstStreamControlFrame& frame) {
spdy::SpdyStreamId stream_id = frame.stream_id();
net_log().AddEvent(
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index 5256501..92af8b6 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -231,7 +231,7 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
// Indicates whether the session is being reused after having successfully
// used to send/receive data in the past.
bool IsReused() const {
- return frames_received_ > 0;
+ return buffered_spdy_framer_.frames_received() > 0;
}
// Returns true if the underlying transport socket ever had any reads or
@@ -333,14 +333,6 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
scoped_refptr<SpdyStream>* spdy_stream,
const BoundNetLog& stream_net_log);
- // Control frame handlers.
- void OnRst(const spdy::SpdyRstStreamControlFrame& frame);
- void OnGoAway(const spdy::SpdyGoAwayControlFrame& frame);
- void OnPing(const spdy::SpdyPingControlFrame& frame);
- void OnSettings(const spdy::SpdySettingsControlFrame& frame);
- void OnWindowUpdate(const spdy::SpdyWindowUpdateControlFrame& frame);
- void OnCredential(const spdy::SpdyCredentialControlFrame& frame);
-
// IO Callbacks
void OnReadComplete(int result);
void OnWriteComplete(int result);
@@ -427,23 +419,21 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
void InvokeUserStreamCreationCallback(scoped_refptr<SpdyStream>* stream);
// BufferedSpdyFramerVisitorInterface:
- virtual void OnError(spdy::SpdyFramer*) OVERRIDE;
+ virtual void OnError() OVERRIDE;
+ virtual void OnStreamError(spdy::SpdyStreamId stream_id) OVERRIDE;
+ virtual void OnRstStream(
+ const spdy::SpdyRstStreamControlFrame& frame) OVERRIDE;
+ virtual void OnGoAway(const spdy::SpdyGoAwayControlFrame& frame) OVERRIDE;
+ virtual void OnPing(const spdy::SpdyPingControlFrame& frame) OVERRIDE;
+ virtual void OnSettings(const spdy::SpdySettingsControlFrame& frame) OVERRIDE;
+ virtual void OnWindowUpdate(
+ const spdy::SpdyWindowUpdateControlFrame& frame) OVERRIDE;
virtual void OnStreamFrameData(spdy::SpdyStreamId stream_id,
const char* data,
size_t len) OVERRIDE;
- virtual void OnControl(const spdy::SpdyControlFrame* frame) OVERRIDE;
-
- virtual bool OnControlFrameHeaderData(spdy::SpdyStreamId stream_id,
- const char* header_data,
- size_t len) OVERRIDE;
-
- virtual bool OnCredentialFrameData(const char* frame_data,
- size_t len) OVERRIDE;
-
- virtual void OnDataFrameHeader(const spdy::SpdyDataFrame* frame) OVERRIDE;
-
- virtual void OnSyn(const spdy::SpdySynStreamControlFrame& frame,
- const linked_ptr<spdy::SpdyHeaderBlock>& headers) OVERRIDE;
+ virtual void OnSynStream(
+ const spdy::SpdySynStreamControlFrame& frame,
+ const linked_ptr<spdy::SpdyHeaderBlock>& headers) OVERRIDE;
virtual void OnSynReply(
const spdy::SpdySynReplyControlFrame& frame,
const linked_ptr<spdy::SpdyHeaderBlock>& headers) OVERRIDE;
@@ -563,7 +553,6 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>,
int streams_pushed_count_;
int streams_pushed_and_claimed_count_;
int streams_abandoned_count_;
- int frames_received_;
int bytes_received_;
bool sent_settings_; // Did this session send settings when it started.
bool received_settings_; // Did this session receive at least one settings