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/spdy/spdy_framer.h"
15 #include "net/spdy/spdy_header_block.h"
16 #include "net/spdy/spdy_protocol.h"
20 class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface
{
22 BufferedSpdyFramerVisitorInterface() {}
24 // Called if an error is detected in the SpdyFrame protocol.
25 virtual void OnError(SpdyFramer::SpdyError error_code
) = 0;
27 // Called if an error is detected in a SPDY stream.
28 virtual void OnStreamError(SpdyStreamId stream_id
,
29 const std::string
& description
) = 0;
31 // Called after all the header data for SYN_STREAM control frame is received.
32 virtual void OnSynStream(SpdyStreamId stream_id
,
33 SpdyStreamId associated_stream_id
,
34 SpdyPriority priority
,
35 uint8 credential_slot
,
38 const SpdyHeaderBlock
& headers
) = 0;
40 // Called after all the header data for SYN_REPLY control frame is received.
41 virtual void OnSynReply(SpdyStreamId stream_id
,
43 const SpdyHeaderBlock
& headers
) = 0;
45 // Called after all the header data for HEADERS control frame is received.
46 virtual void OnHeaders(SpdyStreamId stream_id
,
48 const SpdyHeaderBlock
& headers
) = 0;
50 // Called when data is received.
51 // |stream_id| The stream receiving data.
52 // |data| A buffer containing the data received.
53 // |len| The length of the data buffer.
54 // When the other side has finished sending data on this stream,
55 // this method will be called with a zero-length buffer.
56 virtual void OnStreamFrameData(SpdyStreamId stream_id
,
59 SpdyDataFlags flags
) = 0;
61 // Called when an individual setting within a SETTINGS frame has been parsed
63 virtual void OnSetting(SpdySettingsIds id
, uint8 flags
, uint32 value
) = 0;
65 // Called when a PING frame has been parsed.
66 virtual void OnPing(uint32 unique_id
) = 0;
68 // Called when a RST_STREAM frame has been parsed.
69 virtual void OnRstStream(SpdyStreamId stream_id
, SpdyStatusCodes status
) = 0;
71 // Called when a GOAWAY frame has been parsed.
72 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id
,
73 SpdyGoAwayStatus status
) = 0;
75 // Called when a WINDOW_UPDATE frame has been parsed.
76 virtual void OnWindowUpdate(SpdyStreamId stream_id
,
77 int delta_window_size
) = 0;
79 // Called after a control frame has been compressed to allow the visitor
80 // to record compression statistics.
81 virtual void OnControlFrameCompressed(
82 const SpdyControlFrame
& uncompressed_frame
,
83 const SpdyControlFrame
& compressed_frame
) = 0;
86 virtual ~BufferedSpdyFramerVisitorInterface() {}
89 DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramerVisitorInterface
);
92 class NET_EXPORT_PRIVATE BufferedSpdyFramer
93 : public SpdyFramerVisitorInterface
{
95 BufferedSpdyFramer(int version
,
96 bool enable_compression
);
97 virtual ~BufferedSpdyFramer();
99 // Sets callbacks to be called from the buffered spdy framer. A visitor must
100 // be set, or else the framer will likely crash. It is acceptable for the
101 // visitor to do nothing. If this is called multiple times, only the last
102 // visitor will be used.
103 void set_visitor(BufferedSpdyFramerVisitorInterface
* visitor
);
105 // SpdyFramerVisitorInterface
106 virtual void OnError(SpdyFramer
* spdy_framer
) OVERRIDE
;
107 virtual void OnSynStream(SpdyStreamId stream_id
,
108 SpdyStreamId associated_stream_id
,
109 SpdyPriority priority
,
110 uint8 credential_slot
,
112 bool unidirectional
) OVERRIDE
;
113 virtual void OnSynReply(SpdyStreamId stream_id
, bool fin
) OVERRIDE
;
114 virtual void OnHeaders(SpdyStreamId stream_id
, bool fin
) OVERRIDE
;
115 virtual bool OnCredentialFrameData(const char* frame_data
,
116 size_t len
) OVERRIDE
;
117 virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id
,
118 const char* header_data
,
119 size_t len
) OVERRIDE
;
120 virtual void OnStreamFrameData(SpdyStreamId stream_id
,
123 SpdyDataFlags flags
) OVERRIDE
;
124 virtual void OnSetting(
125 SpdySettingsIds id
, uint8 flags
, uint32 value
) OVERRIDE
;
126 virtual void OnPing(uint32 unique_id
) OVERRIDE
;
127 virtual void OnRstStream(SpdyStreamId stream_id
,
128 SpdyStatusCodes status
) OVERRIDE
;
129 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id
,
130 SpdyGoAwayStatus status
) OVERRIDE
;
131 virtual void OnWindowUpdate(SpdyStreamId stream_id
,
132 int delta_window_size
) OVERRIDE
;
133 virtual void OnDataFrameHeader(const SpdyDataFrame
* frame
) OVERRIDE
;
135 // Called after a control frame has been compressed to allow the visitor
136 // to record compression statistics.
137 virtual void OnControlFrameCompressed(
138 const SpdyControlFrame
& uncompressed_frame
,
139 const SpdyControlFrame
& compressed_frame
) OVERRIDE
;
141 // SpdyFramer methods.
142 size_t ProcessInput(const char* data
, size_t len
);
143 int protocol_version();
145 SpdyFramer::SpdyError
error_code() const;
146 SpdyFramer::SpdyState
state() const;
147 bool MessageFullyRead();
149 SpdySynStreamControlFrame
* CreateSynStream(SpdyStreamId stream_id
,
150 SpdyStreamId associated_stream_id
,
151 SpdyPriority priority
,
152 uint8 credential_slot
,
153 SpdyControlFlags flags
,
155 const SpdyHeaderBlock
* headers
);
156 SpdySynReplyControlFrame
* CreateSynReply(SpdyStreamId stream_id
,
157 SpdyControlFlags flags
,
159 const SpdyHeaderBlock
* headers
);
160 SpdyRstStreamControlFrame
* CreateRstStream(SpdyStreamId stream_id
,
161 SpdyStatusCodes status
) const;
162 SpdySettingsControlFrame
* CreateSettings(const SettingsMap
& values
) const;
163 SpdyPingControlFrame
* CreatePingFrame(uint32 unique_id
) const;
164 SpdyGoAwayControlFrame
* CreateGoAway(
165 SpdyStreamId last_accepted_stream_id
,
166 SpdyGoAwayStatus status
) const;
167 SpdyHeadersControlFrame
* CreateHeaders(SpdyStreamId stream_id
,
168 SpdyControlFlags flags
,
170 const SpdyHeaderBlock
* headers
);
171 SpdyWindowUpdateControlFrame
* CreateWindowUpdate(
172 SpdyStreamId stream_id
,
173 uint32 delta_window_size
) const;
174 SpdyCredentialControlFrame
* CreateCredentialFrame(
175 const SpdyCredential
& credential
) const;
176 SpdyDataFrame
* CreateDataFrame(SpdyStreamId stream_id
,
179 SpdyDataFlags flags
);
180 SpdyPriority
GetHighestPriority() const;
181 bool IsCompressible(const SpdyFrame
& frame
) const;
183 int frames_received() const { return frames_received_
; }
186 // The size of the header_buffer_.
187 enum { kHeaderBufferSize
= 32 * 1024 };
189 void InitHeaderStreaming(SpdyStreamId stream_id
);
191 SpdyFramer spdy_framer_
;
192 BufferedSpdyFramerVisitorInterface
* visitor_
;
194 // Header block streaming state:
195 char header_buffer_
[kHeaderBufferSize
];
196 size_t header_buffer_used_
;
197 bool header_buffer_valid_
;
198 SpdyStreamId header_stream_id_
;
199 int frames_received_
;
201 // Collection of fields from control frames that we need to
202 // buffer up from the spdy framer.
203 struct ControlFrameFields
{
204 SpdyControlType type
;
205 SpdyStreamId stream_id
;
206 SpdyStreamId associated_stream_id
;
207 SpdyPriority priority
;
208 uint8 credential_slot
;
212 scoped_ptr
<ControlFrameFields
> control_frame_fields_
;
214 DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramer
);
219 #endif // NET_SPDY_BUFFERED_SPDY_FRAMER_H_