1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/quic/quic_headers_stream.h" 6 7 #include "net/quic/quic_session.h" 8 9 using base::StringPiece; 10 11 namespace net { 12 13 namespace { 14 15 const QuicStreamId kInvalidStreamId = 0; 16 17 } // namespace 18 19 // A SpdyFramer visitor which passed SYN_STREAM and SYN_REPLY frames to 20 // the QuicDataStream, and closes the connection if any unexpected frames 21 // are received. 22 class QuicHeadersStream::SpdyFramerVisitor 23 : public SpdyFramerVisitorInterface, 24 public SpdyFramerDebugVisitorInterface { 25 public: 26 explicit SpdyFramerVisitor(QuicHeadersStream* stream) : stream_(stream) {} 27 28 // SpdyFramerVisitorInterface implementation 29 virtual void OnSynStream(SpdyStreamId stream_id, 30 SpdyStreamId associated_stream_id, 31 SpdyPriority priority, 32 bool fin, 33 bool unidirectional) OVERRIDE { 34 if (!stream_->IsConnected()) { 35 return; 36 } 37 38 if (associated_stream_id != 0) { 39 CloseConnection("associated_stream_id != 0"); 40 return; 41 } 42 43 if (unidirectional != 0) { 44 CloseConnection("unidirectional != 0"); 45 return; 46 } 47 48 stream_->OnSynStream(stream_id, priority, fin); 49 } 50 51 virtual void OnSynReply(SpdyStreamId stream_id, bool fin) OVERRIDE { 52 if (!stream_->IsConnected()) { 53 return; 54 } 55 56 stream_->OnSynReply(stream_id, fin); 57 } 58 59 virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id, 60 const char* header_data, 61 size_t len) OVERRIDE { 62 if (!stream_->IsConnected()) { 63 return false; 64 } 65 stream_->OnControlFrameHeaderData(stream_id, header_data, len); 66 return true; 67 } 68 69 virtual void OnStreamFrameData(SpdyStreamId stream_id, 70 const char* data, 71 size_t len, 72 bool fin) OVERRIDE { 73 if (fin && len == 0) { 74 // The framer invokes OnStreamFrameData with zero-length data and 75 // fin = true after processing a SYN_STREAM or SYN_REPLY frame 76 // that had the fin bit set. 77 return; 78 } 79 CloseConnection("SPDY DATA frame received."); 80 } 81 82 virtual void OnError(SpdyFramer* framer) OVERRIDE { 83 CloseConnection("SPDY framing error."); 84 } 85 86 virtual void OnDataFrameHeader(SpdyStreamId stream_id, 87 size_t length, 88 bool fin) OVERRIDE { 89 CloseConnection("SPDY DATA frame received."); 90 } 91 92 virtual void OnRstStream(SpdyStreamId stream_id, 93 SpdyRstStreamStatus status) OVERRIDE { 94 CloseConnection("SPDY RST_STREAM frame received."); 95 } 96 97 virtual void OnSetting(SpdySettingsIds id, 98 uint8 flags, 99 uint32 value) OVERRIDE { 100 CloseConnection("SPDY SETTINGS frame received."); 101 } 102 103 virtual void OnSettingsAck() OVERRIDE { 104 CloseConnection("SPDY SETTINGS frame received."); 105 } 106 107 virtual void OnSettingsEnd() OVERRIDE { 108 CloseConnection("SPDY SETTINGS frame received."); 109 } 110 111 virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE { 112 CloseConnection("SPDY PING frame received."); 113 } 114 115 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id, 116 SpdyGoAwayStatus status) OVERRIDE { 117 CloseConnection("SPDY GOAWAY frame received."); 118 } 119 120 virtual void OnHeaders(SpdyStreamId stream_id, bool fin, bool end) OVERRIDE { 121 CloseConnection("SPDY HEADERS frame received."); 122 } 123 124 virtual void OnWindowUpdate(SpdyStreamId stream_id, 125 uint32 delta_window_size) OVERRIDE { 126 CloseConnection("SPDY WINDOW_UPDATE frame received."); 127 } 128 129 virtual void OnPushPromise(SpdyStreamId stream_id, 130 SpdyStreamId promised_stream_id, 131 bool end) OVERRIDE { 132 LOG(DFATAL) << "PUSH_PROMISE frame received from a SPDY/3 framer"; 133 CloseConnection("SPDY PUSH_PROMISE frame received."); 134 } 135 136 virtual void OnContinuation(SpdyStreamId stream_id, bool end) OVERRIDE { 137 CloseConnection("SPDY CONTINUATION frame received."); 138 } 139 140 virtual bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) OVERRIDE { 141 CloseConnection("SPDY unknown frame received."); 142 return false; 143 } 144 145 // SpdyFramerDebugVisitorInterface implementation 146 virtual void OnSendCompressedFrame(SpdyStreamId stream_id, 147 SpdyFrameType type, 148 size_t payload_len, 149 size_t frame_len) OVERRIDE {} 150 151 virtual void OnReceiveCompressedFrame(SpdyStreamId stream_id, 152 SpdyFrameType type, 153 size_t frame_len) OVERRIDE { 154 if (stream_->IsConnected()) { 155 stream_->OnCompressedFrameSize(frame_len); 156 } 157 } 158 159 private: 160 void CloseConnection(const string& details) { 161 if (stream_->IsConnected()) { 162 stream_->CloseConnectionWithDetails( 163 QUIC_INVALID_HEADERS_STREAM_DATA, details); 164 } 165 } 166 167 private: 168 QuicHeadersStream* stream_; 169 170 DISALLOW_COPY_AND_ASSIGN(SpdyFramerVisitor); 171 }; 172 173 QuicHeadersStream::QuicHeadersStream(QuicSession* session) 174 : ReliableQuicStream(kHeadersStreamId, session), 175 stream_id_(kInvalidStreamId), 176 fin_(false), 177 frame_len_(0), 178 spdy_framer_(SPDY3), 179 spdy_framer_visitor_(new SpdyFramerVisitor(this)) { 180 spdy_framer_.set_visitor(spdy_framer_visitor_.get()); 181 spdy_framer_.set_debug_visitor(spdy_framer_visitor_.get()); 182 if (version() < QUIC_VERSION_21) { 183 // Prior to QUIC_VERSION_21 the headers stream is not subject to any flow 184 // control. 185 DisableFlowControl(); 186 } 187 // The headers stream is exempt from connection level flow control. 188 DisableConnectionFlowControlForThisStream(); 189 } 190 191 QuicHeadersStream::~QuicHeadersStream() {} 192 193 size_t QuicHeadersStream::WriteHeaders( 194 QuicStreamId stream_id, 195 const SpdyHeaderBlock& headers, 196 bool fin, 197 QuicAckNotifier::DelegateInterface* ack_notifier_delegate) { 198 scoped_ptr<SpdySerializedFrame> frame; 199 if (session()->is_server()) { 200 SpdySynReplyIR syn_reply(stream_id); 201 syn_reply.set_name_value_block(headers); 202 syn_reply.set_fin(fin); 203 frame.reset(spdy_framer_.SerializeFrame(syn_reply)); 204 } else { 205 SpdySynStreamIR syn_stream(stream_id); 206 syn_stream.set_name_value_block(headers); 207 syn_stream.set_fin(fin); 208 frame.reset(spdy_framer_.SerializeFrame(syn_stream)); 209 } 210 WriteOrBufferData(StringPiece(frame->data(), frame->size()), false, 211 ack_notifier_delegate); 212 return frame->size(); 213 } 214 215 uint32 QuicHeadersStream::ProcessRawData(const char* data, 216 uint32 data_len) { 217 return spdy_framer_.ProcessInput(data, data_len); 218 } 219 220 QuicPriority QuicHeadersStream::EffectivePriority() const { return 0; } 221 222 void QuicHeadersStream::OnSynStream(SpdyStreamId stream_id, 223 SpdyPriority priority, 224 bool fin) { 225 if (!session()->is_server()) { 226 CloseConnectionWithDetails( 227 QUIC_INVALID_HEADERS_STREAM_DATA, 228 "SPDY SYN_STREAM frame received at the client"); 229 return; 230 } 231 DCHECK_EQ(kInvalidStreamId, stream_id_); 232 stream_id_ = stream_id; 233 fin_ = fin; 234 session()->OnStreamHeadersPriority(stream_id, priority); 235 } 236 237 void QuicHeadersStream::OnSynReply(SpdyStreamId stream_id, bool fin) { 238 if (session()->is_server()) { 239 CloseConnectionWithDetails( 240 QUIC_INVALID_HEADERS_STREAM_DATA, 241 "SPDY SYN_REPLY frame received at the server"); 242 return; 243 } 244 DCHECK_EQ(kInvalidStreamId, stream_id_); 245 stream_id_ = stream_id; 246 fin_ = fin; 247 } 248 249 void QuicHeadersStream::OnControlFrameHeaderData(SpdyStreamId stream_id, 250 const char* header_data, 251 size_t len) { 252 DCHECK_EQ(stream_id_, stream_id); 253 if (len == 0) { 254 DCHECK_NE(0u, stream_id_); 255 DCHECK_NE(0u, frame_len_); 256 session()->OnStreamHeadersComplete(stream_id_, fin_, frame_len_); 257 // Reset state for the next frame. 258 stream_id_ = kInvalidStreamId; 259 fin_ = false; 260 frame_len_ = 0; 261 } else { 262 session()->OnStreamHeaders(stream_id_, StringPiece(header_data, len)); 263 } 264 } 265 266 void QuicHeadersStream::OnCompressedFrameSize(size_t frame_len) { 267 DCHECK_EQ(kInvalidStreamId, stream_id_); 268 DCHECK_EQ(0u, frame_len_); 269 frame_len_ = frame_len; 270 } 271 272 bool QuicHeadersStream::IsConnected() { 273 return session()->connection()->connected(); 274 } 275 276 } // namespace net 277