OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #ifndef NET_SPDY_BUFFERED_SPDY_FRAMER_H_ | |
6 #define NET_SPDY_BUFFERED_SPDY_FRAMER_H_ | |
7 | |
8 #include <string> | |
9 | |
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" | |
18 | |
19 namespace net { | |
20 | |
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); | |
25 | |
26 class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface { | |
27 public: | |
28 BufferedSpdyFramerVisitorInterface() {} | |
29 | |
30 // Called if an error is detected in the SpdyFrame protocol. | |
31 virtual void OnError(SpdyFramer::SpdyError error_code) = 0; | |
32 | |
33 // Called if an error is detected in a SPDY stream. | |
34 virtual void OnStreamError(SpdyStreamId stream_id, | |
35 const std::string& description) = 0; | |
36 | |
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 bool fin, | |
42 bool unidirectional, | |
43 const SpdyHeaderBlock& headers) = 0; | |
44 | |
45 // Called after all the header data for SYN_REPLY control frame is received. | |
46 virtual void OnSynReply(SpdyStreamId stream_id, | |
47 bool fin, | |
48 const SpdyHeaderBlock& headers) = 0; | |
49 | |
50 // Called after all the header data for HEADERS control frame is received. | |
51 virtual void OnHeaders(SpdyStreamId stream_id, | |
52 bool has_priority, | |
53 SpdyPriority priority, | |
54 bool fin, | |
55 const SpdyHeaderBlock& headers) = 0; | |
56 | |
57 // Called when a data frame header is received. | |
58 virtual void OnDataFrameHeader(SpdyStreamId stream_id, | |
59 size_t length, | |
60 bool fin) = 0; | |
61 | |
62 // Called when data is received. | |
63 // |stream_id| The stream receiving data. | |
64 // |data| A buffer containing the data received. | |
65 // |len| The length of the data buffer (at most 2^24 - 1 for SPDY/3, | |
66 // but 2^16 - 1 - 8 for SPDY/4). | |
67 // When the other side has finished sending data on this stream, | |
68 // this method will be called with a zero-length buffer. | |
69 virtual void OnStreamFrameData(SpdyStreamId stream_id, | |
70 const char* data, | |
71 size_t len, | |
72 bool fin) = 0; | |
73 | |
74 // Called when a SETTINGS frame is received. | |
75 // |clear_persisted| True if the respective flag is set on the SETTINGS frame. | |
76 virtual void OnSettings(bool clear_persisted) = 0; | |
77 | |
78 // Called when an individual setting within a SETTINGS frame has been parsed | |
79 // and validated. | |
80 virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0; | |
81 | |
82 // Called when a SETTINGS frame is received with the ACK flag set. | |
83 virtual void OnSettingsAck() {} | |
84 | |
85 // Called at the completion of parsing SETTINGS id and value tuples. | |
86 virtual void OnSettingsEnd() {} | |
87 | |
88 // Called when a PING frame has been parsed. | |
89 virtual void OnPing(SpdyPingId unique_id, bool is_ack) = 0; | |
90 | |
91 // Called when a RST_STREAM frame has been parsed. | |
92 virtual void OnRstStream(SpdyStreamId stream_id, | |
93 SpdyRstStreamStatus status) = 0; | |
94 | |
95 // Called when a GOAWAY frame has been parsed. | |
96 virtual void OnGoAway(SpdyStreamId last_accepted_stream_id, | |
97 SpdyGoAwayStatus status) = 0; | |
98 | |
99 // Called when a WINDOW_UPDATE frame has been parsed. | |
100 virtual void OnWindowUpdate(SpdyStreamId stream_id, | |
101 uint32 delta_window_size) = 0; | |
102 | |
103 // Called when a PUSH_PROMISE frame has been parsed. | |
104 virtual void OnPushPromise(SpdyStreamId stream_id, | |
105 SpdyStreamId promised_stream_id, | |
106 const SpdyHeaderBlock& headers) = 0; | |
107 | |
108 // Called when a frame type we don't recognize is received. | |
109 // Return true if this appears to be a valid extension frame, false otherwise. | |
110 // We distinguish between extension frames and nonsense by checking | |
111 // whether the stream id is valid. | |
112 virtual bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) = 0; | |
113 | |
114 protected: | |
115 virtual ~BufferedSpdyFramerVisitorInterface() {} | |
116 | |
117 private: | |
118 DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramerVisitorInterface); | |
119 }; | |
120 | |
121 class NET_EXPORT_PRIVATE BufferedSpdyFramer | |
122 : public SpdyFramerVisitorInterface { | |
123 public: | |
124 BufferedSpdyFramer(SpdyMajorVersion version, | |
125 bool enable_compression); | |
126 ~BufferedSpdyFramer() override; | |
127 | |
128 // Sets callbacks to be called from the buffered spdy framer. A visitor must | |
129 // be set, or else the framer will likely crash. It is acceptable for the | |
130 // visitor to do nothing. If this is called multiple times, only the last | |
131 // visitor will be used. | |
132 void set_visitor(BufferedSpdyFramerVisitorInterface* visitor); | |
133 | |
134 // Set debug callbacks to be called from the framer. The debug visitor is | |
135 // completely optional and need not be set in order for normal operation. | |
136 // If this is called multiple times, only the last visitor will be used. | |
137 void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor); | |
138 | |
139 // SpdyFramerVisitorInterface | |
140 void OnError(SpdyFramer* spdy_framer) override; | |
141 void OnSynStream(SpdyStreamId stream_id, | |
142 SpdyStreamId associated_stream_id, | |
143 SpdyPriority priority, | |
144 bool fin, | |
145 bool unidirectional) override; | |
146 void OnSynReply(SpdyStreamId stream_id, bool fin) override; | |
147 void OnHeaders(SpdyStreamId stream_id, | |
148 bool has_priority, | |
149 SpdyPriority priority, | |
150 bool fin, | |
151 bool end) override; | |
152 bool OnControlFrameHeaderData(SpdyStreamId stream_id, | |
153 const char* header_data, | |
154 size_t len) override; | |
155 void OnStreamFrameData(SpdyStreamId stream_id, | |
156 const char* data, | |
157 size_t len, | |
158 bool fin) override; | |
159 void OnSettings(bool clear_persisted) override; | |
160 void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) override; | |
161 void OnSettingsAck() override; | |
162 void OnSettingsEnd() override; | |
163 void OnPing(SpdyPingId unique_id, bool is_ack) override; | |
164 void OnRstStream(SpdyStreamId stream_id, SpdyRstStreamStatus status) override; | |
165 void OnGoAway(SpdyStreamId last_accepted_stream_id, | |
166 SpdyGoAwayStatus status) override; | |
167 void OnWindowUpdate(SpdyStreamId stream_id, | |
168 uint32 delta_window_size) override; | |
169 void OnPushPromise(SpdyStreamId stream_id, | |
170 SpdyStreamId promised_stream_id, | |
171 bool end) override; | |
172 void OnDataFrameHeader(SpdyStreamId stream_id, | |
173 size_t length, | |
174 bool fin) override; | |
175 void OnContinuation(SpdyStreamId stream_id, bool end) override; | |
176 bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override; | |
177 | |
178 // SpdyFramer methods. | |
179 size_t ProcessInput(const char* data, size_t len); | |
180 SpdyMajorVersion protocol_version(); | |
181 void Reset(); | |
182 SpdyFramer::SpdyError error_code() const; | |
183 SpdyFramer::SpdyState state() const; | |
184 bool MessageFullyRead(); | |
185 bool HasError(); | |
186 SpdyFrame* CreateSynStream(SpdyStreamId stream_id, | |
187 SpdyStreamId associated_stream_id, | |
188 SpdyPriority priority, | |
189 SpdyControlFlags flags, | |
190 const SpdyHeaderBlock* headers); | |
191 SpdyFrame* CreateSynReply(SpdyStreamId stream_id, | |
192 SpdyControlFlags flags, | |
193 const SpdyHeaderBlock* headers); | |
194 SpdyFrame* CreateRstStream(SpdyStreamId stream_id, | |
195 SpdyRstStreamStatus status) const; | |
196 SpdyFrame* CreateSettings(const SettingsMap& values) const; | |
197 SpdyFrame* CreatePingFrame(SpdyPingId unique_id, bool is_ack) const; | |
198 SpdyFrame* CreateGoAway( | |
199 SpdyStreamId last_accepted_stream_id, | |
200 SpdyGoAwayStatus status) const; | |
201 SpdyFrame* CreateHeaders(SpdyStreamId stream_id, | |
202 SpdyControlFlags flags, | |
203 SpdyPriority priority, | |
204 const SpdyHeaderBlock* headers); | |
205 SpdyFrame* CreateWindowUpdate( | |
206 SpdyStreamId stream_id, | |
207 uint32 delta_window_size) const; | |
208 SpdyFrame* CreateDataFrame(SpdyStreamId stream_id, | |
209 const char* data, | |
210 uint32 len, | |
211 SpdyDataFlags flags); | |
212 SpdyFrame* CreatePushPromise(SpdyStreamId stream_id, | |
213 SpdyStreamId promised_stream_id, | |
214 const SpdyHeaderBlock* headers); | |
215 | |
216 // Serialize a frame of unknown type. | |
217 SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame) { | |
218 return spdy_framer_.SerializeFrame(frame); | |
219 } | |
220 | |
221 SpdyPriority GetHighestPriority() const; | |
222 | |
223 size_t GetDataFrameMinimumSize() const { | |
224 return spdy_framer_.GetDataFrameMinimumSize(); | |
225 } | |
226 | |
227 size_t GetControlFrameHeaderSize() const { | |
228 return spdy_framer_.GetControlFrameHeaderSize(); | |
229 } | |
230 | |
231 size_t GetSynStreamMinimumSize() const { | |
232 return spdy_framer_.GetSynStreamMinimumSize(); | |
233 } | |
234 | |
235 size_t GetFrameMinimumSize() const { | |
236 return spdy_framer_.GetFrameMinimumSize(); | |
237 } | |
238 | |
239 size_t GetFrameMaximumSize() const { | |
240 return spdy_framer_.GetFrameMaximumSize(); | |
241 } | |
242 | |
243 size_t GetDataFrameMaximumPayload() const { | |
244 return spdy_framer_.GetDataFrameMaximumPayload(); | |
245 } | |
246 | |
247 int frames_received() const { return frames_received_; } | |
248 | |
249 private: | |
250 // The size of the header_buffer_. | |
251 enum { kHeaderBufferSize = 32 * 1024 }; | |
252 | |
253 void InitHeaderStreaming(SpdyStreamId stream_id); | |
254 | |
255 SpdyFramer spdy_framer_; | |
256 BufferedSpdyFramerVisitorInterface* visitor_; | |
257 | |
258 // Header block streaming state: | |
259 char header_buffer_[kHeaderBufferSize]; | |
260 size_t header_buffer_used_; | |
261 bool header_buffer_valid_; | |
262 SpdyStreamId header_stream_id_; | |
263 int frames_received_; | |
264 | |
265 // Collection of fields from control frames that we need to | |
266 // buffer up from the spdy framer. | |
267 struct ControlFrameFields { | |
268 SpdyFrameType type; | |
269 SpdyStreamId stream_id; | |
270 SpdyStreamId associated_stream_id; | |
271 SpdyStreamId promised_stream_id; | |
272 bool has_priority; | |
273 SpdyPriority priority; | |
274 uint8 credential_slot; | |
275 bool fin; | |
276 bool unidirectional; | |
277 }; | |
278 scoped_ptr<ControlFrameFields> control_frame_fields_; | |
279 | |
280 DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramer); | |
281 }; | |
282 | |
283 } // namespace net | |
284 | |
285 #endif // NET_SPDY_BUFFERED_SPDY_FRAMER_H_ | |
OLD | NEW |