diff options
Diffstat (limited to 'net/spdy/spdy_session.cc')
-rw-r--r-- | net/spdy/spdy_session.cc | 95 |
1 files changed, 73 insertions, 22 deletions
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index 2c79c45..a134b98 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc @@ -31,8 +31,12 @@ namespace net { NetLogSpdySynParameter::NetLogSpdySynParameter( const linked_ptr<spdy::SpdyHeaderBlock>& headers, spdy::SpdyControlFlags flags, - spdy::SpdyStreamId id) - : headers_(headers), flags_(flags), id_(id) { + spdy::SpdyStreamId id, + spdy::SpdyStreamId associated_stream) + : headers_(headers), + flags_(flags), + id_(id), + associated_stream_(associated_stream) { } NetLogSpdySynParameter::~NetLogSpdySynParameter() { @@ -49,6 +53,8 @@ Value* NetLogSpdySynParameter::ToValue() const { dict->SetInteger("flags", flags_); dict->Set("headers", headers_list); dict->SetInteger("id", id_); + if (associated_stream_) + dict->SetInteger("associated_stream", associated_stream_); return dict; } @@ -242,8 +248,8 @@ SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair, frames_received_(0), sent_settings_(false), received_settings_(false), - initial_send_window_size_(spdy::kInitialWindowSize), - initial_recv_window_size_(spdy::kInitialWindowSize), + initial_send_window_size_(spdy::kSpdyStreamInitialWindowSize), + initial_recv_window_size_(spdy::kSpdyStreamInitialWindowSize), net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)) { DCHECK(HttpStreamFactory::spdy_enabled()); net_log_.BeginEvent( @@ -320,9 +326,7 @@ int SpdySession::GetPushStream( return ERR_SPDY_PROTOCOL_ERROR; } - const std::string& path = url.PathForRequest(); - - *stream = GetActivePushStream(path); + *stream = GetActivePushStream(url.spec()); if (stream->get()) { DCHECK(streams_pushed_and_claimed_count_ < streams_pushed_count_); streams_pushed_and_claimed_count_++; @@ -470,7 +474,7 @@ int SpdySession::WriteSynStream( net_log().AddEvent( NetLog::TYPE_SPDY_SESSION_SYN_STREAM, make_scoped_refptr( - new NetLogSpdySynParameter(headers, flags, stream_id))); + new NetLogSpdySynParameter(headers, flags, stream_id, 0))); } return ERR_IO_PENDING; @@ -995,7 +999,6 @@ void SpdySession::OnStreamFrameData(spdy::SpdyStreamId stream_id, bool SpdySession::Respond(const spdy::SpdyHeaderBlock& headers, const scoped_refptr<SpdyStream> stream) { int rv = OK; - rv = stream->OnResponseReceived(headers); if (rv < 0) { DCHECK_NE(rv, ERR_IO_PENDING); @@ -1016,7 +1019,7 @@ void SpdySession::OnSyn(const spdy::SpdySynStreamControlFrame& frame, NetLog::TYPE_SPDY_SESSION_PUSHED_SYN_STREAM, make_scoped_refptr(new NetLogSpdySynParameter( headers, static_cast<spdy::SpdyControlFlags>(frame.flags()), - stream_id))); + stream_id, associated_stream_id))); } // Server-initiated streams should have even sequence numbers. @@ -1042,13 +1045,20 @@ void SpdySession::OnSyn(const spdy::SpdySynStreamControlFrame& frame, // TODO(mbelshe): DCHECK that this is a GET method? - const std::string& path = ContainsKey(*headers, "path") ? - headers->find("path")->second : ""; + const std::string& url = ContainsKey(*headers, "url") ? + headers->find("url")->second : ""; // Verify that the response had a URL for us. - if (path.empty()) { + if (url.empty()) { + ResetStream(stream_id, spdy::PROTOCOL_ERROR); + LOG(WARNING) << "Pushed stream did not contain a url."; + return; + } + + GURL gurl(url); + if (!gurl.is_valid()) { ResetStream(stream_id, spdy::PROTOCOL_ERROR); - LOG(WARNING) << "Pushed stream did not contain a path."; + LOG(WARNING) << "Pushed stream url was invalid: " << url; return; } @@ -1062,9 +1072,9 @@ void SpdySession::OnSyn(const spdy::SpdySynStreamControlFrame& frame, // TODO(erikchen): Actually do something with the associated id. // There should not be an existing pushed stream with the same path. - PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(path); + PushedStreamMap::iterator it = unclaimed_pushed_streams_.find(url); if (it != unclaimed_pushed_streams_.end()) { - LOG(ERROR) << "Received duplicate pushed stream with path: " << path; + LOG(ERROR) << "Received duplicate pushed stream with url: " << url; ResetStream(stream_id, spdy::PROTOCOL_ERROR); return; } @@ -1072,9 +1082,9 @@ void SpdySession::OnSyn(const spdy::SpdySynStreamControlFrame& frame, scoped_refptr<SpdyStream> stream( new SpdyStream(this, stream_id, true, net_log_)); - stream->set_path(path); + stream->set_path(gurl.PathForRequest()); - unclaimed_pushed_streams_[path] = stream; + unclaimed_pushed_streams_[url] = stream; ActivateStream(stream); stream->set_response_received(); @@ -1114,25 +1124,62 @@ void SpdySession::OnSynReply(const spdy::SpdySynReplyControlFrame& frame, NetLog::TYPE_SPDY_SESSION_SYN_REPLY, make_scoped_refptr(new NetLogSpdySynParameter( headers, static_cast<spdy::SpdyControlFlags>(frame.flags()), - stream_id))); + stream_id, 0))); } Respond(*headers, stream); } +void SpdySession::OnHeaders(const spdy::SpdyHeadersControlFrame& frame, + const linked_ptr<spdy::SpdyHeaderBlock>& headers) { + spdy::SpdyStreamId stream_id = frame.stream_id(); + + bool valid_stream = IsStreamActive(stream_id); + if (!valid_stream) { + // NOTE: it may just be that the stream was cancelled. + LOG(WARNING) << "Received HEADERS for invalid stream " << stream_id; + return; + } + + scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; + CHECK_EQ(stream->stream_id(), stream_id); + CHECK(!stream->cancelled()); + + if (net_log().IsLoggingAllEvents()) { + net_log().AddEvent( + NetLog::TYPE_SPDY_SESSION_HEADERS, + make_scoped_refptr(new NetLogSpdySynParameter( + headers, static_cast<spdy::SpdyControlFlags>(frame.flags()), + stream_id, 0))); + } + + int rv = stream->OnHeaders(*headers); + if (rv < 0) { + DCHECK_NE(rv, ERR_IO_PENDING); + const spdy::SpdyStreamId stream_id = stream->stream_id(); + DeleteStream(stream_id, rv); + } +} + void SpdySession::OnControl(const spdy::SpdyControlFrame* frame) { const linked_ptr<spdy::SpdyHeaderBlock> headers(new spdy::SpdyHeaderBlock); uint32 type = frame->type(); - if (type == spdy::SYN_STREAM || type == spdy::SYN_REPLY) { + if (type == spdy::SYN_STREAM || + type == spdy::SYN_REPLY || + type == spdy::HEADERS) { if (!spdy_framer_.ParseHeaderBlock(frame, headers.get())) { LOG(WARNING) << "Could not parse Spdy Control Frame Header."; int stream_id = 0; - if (type == spdy::SYN_STREAM) + if (type == spdy::SYN_STREAM) { stream_id = (reinterpret_cast<const spdy::SpdySynStreamControlFrame*> (frame))->stream_id(); - if (type == spdy::SYN_REPLY) + } else if (type == spdy::SYN_REPLY) { stream_id = (reinterpret_cast<const spdy::SpdySynReplyControlFrame*> (frame))->stream_id(); + } else if (type == spdy::HEADERS) { + stream_id = (reinterpret_cast<const spdy::SpdyHeadersControlFrame*> + (frame))->stream_id(); + } if(IsStreamActive(stream_id)) ResetStream(stream_id, spdy::PROTOCOL_ERROR); return; @@ -1156,6 +1203,10 @@ void SpdySession::OnControl(const spdy::SpdyControlFrame* frame) { OnSyn(*reinterpret_cast<const spdy::SpdySynStreamControlFrame*>(frame), headers); break; + case spdy::HEADERS: + OnHeaders(*reinterpret_cast<const spdy::SpdyHeadersControlFrame*>(frame), + headers); + break; case spdy::SYN_REPLY: OnSynReply( *reinterpret_cast<const spdy::SpdySynReplyControlFrame*>(frame), |