buffered_spdy_framer.h revision f2477e01787aa58f445919b809d89e252beef54f
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
19namespace net {
20
21// Returns the SPDY major version corresponding to the given NextProto
22// value, which must represent a SPDY-like protocol.
23NET_EXPORT_PRIVATE SpdyMajorVersion NextProtoToSpdyMajorVersion(
24    NextProto next_proto);
25
26class 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                           uint8 credential_slot,
42                           bool fin,
43                           bool unidirectional,
44                           const SpdyHeaderBlock& headers) = 0;
45
46  // Called after all the header data for SYN_REPLY control frame is received.
47  virtual void OnSynReply(SpdyStreamId stream_id,
48                          bool fin,
49                          const SpdyHeaderBlock& headers) = 0;
50
51  // Called after all the header data for HEADERS control frame is received.
52  virtual void OnHeaders(SpdyStreamId stream_id,
53                         bool fin,
54                         const SpdyHeaderBlock& headers) = 0;
55
56  // Called when data is received.
57  // |stream_id| The stream receiving data.
58  // |data| A buffer containing the data received.
59  // |len| The length of the data buffer (at most 2^24 - 1 for SPDY/3,
60  // but 2^16 - 1 - 8 for SPDY/4).
61  // When the other side has finished sending data on this stream,
62  // this method will be called with a zero-length buffer.
63  virtual void OnStreamFrameData(SpdyStreamId stream_id,
64                                 const char* data,
65                                 size_t len,
66                                 bool fin) = 0;
67
68  // Called when a SETTINGS frame is received.
69  // |clear_persisted| True if the respective flag is set on the SETTINGS frame.
70  virtual void OnSettings(bool clear_persisted) = 0;
71
72  // Called when an individual setting within a SETTINGS frame has been parsed
73  // and validated.
74  virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0;
75
76  // Called when a PING frame has been parsed.
77  virtual void OnPing(uint32 unique_id) = 0;
78
79  // Called when a RST_STREAM frame has been parsed.
80  virtual void OnRstStream(SpdyStreamId stream_id,
81                           SpdyRstStreamStatus status) = 0;
82
83  // Called when a GOAWAY frame has been parsed.
84  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
85                        SpdyGoAwayStatus status) = 0;
86
87  // Called when a WINDOW_UPDATE frame has been parsed.
88  virtual void OnWindowUpdate(SpdyStreamId stream_id,
89                              uint32 delta_window_size) = 0;
90
91  // Called when a PUSH_PROMISE frame has been parsed.
92  virtual void OnPushPromise(SpdyStreamId stream_id,
93                             SpdyStreamId promised_stream_id) = 0;
94
95 protected:
96  virtual ~BufferedSpdyFramerVisitorInterface() {}
97
98 private:
99  DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramerVisitorInterface);
100};
101
102class NET_EXPORT_PRIVATE BufferedSpdyFramer
103    : public SpdyFramerVisitorInterface {
104 public:
105  BufferedSpdyFramer(SpdyMajorVersion version,
106                     bool enable_compression);
107  virtual ~BufferedSpdyFramer();
108
109  // Sets callbacks to be called from the buffered spdy framer.  A visitor must
110  // be set, or else the framer will likely crash.  It is acceptable for the
111  // visitor to do nothing.  If this is called multiple times, only the last
112  // visitor will be used.
113  void set_visitor(BufferedSpdyFramerVisitorInterface* visitor);
114
115  // Set debug callbacks to be called from the framer. The debug visitor is
116  // completely optional and need not be set in order for normal operation.
117  // If this is called multiple times, only the last visitor will be used.
118  void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor);
119
120  // SpdyFramerVisitorInterface
121  virtual void OnError(SpdyFramer* spdy_framer) OVERRIDE;
122  virtual void OnSynStream(SpdyStreamId stream_id,
123                           SpdyStreamId associated_stream_id,
124                           SpdyPriority priority,
125                           uint8 credential_slot,
126                           bool fin,
127                           bool unidirectional) OVERRIDE;
128  virtual void OnSynReply(SpdyStreamId stream_id, bool fin) OVERRIDE;
129  virtual void OnHeaders(SpdyStreamId stream_id, bool fin) OVERRIDE;
130  virtual bool OnCredentialFrameData(const char* frame_data,
131                                     size_t len) OVERRIDE;
132  virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id,
133                                        const char* header_data,
134                                        size_t len) OVERRIDE;
135  virtual void OnStreamFrameData(SpdyStreamId stream_id,
136                                 const char* data,
137                                 size_t len,
138                                 bool fin) OVERRIDE;
139  virtual void OnSettings(bool clear_persisted) OVERRIDE;
140  virtual void OnSetting(
141      SpdySettingsIds id, uint8 flags, uint32 value) OVERRIDE;
142  virtual void OnPing(uint32 unique_id) OVERRIDE;
143  virtual void OnRstStream(SpdyStreamId stream_id,
144                           SpdyRstStreamStatus status) OVERRIDE;
145  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
146                        SpdyGoAwayStatus status) OVERRIDE;
147  virtual void OnWindowUpdate(SpdyStreamId stream_id,
148                              uint32 delta_window_size) OVERRIDE;
149  virtual void OnPushPromise(SpdyStreamId stream_id,
150                             SpdyStreamId promised_stream_id) OVERRIDE;
151  virtual void OnDataFrameHeader(SpdyStreamId stream_id,
152                                 size_t length,
153                                 bool fin) OVERRIDE;
154
155  // SpdyFramer methods.
156  size_t ProcessInput(const char* data, size_t len);
157  SpdyMajorVersion protocol_version();
158  void Reset();
159  SpdyFramer::SpdyError error_code() const;
160  SpdyFramer::SpdyState state() const;
161  bool MessageFullyRead();
162  bool HasError();
163  SpdyFrame* CreateSynStream(SpdyStreamId stream_id,
164                             SpdyStreamId associated_stream_id,
165                             SpdyPriority priority,
166                             uint8 credential_slot,
167                             SpdyControlFlags flags,
168                             bool compressed,
169                             const SpdyHeaderBlock* headers);
170  SpdyFrame* CreateSynReply(SpdyStreamId stream_id,
171                            SpdyControlFlags flags,
172                            bool compressed,
173                            const SpdyHeaderBlock* headers);
174  SpdyFrame* CreateRstStream(SpdyStreamId stream_id,
175                             SpdyRstStreamStatus status) const;
176  SpdyFrame* CreateSettings(const SettingsMap& values) const;
177  SpdyFrame* CreatePingFrame(uint32 unique_id) const;
178  SpdyFrame* CreateGoAway(
179      SpdyStreamId last_accepted_stream_id,
180      SpdyGoAwayStatus status) const;
181  SpdyFrame* CreateHeaders(SpdyStreamId stream_id,
182                           SpdyControlFlags flags,
183                           bool compressed,
184                           const SpdyHeaderBlock* headers);
185  SpdyFrame* CreateWindowUpdate(
186      SpdyStreamId stream_id,
187      uint32 delta_window_size) const;
188  SpdyFrame* CreateDataFrame(SpdyStreamId stream_id,
189                             const char* data,
190                             uint32 len,
191                             SpdyDataFlags flags);
192
193  // Serialize a frame of unknown type.
194  SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame) {
195    return spdy_framer_.SerializeFrame(frame);
196  }
197
198  SpdyPriority GetHighestPriority() const;
199
200  size_t GetDataFrameMinimumSize() const {
201    return spdy_framer_.GetDataFrameMinimumSize();
202  }
203
204  size_t GetControlFrameHeaderSize() const {
205    return spdy_framer_.GetControlFrameHeaderSize();
206  }
207
208  size_t GetSynStreamMinimumSize() const {
209    return spdy_framer_.GetSynStreamMinimumSize();
210  }
211
212  size_t GetFrameMinimumSize() const {
213    return spdy_framer_.GetFrameMinimumSize();
214  }
215
216  size_t GetFrameMaximumSize() const {
217    return spdy_framer_.GetFrameMaximumSize();
218  }
219
220  size_t GetDataFrameMaximumPayload() const {
221    return spdy_framer_.GetDataFrameMaximumPayload();
222  }
223
224  int frames_received() const { return frames_received_; }
225
226 private:
227  // The size of the header_buffer_.
228  enum { kHeaderBufferSize = 32 * 1024 };
229
230  void InitHeaderStreaming(SpdyStreamId stream_id);
231
232  SpdyFramer spdy_framer_;
233  BufferedSpdyFramerVisitorInterface* visitor_;
234
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_;
241
242  // Collection of fields from control frames that we need to
243  // buffer up from the spdy framer.
244  struct ControlFrameFields {
245    SpdyFrameType type;
246    SpdyStreamId stream_id;
247    SpdyStreamId associated_stream_id;
248    SpdyPriority priority;
249    uint8 credential_slot;
250    bool fin;
251    bool unidirectional;
252  };
253  scoped_ptr<ControlFrameFields> control_frame_fields_;
254
255  DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramer);
256};
257
258}  // namespace net
259
260#endif  // NET_SPDY_BUFFERED_SPDY_FRAMER_H_
261