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                            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.
     81   virtual void OnSettingsAck() {}
     82 
     83   // Called at the completion of parsing SETTINGS id and value tuples.
     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:
    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.
    212   SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame) {
    213     return spdy_framer_.SerializeFrame(frame);
    214   }
    215 
    216   SpdyPriority GetHighestPriority() const;
    217 
    218   size_t GetDataFrameMinimumSize() const {
    219     return spdy_framer_.GetDataFrameMinimumSize();
    220   }
    221 
    222   size_t GetControlFrameHeaderSize() const {
    223     return spdy_framer_.GetControlFrameHeaderSize();
    224   }
    225 
    226   size_t GetSynStreamMinimumSize() const {
    227     return spdy_framer_.GetSynStreamMinimumSize();
    228   }
    229 
    230   size_t GetFrameMinimumSize() const {
    231     return spdy_framer_.GetFrameMinimumSize();
    232   }
    233 
    234   size_t GetFrameMaximumSize() const {
    235     return spdy_framer_.GetFrameMaximumSize();
    236   }
    237 
    238   size_t GetDataFrameMaximumPayload() const {
    239     return spdy_framer_.GetDataFrameMaximumPayload();
    240   }
    241 
    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