| Index: net/quic/quic_headers_stream.cc
|
| diff --git a/net/quic/quic_headers_stream.cc b/net/quic/quic_headers_stream.cc
|
| index 369a34898846432c2883db6d1162e8187d8d5c79..d7b89fa1bfbc79baab3575c690df07772c283697 100644
|
| --- a/net/quic/quic_headers_stream.cc
|
| +++ b/net/quic/quic_headers_stream.cc
|
| @@ -25,7 +25,8 @@ class QuicHeadersStream::SpdyFramerVisitor
|
| : public SpdyFramerVisitorInterface,
|
| public SpdyFramerDebugVisitorInterface {
|
| public:
|
| - explicit SpdyFramerVisitor(QuicHeadersStream* stream) : stream_(stream) {}
|
| + SpdyFramerVisitor(SpdyMajorVersion spdy_version, QuicHeadersStream* stream)
|
| + : spdy_version_(spdy_version), stream_(stream) {}
|
|
|
| // SpdyFramerVisitorInterface implementation
|
| void OnSynStream(SpdyStreamId stream_id,
|
| @@ -33,6 +34,11 @@ class QuicHeadersStream::SpdyFramerVisitor
|
| SpdyPriority priority,
|
| bool fin,
|
| bool unidirectional) override {
|
| + if (spdy_version_ != SPDY3) {
|
| + CloseConnection("SPDY SYN_STREAM frame received.");
|
| + return;
|
| + }
|
| +
|
| if (!stream_->IsConnected()) {
|
| return;
|
| }
|
| @@ -51,6 +57,11 @@ class QuicHeadersStream::SpdyFramerVisitor
|
| }
|
|
|
| void OnSynReply(SpdyStreamId stream_id, bool fin) override {
|
| + if (spdy_version_ != SPDY3) {
|
| + CloseConnection("SPDY SYN_REPLY frame received.");
|
| + return;
|
| + }
|
| +
|
| if (!stream_->IsConnected()) {
|
| return;
|
| }
|
| @@ -124,7 +135,18 @@ class QuicHeadersStream::SpdyFramerVisitor
|
| SpdyPriority priority,
|
| bool fin,
|
| bool end) override {
|
| - CloseConnection("SPDY HEADERS frame received.");
|
| + if (spdy_version_ == SPDY3) {
|
| + CloseConnection("SPDY HEADERS frame received.");
|
| + return;
|
| + }
|
| + if (!stream_->IsConnected()) {
|
| + return;
|
| + }
|
| + if (has_priority) {
|
| + stream_->OnSynStream(stream_id, priority, fin);
|
| + } else {
|
| + stream_->OnSynReply(stream_id, fin);
|
| + }
|
| }
|
|
|
| void OnWindowUpdate(SpdyStreamId stream_id,
|
| @@ -140,7 +162,9 @@ class QuicHeadersStream::SpdyFramerVisitor
|
| }
|
|
|
| void OnContinuation(SpdyStreamId stream_id, bool end) override {
|
| - CloseConnection("SPDY CONTINUATION frame received.");
|
| + if (spdy_version_ == SPDY3) {
|
| + CloseConnection("SPDY CONTINUATION frame received.");
|
| + }
|
| }
|
|
|
| bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override {
|
| @@ -171,6 +195,7 @@ class QuicHeadersStream::SpdyFramerVisitor
|
| }
|
|
|
| private:
|
| + SpdyMajorVersion spdy_version_;
|
| QuicHeadersStream* stream_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(SpdyFramerVisitor);
|
| @@ -180,11 +205,8 @@ QuicHeadersStream::QuicHeadersStream(QuicSession* session)
|
| : ReliableQuicStream(kHeadersStreamId, session),
|
| stream_id_(kInvalidStreamId),
|
| fin_(false),
|
| - frame_len_(0),
|
| - spdy_framer_(SPDY3),
|
| - spdy_framer_visitor_(new SpdyFramerVisitor(this)) {
|
| - spdy_framer_.set_visitor(spdy_framer_visitor_.get());
|
| - spdy_framer_.set_debug_visitor(spdy_framer_visitor_.get());
|
| + frame_len_(0) {
|
| + InitializeFramer(session->connection()->version());
|
| // The headers stream is exempt from connection level flow control.
|
| DisableConnectionFlowControlForThisStream();
|
| }
|
| @@ -197,16 +219,26 @@ size_t QuicHeadersStream::WriteHeaders(
|
| bool fin,
|
| QuicAckNotifier::DelegateInterface* ack_notifier_delegate) {
|
| scoped_ptr<SpdySerializedFrame> frame;
|
| - if (session()->is_server()) {
|
| - SpdySynReplyIR syn_reply(stream_id);
|
| - syn_reply.set_name_value_block(headers);
|
| - syn_reply.set_fin(fin);
|
| - frame.reset(spdy_framer_.SerializeFrame(syn_reply));
|
| + if (spdy_framer_->protocol_version() == SPDY3) {
|
| + if (session()->is_server()) {
|
| + SpdySynReplyIR syn_reply(stream_id);
|
| + syn_reply.set_name_value_block(headers);
|
| + syn_reply.set_fin(fin);
|
| + frame.reset(spdy_framer_->SerializeFrame(syn_reply));
|
| + } else {
|
| + SpdySynStreamIR syn_stream(stream_id);
|
| + syn_stream.set_name_value_block(headers);
|
| + syn_stream.set_fin(fin);
|
| + frame.reset(spdy_framer_->SerializeFrame(syn_stream));
|
| + }
|
| } else {
|
| - SpdySynStreamIR syn_stream(stream_id);
|
| - syn_stream.set_name_value_block(headers);
|
| - syn_stream.set_fin(fin);
|
| - frame.reset(spdy_framer_.SerializeFrame(syn_stream));
|
| + SpdyHeadersIR headers_frame(stream_id);
|
| + headers_frame.set_name_value_block(headers);
|
| + headers_frame.set_fin(fin);
|
| + if (!session()->is_server()) {
|
| + headers_frame.set_has_priority(true);
|
| + }
|
| + frame.reset(spdy_framer_->SerializeFrame(headers_frame));
|
| }
|
| WriteOrBufferData(StringPiece(frame->data(), frame->size()), false,
|
| ack_notifier_delegate);
|
| @@ -215,11 +247,27 @@ size_t QuicHeadersStream::WriteHeaders(
|
|
|
| uint32 QuicHeadersStream::ProcessRawData(const char* data,
|
| uint32 data_len) {
|
| - return spdy_framer_.ProcessInput(data, data_len);
|
| + return spdy_framer_->ProcessInput(data, data_len);
|
| }
|
|
|
| QuicPriority QuicHeadersStream::EffectivePriority() const { return 0; }
|
|
|
| +void QuicHeadersStream::OnSuccessfulVersionNegotiation(QuicVersion version) {
|
| + InitializeFramer(version);
|
| +}
|
| +
|
| +void QuicHeadersStream::InitializeFramer(QuicVersion version) {
|
| + SpdyMajorVersion spdy_version = version > QUIC_VERSION_23 ? SPDY4 : SPDY3;
|
| + if (spdy_framer_.get() != nullptr &&
|
| + spdy_framer_->protocol_version() == spdy_version) {
|
| + return;
|
| + }
|
| + spdy_framer_.reset(new SpdyFramer(spdy_version));
|
| + spdy_framer_visitor_.reset(new SpdyFramerVisitor(spdy_version, this));
|
| + spdy_framer_->set_visitor(spdy_framer_visitor_.get());
|
| + spdy_framer_->set_debug_visitor(spdy_framer_visitor_.get());
|
| +}
|
| +
|
| void QuicHeadersStream::OnSynStream(SpdyStreamId stream_id,
|
| SpdyPriority priority,
|
| bool fin) {
|
| @@ -265,9 +313,9 @@ void QuicHeadersStream::OnControlFrameHeaderData(SpdyStreamId stream_id,
|
| }
|
|
|
| void QuicHeadersStream::OnCompressedFrameSize(size_t frame_len) {
|
| - DCHECK_EQ(kInvalidStreamId, stream_id_);
|
| - DCHECK_EQ(0u, frame_len_);
|
| - frame_len_ = frame_len;
|
| + // DCHECK_EQ(kInvalidStreamId, stream_id_);
|
| + // DCHECK_EQ(0u, frame_len_);
|
| + frame_len_ += frame_len;
|
| }
|
|
|
| bool QuicHeadersStream::IsConnected() {
|
|
|