Home | History | Annotate | Download | only in spdy
      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                            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 
    102 class 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   int 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* CreateCredentialFrame(
    189       const SpdyCredential& credential) const;
    190   SpdyFrame* CreateDataFrame(SpdyStreamId stream_id,
    191                              const char* data,
    192                              uint32 len,
    193                              SpdyDataFlags flags);
    194 
    195   // Serialize a frame of unknown type.
    196   SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame) {
    197     return spdy_framer_.SerializeFrame(frame);
    198   }
    199 
    200   SpdyPriority GetHighestPriority() const;
    201 
    202   size_t GetDataFrameMinimumSize() const {
    203     return spdy_framer_.GetDataFrameMinimumSize();
    204   }
    205 
    206   size_t GetControlFrameHeaderSize() const {
    207     return spdy_framer_.GetControlFrameHeaderSize();
    208   }
    209 
    210   size_t GetSynStreamMinimumSize() const {
    211     return spdy_framer_.GetSynStreamMinimumSize();
    212   }
    213 
    214   size_t GetFrameMinimumSize() const {
    215     return spdy_framer_.GetFrameMinimumSize();
    216   }
    217 
    218   size_t GetFrameMaximumSize() const {
    219     return spdy_framer_.GetFrameMaximumSize();
    220   }
    221 
    222   size_t GetDataFrameMaximumPayload() const {
    223     return spdy_framer_.GetDataFrameMaximumPayload();
    224   }
    225 
    226   int frames_received() const { return frames_received_; }
    227 
    228  private:
    229   // The size of the header_buffer_.
    230   enum { kHeaderBufferSize = 32 * 1024 };
    231 
    232   void InitHeaderStreaming(SpdyStreamId stream_id);
    233 
    234   SpdyFramer spdy_framer_;
    235   BufferedSpdyFramerVisitorInterface* visitor_;
    236 
    237   // Header block streaming state:
    238   char header_buffer_[kHeaderBufferSize];
    239   size_t header_buffer_used_;
    240   bool header_buffer_valid_;
    241   SpdyStreamId header_stream_id_;
    242   int frames_received_;
    243 
    244   // Collection of fields from control frames that we need to
    245   // buffer up from the spdy framer.
    246   struct ControlFrameFields {
    247     SpdyFrameType type;
    248     SpdyStreamId stream_id;
    249     SpdyStreamId associated_stream_id;
    250     SpdyPriority priority;
    251     uint8 credential_slot;
    252     bool fin;
    253     bool unidirectional;
    254   };
    255   scoped_ptr<ControlFrameFields> control_frame_fields_;
    256 
    257   DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramer);
    258 };
    259 
    260 }  // namespace net
    261 
    262 #endif  // NET_SPDY_BUFFERED_SPDY_FRAMER_H_
    263