1 // Copyright (c) 2012 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 #ifndef NET_SPDY_BUFFERED_SPDY_FRAMER_H_
6 #define NET_SPDY_BUFFERED_SPDY_FRAMER_H_
10 #include "base/basictypes.h"
11 #include "base/gtest_prod_util.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "net/base/net_export.h"
14 #include "net/socket/next_proto.h"
15 #include "net/spdy/spdy_framer.h"
16 #include "net/spdy/spdy_header_block.h"
17 #include "net/spdy/spdy_protocol.h"
21 // Returns the SPDY major version corresponding to the given NextProto
22 // value, which must represent a SPDY-like protocol.
23 NET_EXPORT_PRIVATE SpdyMajorVersion NextProtoToSpdyMajorVersion(
24 NextProto next_proto);
26 class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface {
28 BufferedSpdyFramerVisitorInterface() {}
30 // Called if an error is detected in the SpdyFrame protocol.
31 virtual void OnError(SpdyFramer::SpdyError error_code) = 0;
33 // Called if an error is detected in a SPDY stream.
34 virtual void OnStreamError(SpdyStreamId stream_id,
35 const std::string& description) = 0;
37 // Called after all the header data for SYN_STREAM control frame is received.
38 virtual void OnSynStream(SpdyStreamId stream_id,
39 SpdyStreamId associated_stream_id,
40 SpdyPriority priority,
41 uint8 credential_slot,
44 const SpdyHeaderBlock& headers) = 0;
46 // Called after all the header data for SYN_REPLY control frame is received.
47 virtual void OnSynReply(SpdyStreamId stream_id,
49 const SpdyHeaderBlock& headers) = 0;
51 // Called after all the header data for HEADERS control frame is received.
52 virtual void OnHeaders(SpdyStreamId stream_id,
54 const SpdyHeaderBlock& headers) = 0;
56 // Called when a data frame header is received.
57 virtual void OnDataFrameHeader(SpdyStreamId stream_id,
61 // Called when data is received.
62 // |stream_id| The stream receiving data.
63 // |data| A buffer containing the data received.
64 // |len| The length of the data buffer (at most 2^24 - 1 for SPDY/3,
65 // but 2^16 - 1 - 8 for SPDY/4).
66 // When the other side has finished sending data on this stream,
67 // this method will be called with a zero-length buffer.
68 virtual void OnStreamFrameData(SpdyStreamId stream_id,
73 // Called when a SETTINGS frame is received.
74 // |clear_persisted| True if the respective flag is set on the SETTINGS frame.
75 virtual void OnSettings(bool clear_persisted) = 0;
77 // Called when an individual setting within a SETTINGS frame has been parsed
79 virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0;
81 // Called when a PING frame has been parsed.
82 virtual void OnPing(uint32 unique_id) = 0;
84 // Called when a RST_STREAM frame has been parsed.
85 virtual void OnRstStream(SpdyStreamId stream_id,
86 SpdyRstStreamStatus status) = 0;
88 // Called when a GOAWAY frame has been parsed.
89 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
90 SpdyGoAwayStatus status) = 0;
92 // Called when a WINDOW_UPDATE frame has been parsed.
93 virtual void OnWindowUpdate(SpdyStreamId stream_id,
94 uint32 delta_window_size) = 0;
96 // Called when a PUSH_PROMISE frame has been parsed.
97 virtual void OnPushPromise(SpdyStreamId stream_id,
98 SpdyStreamId promised_stream_id) = 0;
101 virtual ~BufferedSpdyFramerVisitorInterface() {}
104 DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramerVisitorInterface);
107 class NET_EXPORT_PRIVATE BufferedSpdyFramer
108 : public SpdyFramerVisitorInterface {
110 BufferedSpdyFramer(SpdyMajorVersion version,
111 bool enable_compression);
112 virtual ~BufferedSpdyFramer();
114 // Sets callbacks to be called from the buffered spdy framer. A visitor must
115 // be set, or else the framer will likely crash. It is acceptable for the
116 // visitor to do nothing. If this is called multiple times, only the last
117 // visitor will be used.
118 void set_visitor(BufferedSpdyFramerVisitorInterface* visitor);
120 // Set debug callbacks to be called from the framer. The debug visitor is
121 // completely optional and need not be set in order for normal operation.
122 // If this is called multiple times, only the last visitor will be used.
123 void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor);
125 // SpdyFramerVisitorInterface
126 virtual void OnError(SpdyFramer* spdy_framer) OVERRIDE;
127 virtual void OnSynStream(SpdyStreamId stream_id,
128 SpdyStreamId associated_stream_id,
129 SpdyPriority priority,
130 uint8 credential_slot,
132 bool unidirectional) OVERRIDE;
133 virtual void OnSynReply(SpdyStreamId stream_id, bool fin) OVERRIDE;
134 virtual void OnHeaders(SpdyStreamId stream_id, bool fin) OVERRIDE;
135 virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id,
136 const char* header_data,
137 size_t len) OVERRIDE;
138 virtual void OnStreamFrameData(SpdyStreamId stream_id,
142 virtual void OnSettings(bool clear_persisted) OVERRIDE;
143 virtual void OnSetting(
144 SpdySettingsIds id, uint8 flags, uint32 value) OVERRIDE;
145 virtual void OnPing(uint32 unique_id) OVERRIDE;
146 virtual void OnRstStream(SpdyStreamId stream_id,
147 SpdyRstStreamStatus status) OVERRIDE;
148 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
149 SpdyGoAwayStatus status) OVERRIDE;
150 virtual void OnWindowUpdate(SpdyStreamId stream_id,
151 uint32 delta_window_size) OVERRIDE;
152 virtual void OnPushPromise(SpdyStreamId stream_id,
153 SpdyStreamId promised_stream_id) OVERRIDE;
154 virtual void OnDataFrameHeader(SpdyStreamId stream_id,
158 // SpdyFramer methods.
159 size_t ProcessInput(const char* data, size_t len);
160 SpdyMajorVersion protocol_version();
162 SpdyFramer::SpdyError error_code() const;
163 SpdyFramer::SpdyState state() const;
164 bool MessageFullyRead();
166 SpdyFrame* CreateSynStream(SpdyStreamId stream_id,
167 SpdyStreamId associated_stream_id,
168 SpdyPriority priority,
169 uint8 credential_slot,
170 SpdyControlFlags flags,
171 const SpdyHeaderBlock* headers);
172 SpdyFrame* CreateSynReply(SpdyStreamId stream_id,
173 SpdyControlFlags flags,
174 const SpdyHeaderBlock* headers);
175 SpdyFrame* CreateRstStream(SpdyStreamId stream_id,
176 SpdyRstStreamStatus status) const;
177 SpdyFrame* CreateSettings(const SettingsMap& values) const;
178 SpdyFrame* CreatePingFrame(uint32 unique_id) const;
179 SpdyFrame* CreateGoAway(
180 SpdyStreamId last_accepted_stream_id,
181 SpdyGoAwayStatus status) const;
182 SpdyFrame* CreateHeaders(SpdyStreamId stream_id,
183 SpdyControlFlags flags,
184 const SpdyHeaderBlock* headers);
185 SpdyFrame* CreateWindowUpdate(
186 SpdyStreamId stream_id,
187 uint32 delta_window_size) const;
188 SpdyFrame* CreateDataFrame(SpdyStreamId stream_id,
191 SpdyDataFlags flags);
193 // Serialize a frame of unknown type.
194 SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame) {
195 return spdy_framer_.SerializeFrame(frame);
198 SpdyPriority GetHighestPriority() const;
200 size_t GetDataFrameMinimumSize() const {
201 return spdy_framer_.GetDataFrameMinimumSize();
204 size_t GetControlFrameHeaderSize() const {
205 return spdy_framer_.GetControlFrameHeaderSize();
208 size_t GetSynStreamMinimumSize() const {
209 return spdy_framer_.GetSynStreamMinimumSize();
212 size_t GetFrameMinimumSize() const {
213 return spdy_framer_.GetFrameMinimumSize();
216 size_t GetFrameMaximumSize() const {
217 return spdy_framer_.GetFrameMaximumSize();
220 size_t GetDataFrameMaximumPayload() const {
221 return spdy_framer_.GetDataFrameMaximumPayload();
224 int frames_received() const { return frames_received_; }
227 // The size of the header_buffer_.
228 enum { kHeaderBufferSize = 32 * 1024 };
230 void InitHeaderStreaming(SpdyStreamId stream_id);
232 SpdyFramer spdy_framer_;
233 BufferedSpdyFramerVisitorInterface* visitor_;
235 // Header block streaming state:
236 char header_buffer_[kHeaderBufferSize];
237 size_t header_buffer_used_;
238 bool header_buffer_valid_;
239 SpdyStreamId header_stream_id_;
240 int frames_received_;
242 // Collection of fields from control frames that we need to
243 // buffer up from the spdy framer.
244 struct ControlFrameFields {
246 SpdyStreamId stream_id;
247 SpdyStreamId associated_stream_id;
248 SpdyPriority priority;
249 uint8 credential_slot;
253 scoped_ptr<ControlFrameFields> control_frame_fields_;
255 DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramer);
260 #endif // NET_SPDY_BUFFERED_SPDY_FRAMER_H_