15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_headers_stream.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_session.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::StringPiece; 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace net { 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const QuicStreamId kInvalidStreamId = 0; 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A SpdyFramer visitor which passed SYN_STREAM and SYN_REPLY frames to 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the QuicDataStream, and closes the connection if any unexpected frames 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// are received. 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class QuicHeadersStream::SpdyFramerVisitor 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : public SpdyFramerVisitorInterface, 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public SpdyFramerDebugVisitorInterface { 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit SpdyFramerVisitor(QuicHeadersStream* stream) : stream_(stream) {} 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // SpdyFramerVisitorInterface implementation 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnSynStream(SpdyStreamId stream_id, 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyStreamId associated_stream_id, 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyPriority priority, 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin, 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool unidirectional) OVERRIDE { 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!stream_->IsConnected()) { 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (associated_stream_id != 0) { 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CloseConnection("associated_stream_id != 0"); 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (unidirectional != 0) { 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CloseConnection("unidirectional != 0"); 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_->OnSynStream(stream_id, priority, fin); 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnSynReply(SpdyStreamId stream_id, bool fin) OVERRIDE { 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!stream_->IsConnected()) { 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_->OnSynReply(stream_id, fin); 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id, 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* header_data, 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t len) OVERRIDE { 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!stream_->IsConnected()) { 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_->OnControlFrameHeaderData(stream_id, header_data, len); 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnStreamFrameData(SpdyStreamId stream_id, 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* data, 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t len, 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin) OVERRIDE { 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fin && len == 0) { 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The framer invokes OnStreamFrameData with zero-length data and 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // fin = true after processing a SYN_STREAM or SYN_REPLY frame 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // that had the fin bit set. 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CloseConnection("SPDY DATA frame received."); 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnError(SpdyFramer* framer) OVERRIDE { 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CloseConnection("SPDY framing error."); 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnDataFrameHeader(SpdyStreamId stream_id, 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t length, 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin) OVERRIDE { 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CloseConnection("SPDY DATA frame received."); 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnRstStream(SpdyStreamId stream_id, 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyRstStreamStatus status) OVERRIDE { 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CloseConnection("SPDY RST_STREAM frame received."); 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnSetting(SpdySettingsIds id, 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint8 flags, 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32 value) OVERRIDE { 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CloseConnection("SPDY SETTINGS frame received."); 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnSettingsAck() OVERRIDE { 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CloseConnection("SPDY SETTINGS frame received."); 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnSettingsEnd() OVERRIDE { 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CloseConnection("SPDY SETTINGS frame received."); 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE { 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CloseConnection("SPDY PING frame received."); 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnGoAway(SpdyStreamId last_accepted_stream_id, 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyGoAwayStatus status) OVERRIDE { 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CloseConnection("SPDY GOAWAY frame received."); 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnHeaders(SpdyStreamId stream_id, bool fin, bool end) OVERRIDE { 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CloseConnection("SPDY HEADERS frame received."); 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnWindowUpdate(SpdyStreamId stream_id, 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32 delta_window_size) OVERRIDE { 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CloseConnection("SPDY WINDOW_UPDATE frame received."); 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnPushPromise(SpdyStreamId stream_id, 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SpdyStreamId promised_stream_id, 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool end) OVERRIDE { 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(DFATAL) << "PUSH_PROMISE frame received from a SPDY/3 framer"; 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CloseConnection("SPDY PUSH_PROMISE frame received."); 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnContinuation(SpdyStreamId stream_id, bool end) OVERRIDE { 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CloseConnection("SPDY CONTINUATION frame received."); 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) virtual bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) OVERRIDE { 14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) CloseConnection("SPDY unknown frame received."); 14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // SpdyFramerDebugVisitorInterface implementation 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnSendCompressedFrame(SpdyStreamId stream_id, 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyFrameType type, 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t payload_len, 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t frame_len) OVERRIDE {} 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnReceiveCompressedFrame(SpdyStreamId stream_id, 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyFrameType type, 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t frame_len) OVERRIDE { 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (stream_->IsConnected()) { 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_->OnCompressedFrameSize(frame_len); 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void CloseConnection(const string& details) { 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (stream_->IsConnected()) { 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_->CloseConnectionWithDetails( 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QUIC_INVALID_HEADERS_STREAM_DATA, details); 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QuicHeadersStream* stream_; 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(SpdyFramerVisitor); 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicHeadersStream::QuicHeadersStream(QuicSession* session) 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : ReliableQuicStream(kHeadersStreamId, session), 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_id_(kInvalidStreamId), 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fin_(false), 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frame_len_(0), 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_framer_(SPDY3), 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_framer_visitor_(new SpdyFramerVisitor(this)) { 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_framer_.set_visitor(spdy_framer_visitor_.get()); 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spdy_framer_.set_debug_visitor(spdy_framer_visitor_.get()); 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (version() < QUIC_VERSION_21) { 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Prior to QUIC_VERSION_21 the headers stream is not subject to any flow 184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // control. 185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DisableFlowControl(); 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // The headers stream is exempt from connection level flow control. 188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DisableConnectionFlowControlForThisStream(); 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicHeadersStream::~QuicHeadersStream() {} 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 19323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)size_t QuicHeadersStream::WriteHeaders( 19423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) QuicStreamId stream_id, 19523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const SpdyHeaderBlock& headers, 19623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool fin, 19723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<SpdySerializedFrame> frame; 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (session()->is_server()) { 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdySynReplyIR syn_reply(stream_id); 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syn_reply.set_name_value_block(headers); 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syn_reply.set_fin(fin); 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frame.reset(spdy_framer_.SerializeFrame(syn_reply)); 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdySynStreamIR syn_stream(stream_id); 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syn_stream.set_name_value_block(headers); 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syn_stream.set_fin(fin); 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frame.reset(spdy_framer_.SerializeFrame(syn_stream)); 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 21023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) WriteOrBufferData(StringPiece(frame->data(), frame->size()), false, 21123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ack_notifier_delegate); 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return frame->size(); 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)uint32 QuicHeadersStream::ProcessRawData(const char* data, 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32 data_len) { 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return spdy_framer_.ProcessInput(data, data_len); 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicPriority QuicHeadersStream::EffectivePriority() const { return 0; } 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicHeadersStream::OnSynStream(SpdyStreamId stream_id, 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SpdyPriority priority, 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool fin) { 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!session()->is_server()) { 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CloseConnectionWithDetails( 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QUIC_INVALID_HEADERS_STREAM_DATA, 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "SPDY SYN_STREAM frame received at the client"); 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(kInvalidStreamId, stream_id_); 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_id_ = stream_id; 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fin_ = fin; 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session()->OnStreamHeadersPriority(stream_id, priority); 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicHeadersStream::OnSynReply(SpdyStreamId stream_id, bool fin) { 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (session()->is_server()) { 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CloseConnectionWithDetails( 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) QUIC_INVALID_HEADERS_STREAM_DATA, 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "SPDY SYN_REPLY frame received at the server"); 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(kInvalidStreamId, stream_id_); 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_id_ = stream_id; 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fin_ = fin; 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicHeadersStream::OnControlFrameHeaderData(SpdyStreamId stream_id, 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const char* header_data, 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t len) { 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(stream_id_, stream_id); 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (len == 0) { 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_NE(0u, stream_id_); 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_NE(0u, frame_len_); 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session()->OnStreamHeadersComplete(stream_id_, fin_, frame_len_); 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Reset state for the next frame. 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stream_id_ = kInvalidStreamId; 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fin_ = false; 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frame_len_ = 0; 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session()->OnStreamHeaders(stream_id_, StringPiece(header_data, len)); 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicHeadersStream::OnCompressedFrameSize(size_t frame_len) { 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(kInvalidStreamId, stream_id_); 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(0u, frame_len_); 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frame_len_ = frame_len; 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool QuicHeadersStream::IsConnected() { 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return session()->connection()->connected(); 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace net 277