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
,
43 const SpdyHeaderBlock
& headers
) = 0;
45 // Called after all the header data for SYN_REPLY control frame is received.
46 virtual void OnSynReply(SpdyStreamId stream_id
,
48 const SpdyHeaderBlock
& headers
) = 0;
50 // Called after all the header data for HEADERS control frame is received.
51 virtual void OnHeaders(SpdyStreamId stream_id
,
53 const SpdyHeaderBlock
& headers
) = 0;
55 // Called when a data frame header is received.
56 virtual void OnDataFrameHeader(SpdyStreamId stream_id
,
60 // Called when data is received.
61 // |stream_id| The stream receiving data.
62 // |data| A buffer containing the data received.
63 // |len| The length of the data buffer (at most 2^24 - 1 for SPDY/3,
64 // but 2^16 - 1 - 8 for SPDY/4).
65 // When the other side has finished sending data on this stream,
66 // this method will be called with a zero-length buffer.
67 virtual void OnStreamFrameData(SpdyStreamId stream_id
,
72 // Called when a SETTINGS frame is received.
73 // |clear_persisted| True if the respective flag is set on the SETTINGS frame.
74 virtual void OnSettings(bool clear_persisted
) = 0;
76 // Called when an individual setting within a SETTINGS frame has been parsed
78 virtual void OnSetting(SpdySettingsIds id
, uint8 flags
, uint32 value
) = 0;
80 // Called when a SETTINGS frame is received with the ACK flag set.
81 virtual void OnSettingsAck() {}
83 // Called at the completion of parsing SETTINGS id and value tuples.
84 virtual void OnSettingsEnd() {}
86 // Called when a PING frame has been parsed.
87 virtual void OnPing(SpdyPingId unique_id
, bool is_ack
) = 0;
89 // Called when a RST_STREAM frame has been parsed.
90 virtual void OnRstStream(SpdyStreamId stream_id
,
91 SpdyRstStreamStatus status
) = 0;
93 // Called when a GOAWAY frame has been parsed.
94 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id
,
95 SpdyGoAwayStatus status
) = 0;
97 // Called when a WINDOW_UPDATE frame has been parsed.
98 virtual void OnWindowUpdate(SpdyStreamId stream_id
,
99 uint32 delta_window_size
) = 0;
101 // Called when a PUSH_PROMISE frame has been parsed.
102 virtual void OnPushPromise(SpdyStreamId stream_id
,
103 SpdyStreamId promised_stream_id
,
104 const SpdyHeaderBlock
& headers
) = 0;
106 // Called when a frame type we don't recognize is received.
107 // Return true if this appears to be a valid extension frame, false otherwise.
108 // We distinguish between extension frames and nonsense by checking
109 // whether the stream id is valid.
110 virtual bool OnUnknownFrame(SpdyStreamId stream_id
, int frame_type
) = 0;
113 virtual ~BufferedSpdyFramerVisitorInterface() {}
116 DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramerVisitorInterface
);
119 class NET_EXPORT_PRIVATE BufferedSpdyFramer
120 : public SpdyFramerVisitorInterface
{
122 BufferedSpdyFramer(SpdyMajorVersion version
,
123 bool enable_compression
);
124 virtual ~BufferedSpdyFramer();
126 // Sets callbacks to be called from the buffered spdy framer. A visitor must
127 // be set, or else the framer will likely crash. It is acceptable for the
128 // visitor to do nothing. If this is called multiple times, only the last
129 // visitor will be used.
130 void set_visitor(BufferedSpdyFramerVisitorInterface
* visitor
);
132 // Set debug callbacks to be called from the framer. The debug visitor is
133 // completely optional and need not be set in order for normal operation.
134 // If this is called multiple times, only the last visitor will be used.
135 void set_debug_visitor(SpdyFramerDebugVisitorInterface
* debug_visitor
);
137 // SpdyFramerVisitorInterface
138 virtual void OnError(SpdyFramer
* spdy_framer
) OVERRIDE
;
139 virtual void OnSynStream(SpdyStreamId stream_id
,
140 SpdyStreamId associated_stream_id
,
141 SpdyPriority priority
,
143 bool unidirectional
) OVERRIDE
;
144 virtual void OnSynReply(SpdyStreamId stream_id
, bool fin
) OVERRIDE
;
145 virtual void OnHeaders(SpdyStreamId stream_id
, bool fin
, bool end
) OVERRIDE
;
146 virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id
,
147 const char* header_data
,
148 size_t len
) OVERRIDE
;
149 virtual void OnStreamFrameData(SpdyStreamId stream_id
,
153 virtual void OnSettings(bool clear_persisted
) OVERRIDE
;
154 virtual void OnSetting(
155 SpdySettingsIds id
, uint8 flags
, uint32 value
) OVERRIDE
;
156 virtual void OnSettingsAck() OVERRIDE
;
157 virtual void OnSettingsEnd() OVERRIDE
;
158 virtual void OnPing(SpdyPingId unique_id
, bool is_ack
) OVERRIDE
;
159 virtual void OnRstStream(SpdyStreamId stream_id
,
160 SpdyRstStreamStatus status
) OVERRIDE
;
161 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id
,
162 SpdyGoAwayStatus status
) OVERRIDE
;
163 virtual void OnWindowUpdate(SpdyStreamId stream_id
,
164 uint32 delta_window_size
) OVERRIDE
;
165 virtual void OnPushPromise(SpdyStreamId stream_id
,
166 SpdyStreamId promised_stream_id
,
168 virtual void OnDataFrameHeader(SpdyStreamId stream_id
,
171 virtual void OnContinuation(SpdyStreamId stream_id
, bool end
) OVERRIDE
;
172 virtual bool OnUnknownFrame(SpdyStreamId stream_id
, int frame_type
) OVERRIDE
;
174 // SpdyFramer methods.
175 size_t ProcessInput(const char* data
, size_t len
);
176 SpdyMajorVersion
protocol_version();
178 SpdyFramer::SpdyError
error_code() const;
179 SpdyFramer::SpdyState
state() const;
180 bool MessageFullyRead();
182 SpdyFrame
* CreateSynStream(SpdyStreamId stream_id
,
183 SpdyStreamId associated_stream_id
,
184 SpdyPriority priority
,
185 SpdyControlFlags flags
,
186 const SpdyHeaderBlock
* headers
);
187 SpdyFrame
* CreateSynReply(SpdyStreamId stream_id
,
188 SpdyControlFlags flags
,
189 const SpdyHeaderBlock
* headers
);
190 SpdyFrame
* CreateRstStream(SpdyStreamId stream_id
,
191 SpdyRstStreamStatus status
) const;
192 SpdyFrame
* CreateSettings(const SettingsMap
& values
) const;
193 SpdyFrame
* CreatePingFrame(uint32 unique_id
, bool is_ack
) const;
194 SpdyFrame
* CreateGoAway(
195 SpdyStreamId last_accepted_stream_id
,
196 SpdyGoAwayStatus status
) const;
197 SpdyFrame
* CreateHeaders(SpdyStreamId stream_id
,
198 SpdyControlFlags flags
,
199 const SpdyHeaderBlock
* headers
);
200 SpdyFrame
* CreateWindowUpdate(
201 SpdyStreamId stream_id
,
202 uint32 delta_window_size
) const;
203 SpdyFrame
* CreateDataFrame(SpdyStreamId stream_id
,
206 SpdyDataFlags flags
);
207 SpdyFrame
* CreatePushPromise(SpdyStreamId stream_id
,
208 SpdyStreamId promised_stream_id
,
209 const SpdyHeaderBlock
* headers
);
211 // Serialize a frame of unknown type.
212 SpdySerializedFrame
* SerializeFrame(const SpdyFrameIR
& frame
) {
213 return spdy_framer_
.SerializeFrame(frame
);
216 SpdyPriority
GetHighestPriority() const;
218 size_t GetDataFrameMinimumSize() const {
219 return spdy_framer_
.GetDataFrameMinimumSize();
222 size_t GetControlFrameHeaderSize() const {
223 return spdy_framer_
.GetControlFrameHeaderSize();
226 size_t GetSynStreamMinimumSize() const {
227 return spdy_framer_
.GetSynStreamMinimumSize();
230 size_t GetFrameMinimumSize() const {
231 return spdy_framer_
.GetFrameMinimumSize();
234 size_t GetFrameMaximumSize() const {
235 return spdy_framer_
.GetFrameMaximumSize();
238 size_t GetDataFrameMaximumPayload() const {
239 return spdy_framer_
.GetDataFrameMaximumPayload();
242 int frames_received() const { return frames_received_
; }
245 // The size of the header_buffer_.
246 enum { kHeaderBufferSize
= 32 * 1024 };
248 void InitHeaderStreaming(SpdyStreamId stream_id
);
250 SpdyFramer spdy_framer_
;
251 BufferedSpdyFramerVisitorInterface
* visitor_
;
253 // Header block streaming state:
254 char header_buffer_
[kHeaderBufferSize
];
255 size_t header_buffer_used_
;
256 bool header_buffer_valid_
;
257 SpdyStreamId header_stream_id_
;
258 int frames_received_
;
260 // Collection of fields from control frames that we need to
261 // buffer up from the spdy framer.
262 struct ControlFrameFields
{
264 SpdyStreamId stream_id
;
265 SpdyStreamId associated_stream_id
;
266 SpdyStreamId promised_stream_id
;
267 SpdyPriority priority
;
268 uint8 credential_slot
;
272 scoped_ptr
<ControlFrameFields
> control_frame_fields_
;
274 DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramer
);
279 #endif // NET_SPDY_BUFFERED_SPDY_FRAMER_H_