Snap pinch zoom gestures near the screen edge.
[chromium-blink-merge.git] / net / quic / quic_headers_stream.cc
blobd077e44f0638be776354b66267eca11811a8ddd9
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.
5 #include "net/quic/quic_headers_stream.h"
7 #include "base/strings/stringprintf.h"
8 #include "net/quic/quic_spdy_session.h"
10 using base::StringPiece;
11 using std::string;
13 namespace net {
15 namespace {
17 const QuicStreamId kInvalidStreamId = 0;
19 } // namespace
21 // A SpdyFramer visitor which passed SYN_STREAM and SYN_REPLY frames to
22 // the QuicDataStream, and closes the connection if any unexpected frames
23 // are received.
24 class QuicHeadersStream::SpdyFramerVisitor
25 : public SpdyFramerVisitorInterface,
26 public SpdyFramerDebugVisitorInterface {
27 public:
28 SpdyFramerVisitor(SpdyMajorVersion spdy_version, QuicHeadersStream* stream)
29 : spdy_version_(spdy_version), stream_(stream) {}
31 // SpdyFramerVisitorInterface implementation
32 void OnSynStream(SpdyStreamId stream_id,
33 SpdyStreamId associated_stream_id,
34 SpdyPriority priority,
35 bool fin,
36 bool unidirectional) override {
37 CloseConnection("SPDY SYN_STREAM frame received.");
40 void OnSynReply(SpdyStreamId stream_id, bool fin) override {
41 CloseConnection("SPDY SYN_REPLY frame received.");
44 bool OnControlFrameHeaderData(SpdyStreamId stream_id,
45 const char* header_data,
46 size_t len) override {
47 if (!stream_->IsConnected()) {
48 return false;
50 stream_->OnControlFrameHeaderData(stream_id, header_data, len);
51 return true;
54 void OnStreamFrameData(SpdyStreamId stream_id,
55 const char* data,
56 size_t len,
57 bool fin) override {
58 if (fin && len == 0) {
59 // The framer invokes OnStreamFrameData with zero-length data and
60 // fin = true after processing a SYN_STREAM or SYN_REPLY frame
61 // that had the fin bit set.
62 return;
64 CloseConnection("SPDY DATA frame received.");
67 void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {
68 CloseConnection("SPDY frame padding received.");
71 void OnError(SpdyFramer* framer) override {
72 CloseConnection(base::StringPrintf(
73 "SPDY framing error: %s",
74 SpdyFramer::ErrorCodeToString(framer->error_code())));
77 void OnDataFrameHeader(SpdyStreamId stream_id,
78 size_t length,
79 bool fin) override {
80 CloseConnection("SPDY DATA frame received.");
83 void OnRstStream(SpdyStreamId stream_id,
84 SpdyRstStreamStatus status) override {
85 CloseConnection("SPDY RST_STREAM frame received.");
88 void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) override {
89 CloseConnection("SPDY SETTINGS frame received.");
92 void OnSettingsAck() override {
93 CloseConnection("SPDY SETTINGS frame received.");
96 void OnSettingsEnd() override {
97 CloseConnection("SPDY SETTINGS frame received.");
100 void OnPing(SpdyPingId unique_id, bool is_ack) override {
101 CloseConnection("SPDY PING frame received.");
104 void OnGoAway(SpdyStreamId last_accepted_stream_id,
105 SpdyGoAwayStatus status) override {
106 CloseConnection("SPDY GOAWAY frame received.");
109 void OnHeaders(SpdyStreamId stream_id,
110 bool has_priority,
111 SpdyPriority priority,
112 SpdyStreamId parent_stream_id,
113 bool exclusive,
114 bool fin,
115 bool end) override {
116 if (!stream_->IsConnected()) {
117 return;
119 if (has_priority) {
120 stream_->OnSynStream(stream_id, priority, fin);
121 } else {
122 stream_->OnSynReply(stream_id, fin);
126 void OnWindowUpdate(SpdyStreamId stream_id,
127 uint32 delta_window_size) override {
128 CloseConnection("SPDY WINDOW_UPDATE frame received.");
131 void OnPushPromise(SpdyStreamId stream_id,
132 SpdyStreamId promised_stream_id,
133 bool end) override {
134 CloseConnection("SPDY PUSH_PROMISE frame received.");
137 void OnContinuation(SpdyStreamId stream_id, bool end) override {
140 bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override {
141 CloseConnection("Unknown frame type received.");
142 return false;
145 // SpdyFramerDebugVisitorInterface implementation
146 void OnSendCompressedFrame(SpdyStreamId stream_id,
147 SpdyFrameType type,
148 size_t payload_len,
149 size_t frame_len) override {}
151 void OnReceiveCompressedFrame(SpdyStreamId stream_id,
152 SpdyFrameType type,
153 size_t frame_len) override {
154 if (stream_->IsConnected()) {
155 stream_->OnCompressedFrameSize(frame_len);
159 private:
160 void CloseConnection(const string& details) {
161 if (stream_->IsConnected()) {
162 stream_->CloseConnectionWithDetails(
163 QUIC_INVALID_HEADERS_STREAM_DATA, details);
167 private:
168 SpdyMajorVersion spdy_version_;
169 QuicHeadersStream* stream_;
171 DISALLOW_COPY_AND_ASSIGN(SpdyFramerVisitor);
174 QuicHeadersStream::QuicHeadersStream(QuicSpdySession* session)
175 : ReliableQuicStream(kHeadersStreamId, session),
176 spdy_session_(session),
177 stream_id_(kInvalidStreamId),
178 fin_(false),
179 frame_len_(0),
180 spdy_framer_(HTTP2),
181 spdy_framer_visitor_(new SpdyFramerVisitor(HTTP2, this)) {
182 spdy_framer_.set_visitor(spdy_framer_visitor_.get());
183 spdy_framer_.set_debug_visitor(spdy_framer_visitor_.get());
184 // The headers stream is exempt from connection level flow control.
185 DisableConnectionFlowControlForThisStream();
188 QuicHeadersStream::~QuicHeadersStream() {}
190 size_t QuicHeadersStream::WriteHeaders(
191 QuicStreamId stream_id,
192 const SpdyHeaderBlock& headers,
193 bool fin,
194 QuicPriority priority,
195 QuicAckNotifier::DelegateInterface* ack_notifier_delegate) {
196 SpdyHeadersIR headers_frame(stream_id);
197 headers_frame.set_name_value_block(headers);
198 headers_frame.set_fin(fin);
199 if (session()->perspective() == Perspective::IS_CLIENT) {
200 headers_frame.set_has_priority(true);
201 headers_frame.set_priority(priority);
203 scoped_ptr<SpdySerializedFrame> frame(
204 spdy_framer_.SerializeFrame(headers_frame));
205 WriteOrBufferData(StringPiece(frame->data(), frame->size()), false,
206 ack_notifier_delegate);
207 return frame->size();
210 uint32 QuicHeadersStream::ProcessRawData(const char* data,
211 uint32 data_len) {
212 return spdy_framer_.ProcessInput(data, data_len);
215 QuicPriority QuicHeadersStream::EffectivePriority() const { return 0; }
217 void QuicHeadersStream::OnSynStream(SpdyStreamId stream_id,
218 SpdyPriority priority,
219 bool fin) {
220 if (session()->perspective() == Perspective::IS_CLIENT) {
221 CloseConnectionWithDetails(
222 QUIC_INVALID_HEADERS_STREAM_DATA,
223 "SPDY SYN_STREAM frame received at the client");
224 return;
226 DCHECK_EQ(kInvalidStreamId, stream_id_);
227 stream_id_ = stream_id;
228 fin_ = fin;
229 spdy_session_->OnStreamHeadersPriority(stream_id, priority);
232 void QuicHeadersStream::OnSynReply(SpdyStreamId stream_id, bool fin) {
233 if (session()->perspective() == Perspective::IS_SERVER) {
234 CloseConnectionWithDetails(
235 QUIC_INVALID_HEADERS_STREAM_DATA,
236 "SPDY SYN_REPLY frame received at the server");
237 return;
239 DCHECK_EQ(kInvalidStreamId, stream_id_);
240 stream_id_ = stream_id;
241 fin_ = fin;
244 void QuicHeadersStream::OnControlFrameHeaderData(SpdyStreamId stream_id,
245 const char* header_data,
246 size_t len) {
247 DCHECK_EQ(stream_id_, stream_id);
248 if (len == 0) {
249 DCHECK_NE(0u, stream_id_);
250 DCHECK_NE(0u, frame_len_);
251 spdy_session_->OnStreamHeadersComplete(stream_id_, fin_, frame_len_);
252 // Reset state for the next frame.
253 stream_id_ = kInvalidStreamId;
254 fin_ = false;
255 frame_len_ = 0;
256 } else {
257 spdy_session_->OnStreamHeaders(stream_id_, StringPiece(header_data, len));
261 void QuicHeadersStream::OnCompressedFrameSize(size_t frame_len) {
262 frame_len_ += frame_len;
265 bool QuicHeadersStream::IsConnected() {
266 return session()->connection()->connected();
269 } // namespace net