diff options
Diffstat (limited to 'net/spdy/spdy_session.cc')
-rw-r--r-- | net/spdy/spdy_session.cc | 111 |
1 files changed, 68 insertions, 43 deletions
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index 2607f90..1ab3904 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc @@ -25,6 +25,7 @@ #include "net/socket/ssl_client_socket.h" #include "net/spdy/spdy_frame_builder.h" #include "net/spdy/spdy_protocol.h" +#include "net/spdy/spdy_settings_storage.h" #include "net/spdy/spdy_stream.h" #include "net/tools/dump_cache/url_to_filename_encoder.h" @@ -215,6 +216,8 @@ SpdySession::SpdySession(const HostPortPair& host_port_pair, spdy_framer_.set_visitor(this); session_->ssl_config_service()->GetSSLConfig(&ssl_config_); + + SendSettings(); } SpdySession::~SpdySession() { @@ -367,10 +370,7 @@ scoped_refptr<SpdyStream> SpdySession::GetOrCreateStream( scoped_ptr<spdy::SpdySynStreamControlFrame> syn_frame( spdy_framer_.CreateSynStream(stream_id, 0, request.priority, flags, false, &headers)); - int length = spdy::SpdyFrame::size() + syn_frame->length(); - IOBuffer* buffer = new IOBuffer(length); - memcpy(buffer->data(), syn_frame->data(), length); - queue_.push(SpdyIOBuffer(buffer, length, request.priority, stream)); + QueueFrame(syn_frame.get(), request.priority, stream); static StatsCounter spdy_requests("spdy.requests"); spdy_requests.Increment(); @@ -381,14 +381,6 @@ scoped_refptr<SpdyStream> SpdySession::GetOrCreateStream( LOG(INFO) << "SPDY SYN_STREAM HEADERS ----------------------------------"; DumpSpdyHeaders(headers); - // Schedule to write to the socket after we've made it back - // to the message loop so that we can aggregate multiple - // requests. - // TODO(mbelshe): Should we do the "first" request immediately? - // maybe we should only 'do later' for subsequent - // requests. - WriteSocketLater(); - return stream; } @@ -423,15 +415,7 @@ int SpdySession::WriteStreamData(spdy::SpdyStreamId stream_id, // TODO(mbelshe): reduce memory copies here. scoped_ptr<spdy::SpdyDataFrame> frame( spdy_framer_.CreateDataFrame(stream_id, data->data(), len, flags)); - int length = spdy::SpdyFrame::size() + frame->length(); - IOBufferWithSize* buffer = new IOBufferWithSize(length); - memcpy(buffer->data(), frame->data(), length); - queue_.push(SpdyIOBuffer(buffer, length, stream->priority(), stream)); - - // Whenever we queue onto the socket we need to ensure that we will write to - // it later. - WriteSocketLater(); - + QueueFrame(frame.get(), stream->priority(), stream); return ERR_IO_PENDING; } @@ -580,8 +564,10 @@ void SpdySession::OnWriteComplete(int result) { write_pending_ = false; - LOG(INFO) << "Spdy write complete (result=" << result << ") for stream: " - << in_flight_write_.stream()->stream_id(); + scoped_refptr<SpdyStream> stream = in_flight_write_.stream(); + + LOG(INFO) << "Spdy write complete (result=" << result << ")" + << (stream ? " for stream " + stream->stream_id() : ""); if (result >= 0) { // It should not be possible to have written more bytes than our @@ -593,22 +579,23 @@ void SpdySession::OnWriteComplete(int result) { // We only notify the stream when we've fully written the pending frame. if (!in_flight_write_.buffer()->BytesRemaining()) { scoped_refptr<SpdyStream> stream = in_flight_write_.stream(); - DCHECK(stream.get()); - - // Report the number of bytes written to the caller, but exclude the - // frame size overhead. NOTE: if this frame was compressed the reported - // bytes written is the compressed size, not the original size. - if (result > 0) { - result = in_flight_write_.buffer()->size(); - DCHECK_GT(result, static_cast<int>(spdy::SpdyFrame::size())); - result -= static_cast<int>(spdy::SpdyFrame::size()); + if (stream) { + // Report the number of bytes written to the caller, but exclude the + // frame size overhead. NOTE: if this frame was compressed the + // reported bytes written is the compressed size, not the original + // size. + if (result > 0) { + result = in_flight_write_.buffer()->size(); + DCHECK_GT(result, static_cast<int>(spdy::SpdyFrame::size())); + result -= static_cast<int>(spdy::SpdyFrame::size()); + } + + // It is possible that the stream was cancelled while we were writing + // to the socket. + if (!stream->cancelled()) + stream->OnWriteComplete(result); } - // It is possible that the stream was cancelled while we were writing - // to the socket. - if (!stream->cancelled()) - stream->OnWriteComplete(result); - // Cleanup the write which just completed. in_flight_write_.release(); } @@ -664,6 +651,9 @@ void SpdySession::WriteSocketLater() { if (delayed_write_pending_) return; + if (state_ < CONNECTED) + return; + delayed_write_pending_ = true; MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( this, &SpdySession::WriteSocket)); @@ -781,6 +771,17 @@ int SpdySession::GetNewStreamId() { return id; } +void SpdySession::QueueFrame(spdy::SpdyFrame* frame, + spdy::SpdyPriority priority, + SpdyStream* stream) { + int length = spdy::SpdyFrame::size() + frame->length(); + IOBuffer* buffer = new IOBuffer(length); + memcpy(buffer->data(), frame->data(), length); + queue_.push(SpdyIOBuffer(buffer, length, priority, stream)); + + WriteSocketLater(); +} + void SpdySession::CloseSessionOnError(net::Error err) { DCHECK_LT(err, OK); LOG(INFO) << "spdy::CloseSessionOnError(" << err << ") for " << @@ -1040,6 +1041,16 @@ void SpdySession::OnControl(const spdy::SpdyControlFrame* frame) { } switch (type) { + case spdy::GOAWAY: + OnGoAway(*reinterpret_cast<const spdy::SpdyGoAwayControlFrame*>(frame)); + break; + case spdy::SETTINGS: + OnSettings( + *reinterpret_cast<const spdy::SpdySettingsControlFrame*>(frame)); + break; + case spdy::RST_STREAM: + OnFin(*reinterpret_cast<const spdy::SpdyRstStreamControlFrame*>(frame)); + break; case spdy::SYN_STREAM: OnSyn(*reinterpret_cast<const spdy::SpdySynStreamControlFrame*>(frame), headers); @@ -1049,12 +1060,6 @@ void SpdySession::OnControl(const spdy::SpdyControlFrame* frame) { *reinterpret_cast<const spdy::SpdySynReplyControlFrame*>(frame), headers); break; - case spdy::RST_STREAM: - OnFin(*reinterpret_cast<const spdy::SpdyRstStreamControlFrame*>(frame)); - break; - case spdy::GOAWAY: - OnGoAway(*reinterpret_cast<const spdy::SpdyGoAwayControlFrame*>(frame)); - break; default: DCHECK(false); // Error! } @@ -1098,4 +1103,24 @@ void SpdySession::OnGoAway(const spdy::SpdyGoAwayControlFrame& frame) { // closed. } +void SpdySession::OnSettings(const spdy::SpdySettingsControlFrame& frame) { + spdy::SpdySettings settings; + if (spdy_framer_.ParseSettings(&frame, &settings)) { + SpdySettingsStorage* settings_storage = session_->mutable_spdy_settings(); + settings_storage->Set(host_port_pair_, settings); + } +} + +void SpdySession::SendSettings() { + const SpdySettingsStorage& settings_storage = session_->spdy_settings(); + const spdy::SpdySettings& settings = settings_storage.Get(host_port_pair_); + if (settings.empty()) + return; + + // Create the SETTINGS frame and send it. + scoped_ptr<spdy::SpdySettingsControlFrame> settings_frame( + spdy_framer_.CreateSettings(settings)); + QueueFrame(settings_frame.get(), 0, NULL); +} + } // namespace net |