15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_SPDY_BUFFERED_SPDY_FRAMER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_SPDY_BUFFERED_SPDY_FRAMER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h"
14558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "net/socket/next_proto.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_framer.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_header_block.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_protocol.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Returns the SPDY major version corresponding to the given NextProto
22558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// value, which must represent a SPDY-like protocol.
23558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochNET_EXPORT_PRIVATE SpdyMajorVersion NextProtoToSpdyMajorVersion(
24558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    NextProto next_proto);
25558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BufferedSpdyFramerVisitorInterface() {}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called if an error is detected in the SpdyFrame protocol.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnError(SpdyFramer::SpdyError error_code) = 0;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called if an error is detected in a SPDY stream.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnStreamError(SpdyStreamId stream_id,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const std::string& description) = 0;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called after all the header data for SYN_STREAM control frame is received.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnSynStream(SpdyStreamId stream_id,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           SpdyStreamId associated_stream_id,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           SpdyPriority priority,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           bool fin,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           bool unidirectional,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const SpdyHeaderBlock& headers) = 0;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called after all the header data for SYN_REPLY control frame is received.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnSynReply(SpdyStreamId stream_id,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          bool fin,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const SpdyHeaderBlock& headers) = 0;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called after all the header data for HEADERS control frame is received.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnHeaders(SpdyStreamId stream_id,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         bool fin,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const SpdyHeaderBlock& headers) = 0;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Called when a data frame header is received.
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void OnDataFrameHeader(SpdyStreamId stream_id,
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 size_t length,
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 bool fin) = 0;
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when data is received.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |stream_id| The stream receiving data.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |data| A buffer containing the data received.
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |len| The length of the data buffer (at most 2^24 - 1 for SPDY/3,
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // but 2^16 - 1 - 8 for SPDY/4).
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When the other side has finished sending data on this stream,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this method will be called with a zero-length buffer.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnStreamFrameData(SpdyStreamId stream_id,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const char* data,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 size_t len,
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 bool fin) = 0;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Called when a SETTINGS frame is received.
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // |clear_persisted| True if the respective flag is set on the SETTINGS frame.
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnSettings(bool clear_persisted) = 0;
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when an individual setting within a SETTINGS frame has been parsed
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and validated.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Called when a SETTINGS frame is received with the ACK flag set.
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnSettingsAck() {}
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Called at the completion of parsing SETTINGS id and value tuples.
8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual void OnSettingsEnd() {}
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a PING frame has been parsed.
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnPing(SpdyPingId unique_id, bool is_ack) = 0;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a RST_STREAM frame has been parsed.
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnRstStream(SpdyStreamId stream_id,
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           SpdyRstStreamStatus status) = 0;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a GOAWAY frame has been parsed.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        SpdyGoAwayStatus status) = 0;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when a WINDOW_UPDATE frame has been parsed.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowUpdate(SpdyStreamId stream_id,
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              uint32 delta_window_size) = 0;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Called when a PUSH_PROMISE frame has been parsed.
1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual void OnPushPromise(SpdyStreamId stream_id,
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             SpdyStreamId promised_stream_id,
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             const SpdyHeaderBlock& headers) = 0;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Called when a frame type we don't recognize is received.
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Return true if this appears to be a valid extension frame, false otherwise.
10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // We distinguish between extension frames and nonsense by checking
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // whether the stream id is valid.
11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) = 0;
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~BufferedSpdyFramerVisitorInterface() {}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramerVisitorInterface);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE BufferedSpdyFramer
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public SpdyFramerVisitorInterface {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  BufferedSpdyFramer(SpdyMajorVersion version,
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     bool enable_compression);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~BufferedSpdyFramer();
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets callbacks to be called from the buffered spdy framer.  A visitor must
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be set, or else the framer will likely crash.  It is acceptable for the
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // visitor to do nothing.  If this is called multiple times, only the last
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // visitor will be used.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_visitor(BufferedSpdyFramerVisitorInterface* visitor);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Set debug callbacks to be called from the framer. The debug visitor is
1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // completely optional and need not be set in order for normal operation.
1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // If this is called multiple times, only the last visitor will be used.
1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor);
1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SpdyFramerVisitorInterface
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnError(SpdyFramer* spdy_framer) OVERRIDE;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnSynStream(SpdyStreamId stream_id,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           SpdyStreamId associated_stream_id,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           SpdyPriority priority,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           bool fin,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           bool unidirectional) OVERRIDE;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnSynReply(SpdyStreamId stream_id, bool fin) OVERRIDE;
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnHeaders(SpdyStreamId stream_id, bool fin, bool end) OVERRIDE;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const char* header_data,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        size_t len) OVERRIDE;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnStreamFrameData(SpdyStreamId stream_id,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const char* data,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 size_t len,
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 bool fin) OVERRIDE;
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnSettings(bool clear_persisted) OVERRIDE;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnSetting(
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SpdySettingsIds id, uint8 flags, uint32 value) OVERRIDE;
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnSettingsAck() OVERRIDE;
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnSettingsEnd() OVERRIDE;
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnPing(SpdyPingId unique_id, bool is_ack) OVERRIDE;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnRstStream(SpdyStreamId stream_id,
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           SpdyRstStreamStatus status) OVERRIDE;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        SpdyGoAwayStatus status) OVERRIDE;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowUpdate(SpdyStreamId stream_id,
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              uint32 delta_window_size) OVERRIDE;
1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual void OnPushPromise(SpdyStreamId stream_id,
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             SpdyStreamId promised_stream_id,
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             bool end) OVERRIDE;
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnDataFrameHeader(SpdyStreamId stream_id,
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 size_t length,
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 bool fin) OVERRIDE;
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void OnContinuation(SpdyStreamId stream_id, bool end) OVERRIDE;
17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  virtual bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) OVERRIDE;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SpdyFramer methods.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t ProcessInput(const char* data, size_t len);
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SpdyMajorVersion protocol_version();
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer::SpdyError error_code() const;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer::SpdyState state() const;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool MessageFullyRead();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool HasError();
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFrame* CreateSynStream(SpdyStreamId stream_id,
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             SpdyStreamId associated_stream_id,
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             SpdyPriority priority,
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             SpdyControlFlags flags,
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const SpdyHeaderBlock* headers);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFrame* CreateSynReply(SpdyStreamId stream_id,
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            SpdyControlFlags flags,
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            const SpdyHeaderBlock* headers);
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFrame* CreateRstStream(SpdyStreamId stream_id,
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             SpdyRstStreamStatus status) const;
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFrame* CreateSettings(const SettingsMap& values) const;
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SpdyFrame* CreatePingFrame(uint32 unique_id, bool is_ack) const;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFrame* CreateGoAway(
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SpdyStreamId last_accepted_stream_id,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SpdyGoAwayStatus status) const;
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFrame* CreateHeaders(SpdyStreamId stream_id,
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           SpdyControlFlags flags,
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const SpdyHeaderBlock* headers);
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFrame* CreateWindowUpdate(
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SpdyStreamId stream_id,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      uint32 delta_window_size) const;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpdyFrame* CreateDataFrame(SpdyStreamId stream_id,
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const char* data,
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             uint32 len,
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             SpdyDataFlags flags);
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SpdyFrame* CreatePushPromise(SpdyStreamId stream_id,
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                               SpdyStreamId promised_stream_id,
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                               const SpdyHeaderBlock* headers);
210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Serialize a frame of unknown type.
212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame) {
213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return spdy_framer_.SerializeFrame(frame);
214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyPriority GetHighestPriority() const;
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size_t GetDataFrameMinimumSize() const {
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return spdy_framer_.GetDataFrameMinimumSize();
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t GetControlFrameHeaderSize() const {
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return spdy_framer_.GetControlFrameHeaderSize();
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  size_t GetSynStreamMinimumSize() const {
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return spdy_framer_.GetSynStreamMinimumSize();
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size_t GetFrameMinimumSize() const {
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return spdy_framer_.GetFrameMinimumSize();
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size_t GetFrameMaximumSize() const {
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return spdy_framer_.GetFrameMaximumSize();
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  size_t GetDataFrameMaximumPayload() const {
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return spdy_framer_.GetDataFrameMaximumPayload();
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int frames_received() const { return frames_received_; }
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The size of the header_buffer_.
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum { kHeaderBufferSize = 32 * 1024 };
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitHeaderStreaming(SpdyStreamId stream_id);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyFramer spdy_framer_;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BufferedSpdyFramerVisitorInterface* visitor_;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Header block streaming state:
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char header_buffer_[kHeaderBufferSize];
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t header_buffer_used_;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool header_buffer_valid_;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdyStreamId header_stream_id_;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int frames_received_;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Collection of fields from control frames that we need to
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // buffer up from the spdy framer.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct ControlFrameFields {
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SpdyFrameType type;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyStreamId stream_id;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyStreamId associated_stream_id;
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    SpdyStreamId promised_stream_id;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SpdyPriority priority;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8 credential_slot;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool fin;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool unidirectional;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ControlFrameFields> control_frame_fields_;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramer);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NET_SPDY_BUFFERED_SPDY_FRAMER_H_
280