• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
BufferedSpdyFramerVisitorInterface()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 fin,
53                          const SpdyHeaderBlock& headers) = 0;
54 
55   // Called when a data frame header is received.
56   virtual void OnDataFrameHeader(SpdyStreamId stream_id,
57                                  size_t length,
58                                  bool fin) = 0;
59 
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,
68                                  const char* data,
69                                  size_t len,
70                                  bool fin) = 0;
71 
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;
75 
76   // Called when an individual setting within a SETTINGS frame has been parsed
77   // and validated.
78   virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0;
79 
80   // Called when a SETTINGS frame is received with the ACK flag set.
OnSettingsAck()81   virtual void OnSettingsAck() {}
82 
83   // Called at the completion of parsing SETTINGS id and value tuples.
OnSettingsEnd()84   virtual void OnSettingsEnd() {}
85 
86   // Called when a PING frame has been parsed.
87   virtual void OnPing(SpdyPingId unique_id, bool is_ack) = 0;
88 
89   // Called when a RST_STREAM frame has been parsed.
90   virtual void OnRstStream(SpdyStreamId stream_id,
91                            SpdyRstStreamStatus status) = 0;
92 
93   // Called when a GOAWAY frame has been parsed.
94   virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
95                         SpdyGoAwayStatus status) = 0;
96 
97   // Called when a WINDOW_UPDATE frame has been parsed.
98   virtual void OnWindowUpdate(SpdyStreamId stream_id,
99                               uint32 delta_window_size) = 0;
100 
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;
105 
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;
111 
112  protected:
~BufferedSpdyFramerVisitorInterface()113   virtual ~BufferedSpdyFramerVisitorInterface() {}
114 
115  private:
116   DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramerVisitorInterface);
117 };
118 
119 class NET_EXPORT_PRIVATE BufferedSpdyFramer
120     : public SpdyFramerVisitorInterface {
121  public:
122   BufferedSpdyFramer(SpdyMajorVersion version,
123                      bool enable_compression);
124   virtual ~BufferedSpdyFramer();
125 
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);
131 
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);
136 
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,
142                            bool fin,
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,
150                                  const char* data,
151                                  size_t len,
152                                  bool fin) OVERRIDE;
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,
167                              bool end) OVERRIDE;
168   virtual void OnDataFrameHeader(SpdyStreamId stream_id,
169                                  size_t length,
170                                  bool fin) OVERRIDE;
171   virtual void OnContinuation(SpdyStreamId stream_id, bool end) OVERRIDE;
172   virtual bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) OVERRIDE;
173 
174   // SpdyFramer methods.
175   size_t ProcessInput(const char* data, size_t len);
176   SpdyMajorVersion protocol_version();
177   void Reset();
178   SpdyFramer::SpdyError error_code() const;
179   SpdyFramer::SpdyState state() const;
180   bool MessageFullyRead();
181   bool HasError();
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,
204                              const char* data,
205                              uint32 len,
206                              SpdyDataFlags flags);
207   SpdyFrame* CreatePushPromise(SpdyStreamId stream_id,
208                                SpdyStreamId promised_stream_id,
209                                const SpdyHeaderBlock* headers);
210 
211   // Serialize a frame of unknown type.
SerializeFrame(const SpdyFrameIR & frame)212   SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame) {
213     return spdy_framer_.SerializeFrame(frame);
214   }
215 
216   SpdyPriority GetHighestPriority() const;
217 
GetDataFrameMinimumSize()218   size_t GetDataFrameMinimumSize() const {
219     return spdy_framer_.GetDataFrameMinimumSize();
220   }
221 
GetControlFrameHeaderSize()222   size_t GetControlFrameHeaderSize() const {
223     return spdy_framer_.GetControlFrameHeaderSize();
224   }
225 
GetSynStreamMinimumSize()226   size_t GetSynStreamMinimumSize() const {
227     return spdy_framer_.GetSynStreamMinimumSize();
228   }
229 
GetFrameMinimumSize()230   size_t GetFrameMinimumSize() const {
231     return spdy_framer_.GetFrameMinimumSize();
232   }
233 
GetFrameMaximumSize()234   size_t GetFrameMaximumSize() const {
235     return spdy_framer_.GetFrameMaximumSize();
236   }
237 
GetDataFrameMaximumPayload()238   size_t GetDataFrameMaximumPayload() const {
239     return spdy_framer_.GetDataFrameMaximumPayload();
240   }
241 
frames_received()242   int frames_received() const { return frames_received_; }
243 
244  private:
245   // The size of the header_buffer_.
246   enum { kHeaderBufferSize = 32 * 1024 };
247 
248   void InitHeaderStreaming(SpdyStreamId stream_id);
249 
250   SpdyFramer spdy_framer_;
251   BufferedSpdyFramerVisitorInterface* visitor_;
252 
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_;
259 
260   // Collection of fields from control frames that we need to
261   // buffer up from the spdy framer.
262   struct ControlFrameFields {
263     SpdyFrameType type;
264     SpdyStreamId stream_id;
265     SpdyStreamId associated_stream_id;
266     SpdyStreamId promised_stream_id;
267     SpdyPriority priority;
268     uint8 credential_slot;
269     bool fin;
270     bool unidirectional;
271   };
272   scoped_ptr<ControlFrameFields> control_frame_fields_;
273 
274   DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramer);
275 };
276 
277 }  // namespace net
278 
279 #endif  // NET_SPDY_BUFFERED_SPDY_FRAMER_H_
280