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_SPDY_FRAMER_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_SPDY_SPDY_FRAMER_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <memory> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string_piece.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sys_byteorder.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h" 2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "net/spdy/hpack_decoder.h" 2223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "net/spdy/hpack_encoder.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_header_block.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_protocol.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// TODO(akalin): Remove support for CREDENTIAL frames. 271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct z_stream_s z_stream; // Forward declaration for zlib. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HttpProxyClientSocketPoolTest; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HttpNetworkLayer; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HttpNetworkTransactionTest; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpdyHttpStreamTest; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpdyNetworkTransactionTest; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpdyProxyClientSocketTest; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpdySessionTest; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpdyStreamTest; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpdyWebSocketStreamTest; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WebSocketJobTest; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpdyFramer; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpdyFrameBuilder; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpdyFramerTest; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace test { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestSpdyVisitor; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace test 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// A datastructure for holding a set of headers from a HEADERS, PUSH_PROMISE, 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// SYN_STREAM, or SYN_REPLY frame. 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef std::map<std::string, std::string> SpdyHeaderBlock; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A datastructure for holding the ID and flag fields for SETTINGS. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Conveniently handles converstion to/from wire format. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE SettingsFlagsAndId { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static SettingsFlagsAndId FromWireFormat(SpdyMajorVersion version, 625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu uint32 wire); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndId() : flags_(0), id_(0) {} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(hkhalil): restrict to enums instead of free-form ints. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SettingsFlagsAndId(uint8 flags, uint32 id); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu uint32 GetWireFormat(SpdyMajorVersion version) const; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 id() const { return id_; } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 flags() const { return flags_; } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void ConvertFlagsAndIdForSpdy2(uint32* val); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 flags_; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 id_; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SettingsMap has unique (flags, value) pair for given SpdySettingsIds ID. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::pair<SpdySettingsFlags, uint32> SettingsFlagsAndValue; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::map<SpdySettingsIds, SettingsFlagsAndValue> SettingsMap; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Scratch space necessary for processing SETTINGS frames. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct NET_EXPORT_PRIVATE SpdySettingsScratch { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdySettingsScratch() { Reset(); } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Reset() { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) setting_buf_len = 0; 914ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch last_setting_id = -1; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Buffer contains up to one complete key/value pair. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char setting_buf[8]; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The amount of the buffer that is filled with valid data. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t setting_buf_len; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The ID of the last setting that was processed in the current SETTINGS 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // frame. Used for detecting out-of-order or duplicate keys within a settings 1024ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // frame. Set to -1 before first key/value pair is processed. 1034ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch int last_setting_id; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Scratch space necessary for processing ALTSVC frames. 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)struct NET_EXPORT_PRIVATE SpdyAltSvcScratch { 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SpdyAltSvcScratch(); 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ~SpdyAltSvcScratch(); 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) void Reset() { 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) max_age = 0; 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) port = 0; 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) pid_len = 0; 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) host_len = 0; 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) origin_len = 0; 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) pid_buf_len = 0; 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) host_buf_len = 0; 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) origin_buf_len = 0; 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) protocol_id.reset(); 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) host.reset(); 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) origin.reset(); 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint32 max_age; 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint16 port; 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint8 pid_len; 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint8 host_len; 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t origin_len; 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t pid_buf_len; 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t host_buf_len; 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t origin_buf_len; 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<char[]> protocol_id; 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<char[]> host; 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<char[]> origin; 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SpdyFramerVisitorInterface is a set of callbacks for the SpdyFramer. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implement this interface to receive event callbacks as frames are 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// decoded from the framer. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Control frames that contain SPDY header blocks (SYN_STREAM, SYN_REPLY, 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// HEADER, and PUSH_PROMISE) are processed in fashion that allows the 1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// decompressed header block to be delivered in chunks to the visitor. 1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// The following steps are followed: 1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// 1. OnSynStream, OnSynReply, OnHeaders, or OnPushPromise is called. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2. Repeated: OnControlFrameHeaderData is called with chunks of the 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// decompressed header block. In each call the len parameter is greater 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// than zero. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3. OnControlFrameHeaderData is called with len set to zero, indicating 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that the full header block has been delivered for the control frame. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// During step 2 the visitor may return false, indicating that the chunk of 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// header data could not be handled by the visitor (typically this indicates 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// resource exhaustion). If this occurs the framer will discontinue 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// delivering chunks to the visitor, set a SPDY_CONTROL_PAYLOAD_TOO_LARGE 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// error, and clean up appropriately. Note that this will cause the header 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// decompressor to lose synchronization with the sender's header compressor, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// making the SPDY session unusable for future work. The visitor's OnError 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function should deal with this condition by closing the SPDY connection. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE SpdyFramerVisitorInterface { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~SpdyFramerVisitorInterface() {} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called if an error is detected in the SpdyFrame protocol. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnError(SpdyFramer* framer) = 0; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when a data frame header is received. The frame's data 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // payload will be provided via subsequent calls to 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnStreamFrameData(). 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnDataFrameHeader(SpdyStreamId stream_id, 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t length, 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fin) = 0; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when data is received. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |stream_id| The stream receiving data. 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |data| A buffer containing the data received. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |len| The length of the data buffer. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When the other side has finished sending data on this stream, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this method will be called with a zero-length buffer. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnStreamFrameData(SpdyStreamId stream_id, 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* data, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t len, 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fin) = 0; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Called when a chunk of header data is available. This is called 186ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // after OnSynStream, OnSynReply, OnHeaders(), or OnPushPromise. 187ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // |stream_id| The stream receiving the header data. 188ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // |header_data| A buffer containing the header data chunk received. 189ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // |len| The length of the header data buffer. A length of zero indicates 190ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // that the header data block has been completely sent. 191ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // When this function returns true the visitor indicates that it accepted 192ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // all of the data. Returning false indicates that that an unrecoverable 193ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // error has occurred, such as bad header data or resource exhaustion. 194ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id, 195ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const char* header_data, 196ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch size_t len) = 0; 197ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 198ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Called when a SYN_STREAM frame is received. 199ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Note that header block data is not included. See 200ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // OnControlFrameHeaderData(). 201ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch virtual void OnSynStream(SpdyStreamId stream_id, 202ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SpdyStreamId associated_stream_id, 203ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SpdyPriority priority, 204ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch bool fin, 205ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch bool unidirectional) = 0; 206ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 207ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Called when a SYN_REPLY frame is received. 208ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Note that header block data is not included. See 209ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // OnControlFrameHeaderData(). 210ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch virtual void OnSynReply(SpdyStreamId stream_id, bool fin) = 0; 211ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 212ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Called when a RST_STREAM frame has been parsed. 213ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch virtual void OnRstStream(SpdyStreamId stream_id, 214ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SpdyRstStreamStatus status) = 0; 215ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Called when a SETTINGS frame is received. 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |clear_persisted| True if the respective flag is set on the SETTINGS frame. 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnSettings(bool clear_persisted) {} 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when a complete setting within a SETTINGS frame has been parsed and 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // validated. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Called when a SETTINGS frame is received with the ACK flag set. 225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnSettingsAck() {} 226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Called before and after parsing SETTINGS id and value tuples. 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnSettingsEnd() = 0; 229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when a PING frame has been parsed. 231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnPing(SpdyPingId unique_id, bool is_ack) = 0; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when a GOAWAY frame has been parsed. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnGoAway(SpdyStreamId last_accepted_stream_id, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyGoAwayStatus status) = 0; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 237ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Called when a HEADERS frame is received. 238ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Note that header block data is not included. See 239ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // OnControlFrameHeaderData(). 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnHeaders(SpdyStreamId stream_id, bool fin, bool end) = 0; 241ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when a WINDOW_UPDATE frame has been parsed. 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnWindowUpdate(SpdyStreamId stream_id, 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 delta_window_size) = 0; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Called when a goaway frame opaque data is available. 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |goaway_data| A buffer containing the opaque GOAWAY data chunk received. 248ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // |len| The length of the header data buffer. A length of zero indicates 249ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // that the header data block has been completely sent. 250ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // When this function returns true the visitor indicates that it accepted 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // all of the data. Returning false indicates that that an error has 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // occurred while processing the data. Default implementation returns true. 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool OnGoAwayFrameData(const char* goaway_data, size_t len); 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Called when rst_stream frame opaque data is available. 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |rst_stream_data| A buffer containing the opaque RST_STREAM 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // data chunk received. 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |len| The length of the header data buffer. A length of zero indicates 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // that the opaque data has been completely sent. 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // When this function returns true the visitor indicates that it accepted 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // all of the data. Returning false indicates that that an error has 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // occurred while processing the data. Default implementation returns true. 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool OnRstStreamFrameData(const char* rst_stream_data, size_t len); 264ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Called when a BLOCKED frame has been parsed. 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void OnBlocked(SpdyStreamId stream_id) {} 2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Called when a PUSH_PROMISE frame is received. 2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Note that header block data is not included. See 2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // OnControlFrameHeaderData(). 2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual void OnPushPromise(SpdyStreamId stream_id, 272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SpdyStreamId promised_stream_id, 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool end) = 0; 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Called when a CONTINUATION frame is received. 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Note that header block data is not included. See 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // OnControlFrameHeaderData(). 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnContinuation(SpdyStreamId stream_id, bool end) = 0; 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Called when an ALTSVC frame has been parsed. 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual void OnAltSvc(SpdyStreamId stream_id, 282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint32 max_age, 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint16 port, 284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::StringPiece protocol_id, 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::StringPiece host, 286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::StringPiece origin) {} 287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Called when a PRIORITY frame is received. 289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void OnPriority(SpdyStreamId stream_id, 290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SpdyStreamId parent_stream_id, 291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uint8 weight, 29203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool exclusive) {} 29303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 29403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Called when a frame type we don't recognize is received. 29503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Return true if this appears to be a valid extension frame, false otherwise. 29603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // We distinguish between extension frames and nonsense by checking 29703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // whether the stream id is valid. 29803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) virtual bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) = 0; 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Optionally, and in addition to SpdyFramerVisitorInterface, a class supporting 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// SpdyFramerDebugVisitorInterface may be used in conjunction with SpdyFramer in 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// order to extract debug/internal information about the SpdyFramer as it 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// operates. 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Most SPDY implementations need not bother with this interface at all. 3077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass NET_EXPORT_PRIVATE SpdyFramerDebugVisitorInterface { 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~SpdyFramerDebugVisitorInterface() {} 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Called after compressing a frame with a payload of 3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // a list of name-value pairs. 3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // |payload_len| is the uncompressed payload size. 3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // |frame_len| is the compressed frame size. 3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual void OnSendCompressedFrame(SpdyStreamId stream_id, 3167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyFrameType type, 3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) size_t payload_len, 3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) size_t frame_len) {} 3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Called when a frame containing a compressed payload of 3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // name-value pairs is received. 3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // |frame_len| is the compressed frame size. 3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual void OnReceiveCompressedFrame(SpdyStreamId stream_id, 3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SpdyFrameType type, 3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) size_t frame_len) {} 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE SpdyFramer { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SPDY states. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mbelshe): Can we move these into the implementation 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and avoid exposing through the header. (Needed for test) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum SpdyState { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SPDY_ERROR, 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SPDY_RESET, 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SPDY_AUTO_RESET, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SPDY_READING_COMMON_HEADER, 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SPDY_CONTROL_FRAME_PAYLOAD, 3394ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch SPDY_READ_PADDING_LENGTH, 3404ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch SPDY_CONSUME_PADDING, 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SPDY_IGNORE_REMAINING_PAYLOAD, 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SPDY_FORWARD_STREAM_FRAME, 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SPDY_CONTROL_FRAME_HEADER_BLOCK, 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SPDY_GOAWAY_FRAME_PAYLOAD, 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SPDY_RST_STREAM_FRAME_PAYLOAD, 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SPDY_SETTINGS_FRAME_PAYLOAD, 348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SPDY_ALTSVC_FRAME_PAYLOAD, 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SPDY error codes. 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum SpdyError { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SPDY_NO_ERROR, 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SPDY_INVALID_CONTROL_FRAME, // Control frame is mal-formatted. 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SPDY_CONTROL_PAYLOAD_TOO_LARGE, // Control frame payload was too large. 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SPDY_ZLIB_INIT_FAILURE, // The Zlib library could not initialize. 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SPDY_UNSUPPORTED_VERSION, // Control frame has unsupported version. 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SPDY_DECOMPRESS_FAILURE, // There was an error decompressing. 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SPDY_COMPRESS_FAILURE, // There was an error compressing. 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SPDY_GOAWAY_FRAME_CORRUPT, // GOAWAY frame could not be parsed. 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SPDY_RST_STREAM_FRAME_CORRUPT, // RST_STREAM frame could not be parsed. 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SPDY_INVALID_DATA_FRAME_FLAGS, // Data frame has invalid flags. 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SPDY_INVALID_CONTROL_FRAME_FLAGS, // Control frame has invalid flags. 364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SPDY_UNEXPECTED_FRAME, // Frame received out of order. 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LAST_ERROR, // Must be the last entry in the enum. 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Constant for invalid (or unknown) stream IDs. 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const SpdyStreamId kInvalidStream; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The maximum size of header data chunks delivered to the framer visitor 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // through OnControlFrameHeaderData. (It is exposed here for unit test 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // purposes.) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t kHeaderDataChunkMaxSize; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Serializes a SpdyHeaderBlock. 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static void WriteHeaderBlock(SpdyFrameBuilder* frame, 3795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const SpdyMajorVersion spdy_version, 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SpdyHeaderBlock* headers); 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Retrieve serialized length of SpdyHeaderBlock. 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(hkhalil): Remove, or move to quic code. 3845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static size_t GetSerializedLength( 3855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const SpdyMajorVersion spdy_version, 3865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const SpdyHeaderBlock* headers); 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a new Framer, provided a SPDY version. 38990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) explicit SpdyFramer(SpdyMajorVersion version); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~SpdyFramer(); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set callbacks to be called from the framer. A visitor must be set, or 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // else the framer will likely crash. It is acceptable for the visitor 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to do nothing. If this is called multiple times, only the last visitor 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be used. 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_visitor(SpdyFramerVisitorInterface* visitor) { 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) visitor_ = visitor; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set debug callbacks to be called from the framer. The debug visitor is 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // completely optional and need not be set in order for normal operation. 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If this is called multiple times, only the last visitor will be used. 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor) { 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) debug_visitor_ = debug_visitor; 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pass data into the framer for parsing. 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the number of bytes consumed. It is safe to pass more bytes in 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // than may be consumed. 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t ProcessInput(const char* data, size_t len); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Resets the framer state after a frame has been successfully decoded. 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mbelshe): can we make this private? 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Reset(); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check the state of the framer. 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyError error_code() const { return error_code_; } 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyState state() const { return state_; } 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasError() const { return state_ == SPDY_ERROR; } 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Given a buffer containing a decompressed header block in SPDY 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // serialized format, parse out a SpdyHeaderBlock, putting the results 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the given header block. 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns number of bytes consumed if successfully parsed, 0 otherwise. 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t ParseHeaderBlockInBuffer(const char* header_data, 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t header_length, 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyHeaderBlock* block) const; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Serialize a data frame. 430ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SpdySerializedFrame* SerializeData(const SpdyDataIR& data) const; 4315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Serializes the data frame header and optionally padding length fields, 4325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // excluding actual data payload and padding. 4335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SpdySerializedFrame* SerializeDataFrameHeaderWithPaddingLengthField( 4345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const SpdyDataIR& data) const; 435ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Serializes a SYN_STREAM frame. 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySerializedFrame* SerializeSynStream(const SpdySynStreamIR& syn_stream); 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Serialize a SYN_REPLY SpdyFrame. 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySerializedFrame* SerializeSynReply(const SpdySynReplyIR& syn_reply); 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySerializedFrame* SerializeRstStream( 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SpdyRstStreamIR& rst_stream) const; 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Serializes a SETTINGS frame. The SETTINGS frame is 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // used to communicate name/value pairs relevant to the communication channel. 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySerializedFrame* SerializeSettings(const SpdySettingsIR& settings) const; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Serializes a PING frame. The unique_id is used to 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // identify the ping request/response. 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySerializedFrame* SerializePing(const SpdyPingIR& ping) const; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Serializes a GOAWAY frame. The GOAWAY frame is used 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // prior to the shutting down of the TCP connection, and includes the 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stream_id of the last stream the sender of the frame is willing to process 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to completion. 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySerializedFrame* SerializeGoAway(const SpdyGoAwayIR& goaway) const; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Serializes a HEADERS frame. The HEADERS frame is used 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // for sending additional headers outside of a SYN_STREAM/SYN_REPLY. 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySerializedFrame* SerializeHeaders(const SpdyHeadersIR& headers); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Serializes a WINDOW_UPDATE frame. The WINDOW_UPDATE 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // frame is used to implement per stream flow control in SPDY. 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdySerializedFrame* SerializeWindowUpdate( 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SpdyWindowUpdateIR& window_update) const; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Serializes a BLOCKED frame. The BLOCKED frame is used to 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // indicate to the remote endpoint that this endpoint believes itself to be 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // flow-control blocked but otherwise ready to send data. The BLOCKED frame 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // is purely advisory and optional. 472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SpdySerializedFrame* SerializeBlocked(const SpdyBlockedIR& blocked) const; 473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Serializes a PUSH_PROMISE frame. The PUSH_PROMISE frame is used 4757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // to inform the client that it will be receiving an additional stream 4767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // in response to the original request. The frame includes synthesized 4777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // headers to explain the upcoming data. 4787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SpdySerializedFrame* SerializePushPromise( 4797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const SpdyPushPromiseIR& push_promise); 4807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Serializes a CONTINUATION frame. The CONTINUATION frame is used 482a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // to continue a sequence of header block fragments. 48323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // TODO(jgraettinger): This implementation is incorrect. The continuation 48423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // frame continues a previously-begun HPACK encoding; it doesn't begin a 48523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // new one. Figure out whether it makes sense to keep SerializeContinuation(). 486a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SpdySerializedFrame* SerializeContinuation( 487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const SpdyContinuationIR& continuation); 488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 489cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Serializes an ALTSVC frame. The ALTSVC frame advertises the 490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // availability of an alternative service to the client. 491cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SpdySerializedFrame* SerializeAltSvc(const SpdyAltSvcIR& altsvc); 492cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 493116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Serializes a PRIORITY frame. The PRIORITY frame advises a change in 494116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // the relative priority of the given stream. 495116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SpdySerializedFrame* SerializePriority(const SpdyPriorityIR& priority); 496116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Serialize a frame of unknown type. 498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame); 499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTES about frame compression. 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We want spdy to compress headers across the entire session. As long as 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the session is over TCP, frames are sent serially. The client & server 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can each compress frames in the same order and then compress them in that 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // order, and the remote can do the reverse. However, we ultimately want 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the creation of frames to be less sensitive to order so that they can be 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // placed over a UDP based protocol and yet still benefit from some 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // compression. We don't know of any good compression protocol which does 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not build its state in a serial (stream based) manner.... For now, we're 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // using zlib anyway. 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compresses a SpdyFrame. 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On success, returns a new SpdyFrame with the payload compressed. 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compression state is maintained as part of the SpdyFramer. 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returned frame must be freed with "delete". 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On failure, returns NULL. 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyFrame* CompressFrame(const SpdyFrame& frame); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For ease of testing and experimentation we can tweak compression on/off. 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set_enable_compression(bool value) { 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enable_compression_ = value; 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used only in log messages. 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_display_protocol(const std::string& protocol) { 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) display_protocol_ = protocol; 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns the (minimum) size of frames (sans variable-length portions). 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t GetDataFrameMinimumSize() const; 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t GetControlFrameHeaderSize() const; 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t GetSynStreamMinimumSize() const; 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t GetSynReplyMinimumSize() const; 5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t GetRstStreamMinimumSize() const; 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t GetSettingsMinimumSize() const; 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t GetPingSize() const; 5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t GetGoAwayMinimumSize() const; 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t GetHeadersMinimumSize() const; 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t GetWindowUpdateSize() const; 539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size_t GetBlockedSize() const; 5407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch size_t GetPushPromiseMinimumSize() const; 541a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t GetContinuationMinimumSize() const; 542cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t GetAltSvcMinimumSize() const; 543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t GetPrioritySize() const; 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Returns the minimum size a frame can be (data or control). 546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t GetFrameMinimumSize() const; 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Returns the maximum size a frame can be (data or control). 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t GetFrameMaximumSize() const; 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5514ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // Returns the maximum size that a control frame can be. 5524ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch size_t GetControlFrameMaximumSize() const; 5534ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch 554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Returns the maximum payload size of a DATA frame. 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t GetDataFrameMaximumPayload() const; 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Returns the prefix length for the given frame type. 5585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu size_t GetPrefixLength(SpdyFrameType type) const; 5595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For debugging. 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* StateToString(int state); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* ErrorCodeToString(int error_code); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* StatusCodeToString(int status_code); 564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static const char* FrameTypeToString(SpdyFrameType type); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SpdyMajorVersion protocol_version() const { return spdy_version_; } 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool probable_http_response() const { return probable_http_response_; } 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SpdyStreamId expect_continuation() const { return expect_continuation_; } 571a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SpdyPriority GetLowestPriority() const { 5735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return spdy_version_ < SPDY3 ? 3 : 7; 5745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 5755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyPriority GetHighestPriority() const { return 0; } 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 578cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Interpolates SpdyPriority values into SPDY4/HTTP2 priority weights, 579cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // and vice versa. 580cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint8 MapPriorityToWeight(SpdyPriority priority); 581cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SpdyPriority MapWeightToPriority(uint8 weight); 582cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Deliver the given control frame's compressed headers block to the visitor 584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // in decompressed form, in chunks. Returns true if the visitor has 585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // accepted all of the chunks. 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool IncrementallyDecompressControlFrameHeaderData( 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdyStreamId stream_id, 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* data, 589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t len); 590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 5925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // TODO(jgraettinger): Switch to test peer pattern. 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, BasicCompression); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ControlFrameSizesAreValidated); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, HeaderCompression); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, DecompressUncompressedFrame); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ExpandBuffer_HeapSmash); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, HugeHeaderBlock); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, UnclosedStreamDataCompressors); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnclosedStreamDataCompressorsOneByteAtATime); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UncompressLargerThanFrameBufferInitialSize); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ReadLargeSettingsFrame); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadLargeSettingsFrameInSmallChunks); 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ControlFrameAtMaxSizeLimit); 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ControlFrameTooLarge); 6095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, 6105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu TooLargeHeadersFrameUsesContinuation); 6115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, 6125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu TooLargePushPromiseFrameUsesContinuation); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class net::HttpNetworkLayer; // This is temporary for the server. 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class net::HttpNetworkTransactionTest; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class net::HttpProxyClientSocketPoolTest; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class net::SpdyHttpStreamTest; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class net::SpdyNetworkTransactionTest; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class net::SpdyProxyClientSocketTest; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class net::SpdySessionTest; 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class net::SpdyStreamTest; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class net::SpdyWebSocketStreamTest; 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class net::WebSocketJobTest; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class test::TestSpdyVisitor; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Internal breakouts from ProcessInput. Each returns the number of bytes 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // consumed from the data. 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t ProcessCommonHeader(const char* data, size_t len); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t ProcessControlFramePayload(const char* data, size_t len); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t ProcessControlFrameBeforeHeaderBlock(const char* data, size_t len); 63123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // HPACK data is re-encoded as SPDY3 and re-entrantly delivered through 63223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // |ProcessControlFrameHeaderBlock()|. |is_hpack_header_block| controls 63323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // whether data is treated as HPACK- vs SPDY3-encoded. 63423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) size_t ProcessControlFrameHeaderBlock(const char* data, 63523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) size_t len, 63623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool is_hpack_header_block); 6374ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch size_t ProcessFramePaddingLength(const char* data, size_t len); 6384ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch size_t ProcessFramePadding(const char* data, size_t len); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t ProcessDataFramePayload(const char* data, size_t len); 6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t ProcessGoAwayFramePayload(const char* data, size_t len); 6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t ProcessRstStreamFramePayload(const char* data, size_t len); 6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t ProcessSettingsFramePayload(const char* data, size_t len); 643cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) size_t ProcessAltSvcFramePayload(const char* data, size_t len); 6445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu size_t ProcessIgnoredControlFramePayload(/*const char* data,*/ size_t len); 6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 64623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // TODO(jgraettinger): To be removed with migration to 64723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // SpdyHeadersHandlerInterface. 64823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Serializes the last-processed header block of |hpack_decoder_| as 64923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // a SPDY3 format block, and delivers it to the visitor via reentrant 65023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // call to ProcessControlFrameHeaderBlock(). 65123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) void DeliverHpackBlockAsSpdy3Block(); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helpers for above internal breakouts from ProcessInput. 654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ProcessControlFrameHeader(uint16 control_frame_type_field); 655a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Always passed exactly 1 setting's worth of data. 656a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool ProcessSetting(const char* data); 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Retrieve serialized length of SpdyHeaderBlock. If compression is enabled, a 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // maximum estimate is returned. 66023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) size_t GetSerializedLength(const SpdyHeaderBlock& headers); 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get (and lazily initialize) the ZLib state. 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z_stream* GetHeaderCompressor(); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z_stream* GetHeaderDecompressor(); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 666cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Get (and lazily initialize) the HPACK state. 667cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HpackEncoder* GetHpackEncoder(); 668cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) HpackDecoder* GetHpackDecoder(); 669cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 6705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu size_t GetNumberRequiredContinuationFrames(size_t size); 6715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 6725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu void WritePayloadWithContinuation(SpdyFrameBuilder* builder, 6735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& hpack_encoding, 6745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SpdyStreamId stream_id, 6755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SpdyFrameType type); 6765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deliver the given control frame's uncompressed headers block to the 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // visitor in chunks. Returns true if the visitor has accepted all of the 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // chunks. 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool IncrementallyDeliverControlFrameHeaderData(SpdyStreamId stream_id, 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* data, 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t len); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Utility to copy the given data block to the current frame buffer, up 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the given maximum number of bytes, and update the buffer 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // data (pointer and length). Returns the number of bytes 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // read, and: 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // *data is advanced the number of bytes read. 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // *len is reduced by the number of bytes read. 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t UpdateCurrentFrameBuffer(const char** data, size_t* len, 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t max_bytes); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteHeaderBlockToZ(const SpdyHeaderBlock* headers, 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z_stream* out) const; 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SerializeNameValueBlockWithoutCompression( 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdyFrameBuilder* builder, 69923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const SpdyNameValueBlock& name_value_block) const; 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Compresses automatically according to enable_compression_. 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SerializeNameValueBlock( 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdyFrameBuilder* builder, 70423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) const SpdyFrameWithNameValueBlockIR& frame); 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the error code and moves the framer into the error state. 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_error(SpdyError error); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The maximum size of the control frames that we support. 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This limit is arbitrary. We can enforce it here or at the application 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // layer. We chose the framing layer, but this can be changed (or removed) 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // if necessary later down the line. 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t GetControlFrameBufferMaxSize() const { 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The theoretical maximum for SPDY3 and earlier is (2^24 - 1) + 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 8, since the length field does not count the size of the 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // header. 71790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (spdy_version_ == SPDY2) { 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 64 * 1024; 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 72090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (spdy_version_ == SPDY3) { 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 16 * 1024 * 1024; 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 72323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Absolute maximum size of HTTP2 frame payload (section 4.2 "Frame size"). 72423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return (1<<14) - 1; 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 727116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(jgraettinger): For h2-13 interop testing coverage, 728116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // fragment at smaller payload boundaries. 729116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_t GetHeaderFragmentMaxSize() const { 730116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return GetControlFrameBufferMaxSize() >> 4; // 1023 bytes. 731116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 732116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The size of the control frame buffer. 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since this is only used for control frame headers, the maximum control 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // frame header size (SYN_STREAM) is sufficient; all remaining control 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // frame data is streamed to the visitor. 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t kControlFrameBufferSize; 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyState state_; 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyState previous_state_; 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyError error_code_; 7424ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch 7434ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // Note that for DATA frame, remaining_data_length_ is sum of lengths of 7444ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // frame header, padding length field (optional), data payload (optional) and 7454ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // padding payload (optional). 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t remaining_data_length_; 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7484ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // The length (in bytes) of the padding payload to be processed. 7494ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch size_t remaining_padding_payload_length_; 7504ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The number of bytes remaining to read from the current control frame's 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // headers. Note that header data blocks (for control types that have them) 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are part of the frame's payload, and not the frame's headers. 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t remaining_control_header_; 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<char[]> current_frame_buffer_; 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Number of bytes read into the current_frame_buffer_. 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t current_frame_buffer_length_; 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The type of the frame currently being read. 761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SpdyFrameType current_frame_type_; 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The flags field of the frame currently being read. 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint8 current_frame_flags_; 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The total length of the frame currently being read, including frame header. 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 current_frame_length_; 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The stream ID field of the frame currently being read, if applicable. 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdyStreamId current_frame_stream_id_; 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Scratch space for handling SETTINGS frames. 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(hkhalil): Unify memory for this scratch space with 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // current_frame_buffer_. 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdySettingsScratch settings_scratch_; 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 777cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SpdyAltSvcScratch altsvc_scratch_; 778cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enable_compression_; // Controls all compression 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SPDY header compressors. 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<z_stream> header_compressor_; 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<z_stream> header_decompressor_; 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 784cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<HpackEncoder> hpack_encoder_; 785cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_ptr<HpackDecoder> hpack_decoder_; 78623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdyFramerVisitorInterface* visitor_; 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SpdyFramerDebugVisitorInterface* debug_visitor_; 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string display_protocol_; 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The major SPDY version to be spoken/understood by this framer. 79390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const SpdyMajorVersion spdy_version_; 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tracks if we've ever gotten far enough in framing to see a control frame of 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // type SYN_STREAM or SYN_REPLY. 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we ever get something which looks like a data frame before we've had a 7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // SYN, we explicitly check to see if it looks like we got an HTTP response 8005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to a SPDY request. This boolean lets us do that. 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool syn_frame_processed_; 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we ever get a data frame before a SYN frame, we check to see if it 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // starts with HTTP. If it does, we likely have an HTTP response. This 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // isn't guaranteed though: we could have gotten a settings frame and then 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // corrupt data that just looks like HTTP, but deterministic checking requires 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a lot more state. 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool probable_http_response_; 809a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 810a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Set this to the current stream when we receive a HEADERS, PUSH_PROMISE, or 811a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // CONTINUATION frame without the END_HEADERS(0x4) bit set. These frames must 812a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // be followed by a CONTINUATION frame, or else we throw a PROTOCOL_ERROR. 813a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // A value of 0 indicates that we are not expecting a CONTINUATION frame. 814a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SpdyStreamId expect_continuation_; 815a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 816a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If a HEADERS frame is followed by a CONTINUATION frame, the FIN/END_STREAM 817a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // flag is still carried in the HEADERS frame. If it's set, flip this so that 818a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // we know to terminate the stream when the entire header block has been 819a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // processed. 820a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool end_stream_when_done_; 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // NET_SPDY_SPDY_FRAMER_H_ 826