Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / net / spdy / spdy_framer.h
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef NET_SPDY_SPDY_FRAMER_H_
6 #define NET_SPDY_SPDY_FRAMER_H_
7
8 #include <list>
9 #include <map>
10 #include <string>
11 #include <utility>
12 #include <vector>
13
14 #include "base/basictypes.h"
15 #include "base/gtest_prod_util.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/sys_byteorder.h"
18 #include "net/base/net_export.h"
19 #include "net/spdy/hpack_decoder.h"
20 #include "net/spdy/hpack_encoder.h"
21 #include "net/spdy/spdy_header_block.h"
22 #include "net/spdy/spdy_protocol.h"
23
24 // TODO(akalin): Remove support for CREDENTIAL frames.
25
26 typedef struct z_stream_s z_stream;  // Forward declaration for zlib.
27
28 namespace net {
29
30 class HttpProxyClientSocketPoolTest;
31 class HttpNetworkLayer;
32 class HttpNetworkTransactionTest;
33 class SpdyHttpStreamTest;
34 class SpdyNetworkTransactionTest;
35 class SpdyProxyClientSocketTest;
36 class SpdySessionTest;
37 class SpdyStreamTest;
38 class SpdyWebSocketStreamTest;
39 class WebSocketJobTest;
40
41 class SpdyFramer;
42 class SpdyFrameBuilder;
43 class SpdyFramerTest;
44
45 namespace test {
46
47 class TestSpdyVisitor;
48
49 }  // namespace test
50
51 // A datastructure for holding a set of headers from a HEADERS, PUSH_PROMISE,
52 // SYN_STREAM, or SYN_REPLY frame.
53 typedef std::map<std::string, std::string> SpdyHeaderBlock;
54
55 // A datastructure for holding the ID and flag fields for SETTINGS.
56 // Conveniently handles converstion to/from wire format.
57 class NET_EXPORT_PRIVATE SettingsFlagsAndId {
58  public:
59   static SettingsFlagsAndId FromWireFormat(SpdyMajorVersion version,
60                                            uint32 wire);
61
62   SettingsFlagsAndId() : flags_(0), id_(0) {}
63
64   // TODO(hkhalil): restrict to enums instead of free-form ints.
65   SettingsFlagsAndId(uint8 flags, uint32 id);
66
67   uint32 GetWireFormat(SpdyMajorVersion version) const;
68
69   uint32 id() const { return id_; }
70   uint8 flags() const { return flags_; }
71
72  private:
73   static void ConvertFlagsAndIdForSpdy2(uint32* val);
74
75   uint8 flags_;
76   uint32 id_;
77 };
78
79 // SettingsMap has unique (flags, value) pair for given SpdySettingsIds ID.
80 typedef std::pair<SpdySettingsFlags, uint32> SettingsFlagsAndValue;
81 typedef std::map<SpdySettingsIds, SettingsFlagsAndValue> SettingsMap;
82
83 // Scratch space necessary for processing SETTINGS frames.
84 struct NET_EXPORT_PRIVATE SpdySettingsScratch {
85   SpdySettingsScratch() { Reset(); }
86
87   void Reset() {
88     setting_buf_len = 0;
89     last_setting_id = -1;
90   }
91
92   // Buffer contains up to one complete key/value pair.
93   char setting_buf[8];
94
95   // The amount of the buffer that is filled with valid data.
96   size_t setting_buf_len;
97
98   // The ID of the last setting that was processed in the current SETTINGS
99   // frame. Used for detecting out-of-order or duplicate keys within a settings
100   // frame. Set to -1 before first key/value pair is processed.
101   int last_setting_id;
102 };
103
104 // SpdyFramerVisitorInterface is a set of callbacks for the SpdyFramer.
105 // Implement this interface to receive event callbacks as frames are
106 // decoded from the framer.
107 //
108 // Control frames that contain SPDY header blocks (SYN_STREAM, SYN_REPLY,
109 // HEADER, and PUSH_PROMISE) are processed in fashion that allows the
110 // decompressed header block to be delivered in chunks to the visitor.
111 // The following steps are followed:
112 //   1. OnSynStream, OnSynReply, OnHeaders, or OnPushPromise is called.
113 //   2. Repeated: OnControlFrameHeaderData is called with chunks of the
114 //      decompressed header block. In each call the len parameter is greater
115 //      than zero.
116 //   3. OnControlFrameHeaderData is called with len set to zero, indicating
117 //      that the full header block has been delivered for the control frame.
118 // During step 2 the visitor may return false, indicating that the chunk of
119 // header data could not be handled by the visitor (typically this indicates
120 // resource exhaustion). If this occurs the framer will discontinue
121 // delivering chunks to the visitor, set a SPDY_CONTROL_PAYLOAD_TOO_LARGE
122 // error, and clean up appropriately. Note that this will cause the header
123 // decompressor to lose synchronization with the sender's header compressor,
124 // making the SPDY session unusable for future work. The visitor's OnError
125 // function should deal with this condition by closing the SPDY connection.
126 class NET_EXPORT_PRIVATE SpdyFramerVisitorInterface {
127  public:
128   virtual ~SpdyFramerVisitorInterface() {}
129
130   // Called if an error is detected in the SpdyFrame protocol.
131   virtual void OnError(SpdyFramer* framer) = 0;
132
133   // Called when a data frame header is received. The frame's data
134   // payload will be provided via subsequent calls to
135   // OnStreamFrameData().
136   virtual void OnDataFrameHeader(SpdyStreamId stream_id,
137                                  size_t length,
138                                  bool fin) = 0;
139
140   // Called when data is received.
141   // |stream_id| The stream receiving data.
142   // |data| A buffer containing the data received.
143   // |len| The length of the data buffer.
144   // When the other side has finished sending data on this stream,
145   // this method will be called with a zero-length buffer.
146   virtual void OnStreamFrameData(SpdyStreamId stream_id,
147                                  const char* data,
148                                  size_t len,
149                                  bool fin) = 0;
150
151   // Called when a chunk of header data is available. This is called
152   // after OnSynStream, OnSynReply, OnHeaders(), or OnPushPromise.
153   // |stream_id| The stream receiving the header data.
154   // |header_data| A buffer containing the header data chunk received.
155   // |len| The length of the header data buffer. A length of zero indicates
156   //       that the header data block has been completely sent.
157   // When this function returns true the visitor indicates that it accepted
158   // all of the data. Returning false indicates that that an unrecoverable
159   // error has occurred, such as bad header data or resource exhaustion.
160   virtual bool OnControlFrameHeaderData(SpdyStreamId stream_id,
161                                         const char* header_data,
162                                         size_t len) = 0;
163
164   // Called when a SYN_STREAM frame is received.
165   // Note that header block data is not included. See
166   // OnControlFrameHeaderData().
167   virtual void OnSynStream(SpdyStreamId stream_id,
168                            SpdyStreamId associated_stream_id,
169                            SpdyPriority priority,
170                            bool fin,
171                            bool unidirectional) = 0;
172
173   // Called when a SYN_REPLY frame is received.
174   // Note that header block data is not included. See
175   // OnControlFrameHeaderData().
176   virtual void OnSynReply(SpdyStreamId stream_id, bool fin) = 0;
177
178   // Called when a RST_STREAM frame has been parsed.
179   virtual void OnRstStream(SpdyStreamId stream_id,
180                            SpdyRstStreamStatus status) = 0;
181
182   // Called when a SETTINGS frame is received.
183   // |clear_persisted| True if the respective flag is set on the SETTINGS frame.
184   virtual void OnSettings(bool clear_persisted) {}
185
186   // Called when a complete setting within a SETTINGS frame has been parsed and
187   // validated.
188   virtual void OnSetting(SpdySettingsIds id, uint8 flags, uint32 value) = 0;
189
190   // Called when a SETTINGS frame is received with the ACK flag set.
191   virtual void OnSettingsAck() {}
192
193   // Called before and after parsing SETTINGS id and value tuples.
194   virtual void OnSettingsEnd() = 0;
195
196   // Called when a PING frame has been parsed.
197   virtual void OnPing(SpdyPingId unique_id, bool is_ack) = 0;
198
199   // Called when a GOAWAY frame has been parsed.
200   virtual void OnGoAway(SpdyStreamId last_accepted_stream_id,
201                         SpdyGoAwayStatus status) = 0;
202
203   // Called when a HEADERS frame is received.
204   // Note that header block data is not included. See
205   // OnControlFrameHeaderData().
206   virtual void OnHeaders(SpdyStreamId stream_id, bool fin, bool end) = 0;
207
208   // Called when a WINDOW_UPDATE frame has been parsed.
209   virtual void OnWindowUpdate(SpdyStreamId stream_id,
210                               uint32 delta_window_size) = 0;
211
212   // Called when a goaway frame opaque data is available.
213   // |goaway_data| A buffer containing the opaque GOAWAY data chunk received.
214   // |len| The length of the header data buffer. A length of zero indicates
215   //       that the header data block has been completely sent.
216   // When this function returns true the visitor indicates that it accepted
217   // all of the data. Returning false indicates that that an error has
218   // occurred while processing the data. Default implementation returns true.
219   virtual bool OnGoAwayFrameData(const char* goaway_data, size_t len);
220
221   // Called when rst_stream frame opaque data is available.
222   // |rst_stream_data| A buffer containing the opaque RST_STREAM
223   // data chunk received.
224   // |len| The length of the header data buffer. A length of zero indicates
225   //       that the opaque data has been completely sent.
226   // When this function returns true the visitor indicates that it accepted
227   // all of the data. Returning false indicates that that an error has
228   // occurred while processing the data. Default implementation returns true.
229   virtual bool OnRstStreamFrameData(const char* rst_stream_data, size_t len);
230
231   // Called when a BLOCKED frame has been parsed.
232   virtual void OnBlocked(SpdyStreamId stream_id) {}
233
234   // Called when a PUSH_PROMISE frame is received.
235   // Note that header block data is not included. See
236   // OnControlFrameHeaderData().
237   virtual void OnPushPromise(SpdyStreamId stream_id,
238                              SpdyStreamId promised_stream_id,
239                              bool end) = 0;
240
241   // Called when a CONTINUATION frame is received.
242   // Note that header block data is not included. See
243   // OnControlFrameHeaderData().
244   virtual void OnContinuation(SpdyStreamId stream_id, bool end) = 0;
245 };
246
247 // Optionally, and in addition to SpdyFramerVisitorInterface, a class supporting
248 // SpdyFramerDebugVisitorInterface may be used in conjunction with SpdyFramer in
249 // order to extract debug/internal information about the SpdyFramer as it
250 // operates.
251 //
252 // Most SPDY implementations need not bother with this interface at all.
253 class NET_EXPORT_PRIVATE SpdyFramerDebugVisitorInterface {
254  public:
255   virtual ~SpdyFramerDebugVisitorInterface() {}
256
257   // Called after compressing a frame with a payload of
258   // a list of name-value pairs.
259   // |payload_len| is the uncompressed payload size.
260   // |frame_len| is the compressed frame size.
261   virtual void OnSendCompressedFrame(SpdyStreamId stream_id,
262                                      SpdyFrameType type,
263                                      size_t payload_len,
264                                      size_t frame_len) {}
265
266   // Called when a frame containing a compressed payload of
267   // name-value pairs is received.
268   // |frame_len| is the compressed frame size.
269   virtual void OnReceiveCompressedFrame(SpdyStreamId stream_id,
270                                         SpdyFrameType type,
271                                         size_t frame_len) {}
272 };
273
274 class NET_EXPORT_PRIVATE SpdyFramer {
275  public:
276   // SPDY states.
277   // TODO(mbelshe): Can we move these into the implementation
278   //                and avoid exposing through the header.  (Needed for test)
279   enum SpdyState {
280     SPDY_ERROR,
281     SPDY_RESET,
282     SPDY_AUTO_RESET,
283     SPDY_READING_COMMON_HEADER,
284     SPDY_CONTROL_FRAME_PAYLOAD,
285     SPDY_READ_PADDING_LENGTH,
286     SPDY_CONSUME_PADDING,
287     SPDY_IGNORE_REMAINING_PAYLOAD,
288     SPDY_FORWARD_STREAM_FRAME,
289     SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK,
290     SPDY_CONTROL_FRAME_HEADER_BLOCK,
291     SPDY_GOAWAY_FRAME_PAYLOAD,
292     SPDY_RST_STREAM_FRAME_PAYLOAD,
293     SPDY_SETTINGS_FRAME_PAYLOAD,
294   };
295
296   // SPDY error codes.
297   enum SpdyError {
298     SPDY_NO_ERROR,
299     SPDY_INVALID_CONTROL_FRAME,        // Control frame is mal-formatted.
300     SPDY_CONTROL_PAYLOAD_TOO_LARGE,    // Control frame payload was too large.
301     SPDY_ZLIB_INIT_FAILURE,            // The Zlib library could not initialize.
302     SPDY_UNSUPPORTED_VERSION,          // Control frame has unsupported version.
303     SPDY_DECOMPRESS_FAILURE,           // There was an error decompressing.
304     SPDY_COMPRESS_FAILURE,             // There was an error compressing.
305     SPDY_GOAWAY_FRAME_CORRUPT,         // GOAWAY frame could not be parsed.
306     SPDY_RST_STREAM_FRAME_CORRUPT,     // RST_STREAM frame could not be parsed.
307     SPDY_INVALID_DATA_FRAME_FLAGS,     // Data frame has invalid flags.
308     SPDY_INVALID_CONTROL_FRAME_FLAGS,  // Control frame has invalid flags.
309     SPDY_UNEXPECTED_FRAME,             // Frame received out of order.
310
311     LAST_ERROR,  // Must be the last entry in the enum.
312   };
313
314   // Constant for invalid (or unknown) stream IDs.
315   static const SpdyStreamId kInvalidStream;
316
317   // The maximum size of header data chunks delivered to the framer visitor
318   // through OnControlFrameHeaderData. (It is exposed here for unit test
319   // purposes.)
320   static const size_t kHeaderDataChunkMaxSize;
321
322   // Serializes a SpdyHeaderBlock.
323   static void WriteHeaderBlock(SpdyFrameBuilder* frame,
324                                const SpdyMajorVersion spdy_version,
325                                const SpdyHeaderBlock* headers);
326
327   // Retrieve serialized length of SpdyHeaderBlock.
328   // TODO(hkhalil): Remove, or move to quic code.
329   static size_t GetSerializedLength(
330       const SpdyMajorVersion spdy_version,
331       const SpdyHeaderBlock* headers);
332
333   // Create a new Framer, provided a SPDY version.
334   explicit SpdyFramer(SpdyMajorVersion version);
335   virtual ~SpdyFramer();
336
337   // Set callbacks to be called from the framer.  A visitor must be set, or
338   // else the framer will likely crash.  It is acceptable for the visitor
339   // to do nothing.  If this is called multiple times, only the last visitor
340   // will be used.
341   void set_visitor(SpdyFramerVisitorInterface* visitor) {
342     visitor_ = visitor;
343   }
344
345   // Set debug callbacks to be called from the framer. The debug visitor is
346   // completely optional and need not be set in order for normal operation.
347   // If this is called multiple times, only the last visitor will be used.
348   void set_debug_visitor(SpdyFramerDebugVisitorInterface* debug_visitor) {
349     debug_visitor_ = debug_visitor;
350   }
351
352   // Pass data into the framer for parsing.
353   // Returns the number of bytes consumed. It is safe to pass more bytes in
354   // than may be consumed.
355   size_t ProcessInput(const char* data, size_t len);
356
357   // Resets the framer state after a frame has been successfully decoded.
358   // TODO(mbelshe): can we make this private?
359   void Reset();
360
361   // Check the state of the framer.
362   SpdyError error_code() const { return error_code_; }
363   SpdyState state() const { return state_; }
364   bool HasError() const { return state_ == SPDY_ERROR; }
365
366   // Given a buffer containing a decompressed header block in SPDY
367   // serialized format, parse out a SpdyHeaderBlock, putting the results
368   // in the given header block.
369   // Returns number of bytes consumed if successfully parsed, 0 otherwise.
370   size_t ParseHeaderBlockInBuffer(const char* header_data,
371                                 size_t header_length,
372                                 SpdyHeaderBlock* block) const;
373
374   // Serialize a data frame.
375   SpdySerializedFrame* SerializeData(const SpdyDataIR& data) const;
376   // Serializes the data frame header and optionally padding length fields,
377   // excluding actual data payload and padding.
378   SpdySerializedFrame* SerializeDataFrameHeaderWithPaddingLengthField(
379       const SpdyDataIR& data) const;
380
381   // Serializes a SYN_STREAM frame.
382   SpdySerializedFrame* SerializeSynStream(const SpdySynStreamIR& syn_stream);
383
384   // Serialize a SYN_REPLY SpdyFrame.
385   SpdySerializedFrame* SerializeSynReply(const SpdySynReplyIR& syn_reply);
386
387   SpdySerializedFrame* SerializeRstStream(
388       const SpdyRstStreamIR& rst_stream) const;
389
390   // Serializes a SETTINGS frame. The SETTINGS frame is
391   // used to communicate name/value pairs relevant to the communication channel.
392   SpdySerializedFrame* SerializeSettings(const SpdySettingsIR& settings) const;
393
394   // Serializes a PING frame. The unique_id is used to
395   // identify the ping request/response.
396   SpdySerializedFrame* SerializePing(const SpdyPingIR& ping) const;
397
398   // Serializes a GOAWAY frame. The GOAWAY frame is used
399   // prior to the shutting down of the TCP connection, and includes the
400   // stream_id of the last stream the sender of the frame is willing to process
401   // to completion.
402   SpdySerializedFrame* SerializeGoAway(const SpdyGoAwayIR& goaway) const;
403
404   // Serializes a HEADERS frame. The HEADERS frame is used
405   // for sending additional headers outside of a SYN_STREAM/SYN_REPLY.
406   SpdySerializedFrame* SerializeHeaders(const SpdyHeadersIR& headers);
407
408   // Serializes a WINDOW_UPDATE frame. The WINDOW_UPDATE
409   // frame is used to implement per stream flow control in SPDY.
410   SpdySerializedFrame* SerializeWindowUpdate(
411       const SpdyWindowUpdateIR& window_update) const;
412
413   // Serializes a BLOCKED frame. The BLOCKED frame is used to
414   // indicate to the remote endpoint that this endpoint believes itself to be
415   // flow-control blocked but otherwise ready to send data. The BLOCKED frame
416   // is purely advisory and optional.
417   SpdySerializedFrame* SerializeBlocked(const SpdyBlockedIR& blocked) const;
418
419   // Serializes a PUSH_PROMISE frame. The PUSH_PROMISE frame is used
420   // to inform the client that it will be receiving an additional stream
421   // in response to the original request. The frame includes synthesized
422   // headers to explain the upcoming data.
423   SpdySerializedFrame* SerializePushPromise(
424       const SpdyPushPromiseIR& push_promise);
425
426   // Serializes a CONTINUATION frame. The CONTINUATION frame is used
427   // to continue a sequence of header block fragments.
428   // TODO(jgraettinger): This implementation is incorrect. The continuation
429   // frame continues a previously-begun HPACK encoding; it doesn't begin a
430   // new one. Figure out whether it makes sense to keep SerializeContinuation().
431   SpdySerializedFrame* SerializeContinuation(
432       const SpdyContinuationIR& continuation);
433
434   // Serialize a frame of unknown type.
435   SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame);
436
437   // NOTES about frame compression.
438   // We want spdy to compress headers across the entire session.  As long as
439   // the session is over TCP, frames are sent serially.  The client & server
440   // can each compress frames in the same order and then compress them in that
441   // order, and the remote can do the reverse.  However, we ultimately want
442   // the creation of frames to be less sensitive to order so that they can be
443   // placed over a UDP based protocol and yet still benefit from some
444   // compression.  We don't know of any good compression protocol which does
445   // not build its state in a serial (stream based) manner....  For now, we're
446   // using zlib anyway.
447
448   // Compresses a SpdyFrame.
449   // On success, returns a new SpdyFrame with the payload compressed.
450   // Compression state is maintained as part of the SpdyFramer.
451   // Returned frame must be freed with "delete".
452   // On failure, returns NULL.
453   SpdyFrame* CompressFrame(const SpdyFrame& frame);
454
455   // For ease of testing and experimentation we can tweak compression on/off.
456   void set_enable_compression(bool value) {
457     enable_compression_ = value;
458   }
459
460   // Used only in log messages.
461   void set_display_protocol(const std::string& protocol) {
462     display_protocol_ = protocol;
463   }
464
465   // Returns the (minimum) size of frames (sans variable-length portions).
466   size_t GetDataFrameMinimumSize() const;
467   size_t GetControlFrameHeaderSize() const;
468   size_t GetSynStreamMinimumSize() const;
469   size_t GetSynReplyMinimumSize() const;
470   size_t GetRstStreamMinimumSize() const;
471   size_t GetSettingsMinimumSize() const;
472   size_t GetPingSize() const;
473   size_t GetGoAwayMinimumSize() const;
474   size_t GetHeadersMinimumSize() const;
475   size_t GetWindowUpdateSize() const;
476   size_t GetBlockedSize() const;
477   size_t GetPushPromiseMinimumSize() const;
478   size_t GetContinuationMinimumSize() const;
479
480   // Returns the minimum size a frame can be (data or control).
481   size_t GetFrameMinimumSize() const;
482
483   // Returns the maximum size a frame can be (data or control).
484   size_t GetFrameMaximumSize() const;
485
486   // Returns the maximum size that a control frame can be.
487   size_t GetControlFrameMaximumSize() const;
488
489   // Returns the maximum payload size of a DATA frame.
490   size_t GetDataFrameMaximumPayload() const;
491
492   // Returns the prefix length for the given frame type.
493   size_t GetPrefixLength(SpdyFrameType type) const;
494
495   // For debugging.
496   static const char* StateToString(int state);
497   static const char* ErrorCodeToString(int error_code);
498   static const char* StatusCodeToString(int status_code);
499   static const char* FrameTypeToString(SpdyFrameType type);
500
501   SpdyMajorVersion protocol_version() const { return spdy_version_; }
502
503   bool probable_http_response() const { return probable_http_response_; }
504
505   SpdyStreamId expect_continuation() const { return expect_continuation_; }
506
507   SpdyPriority GetLowestPriority() const {
508     return spdy_version_ < SPDY3 ? 3 : 7;
509   }
510
511   SpdyPriority GetHighestPriority() const { return 0; }
512
513   // Deliver the given control frame's compressed headers block to the visitor
514   // in decompressed form, in chunks. Returns true if the visitor has
515   // accepted all of the chunks.
516   bool IncrementallyDecompressControlFrameHeaderData(
517       SpdyStreamId stream_id,
518       const char* data,
519       size_t len);
520
521  protected:
522   // TODO(jgraettinger): Switch to test peer pattern.
523   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, BasicCompression);
524   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ControlFrameSizesAreValidated);
525   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, HeaderCompression);
526   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, DecompressUncompressedFrame);
527   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ExpandBuffer_HeapSmash);
528   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, HugeHeaderBlock);
529   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, UnclosedStreamDataCompressors);
530   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest,
531                            UnclosedStreamDataCompressorsOneByteAtATime);
532   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest,
533                            UncompressLargerThanFrameBufferInitialSize);
534   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ReadLargeSettingsFrame);
535   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest,
536                            ReadLargeSettingsFrameInSmallChunks);
537   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ControlFrameAtMaxSizeLimit);
538   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest, ControlFrameTooLarge);
539   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest,
540                            TooLargeHeadersFrameUsesContinuation);
541   FRIEND_TEST_ALL_PREFIXES(SpdyFramerTest,
542                            TooLargePushPromiseFrameUsesContinuation);
543   friend class net::HttpNetworkLayer;  // This is temporary for the server.
544   friend class net::HttpNetworkTransactionTest;
545   friend class net::HttpProxyClientSocketPoolTest;
546   friend class net::SpdyHttpStreamTest;
547   friend class net::SpdyNetworkTransactionTest;
548   friend class net::SpdyProxyClientSocketTest;
549   friend class net::SpdySessionTest;
550   friend class net::SpdyStreamTest;
551   friend class net::SpdyWebSocketStreamTest;
552   friend class net::WebSocketJobTest;
553   friend class test::TestSpdyVisitor;
554
555  private:
556   // Internal breakouts from ProcessInput. Each returns the number of bytes
557   // consumed from the data.
558   size_t ProcessCommonHeader(const char* data, size_t len);
559   size_t ProcessControlFramePayload(const char* data, size_t len);
560   size_t ProcessControlFrameBeforeHeaderBlock(const char* data, size_t len);
561   // HPACK data is re-encoded as SPDY3 and re-entrantly delivered through
562   // |ProcessControlFrameHeaderBlock()|. |is_hpack_header_block| controls
563   // whether data is treated as HPACK- vs SPDY3-encoded.
564   size_t ProcessControlFrameHeaderBlock(const char* data,
565                                         size_t len,
566                                         bool is_hpack_header_block);
567   size_t ProcessFramePaddingLength(const char* data, size_t len);
568   size_t ProcessFramePadding(const char* data, size_t len);
569   size_t ProcessDataFramePayload(const char* data, size_t len);
570   size_t ProcessGoAwayFramePayload(const char* data, size_t len);
571   size_t ProcessRstStreamFramePayload(const char* data, size_t len);
572   size_t ProcessSettingsFramePayload(const char* data, size_t len);
573   size_t ProcessIgnoredControlFramePayload(/*const char* data,*/ size_t len);
574
575   // TODO(jgraettinger): To be removed with migration to
576   // SpdyHeadersHandlerInterface.
577   // Serializes the last-processed header block of |hpack_decoder_| as
578   // a SPDY3 format block, and delivers it to the visitor via reentrant
579   // call to ProcessControlFrameHeaderBlock().
580   void DeliverHpackBlockAsSpdy3Block();
581
582   // Helpers for above internal breakouts from ProcessInput.
583   void ProcessControlFrameHeader(uint16 control_frame_type_field);
584   // Always passed exactly 1 setting's worth of data.
585   bool ProcessSetting(const char* data);
586
587   // Retrieve serialized length of SpdyHeaderBlock. If compression is enabled, a
588   // maximum estimate is returned.
589   size_t GetSerializedLength(const SpdyHeaderBlock& headers);
590
591   // Get (and lazily initialize) the ZLib state.
592   z_stream* GetHeaderCompressor();
593   z_stream* GetHeaderDecompressor();
594
595   size_t GetNumberRequiredContinuationFrames(size_t size);
596
597   void WritePayloadWithContinuation(SpdyFrameBuilder* builder,
598                                     const std::string& hpack_encoding,
599                                     SpdyStreamId stream_id,
600                                     SpdyFrameType type);
601
602  private:
603   // Deliver the given control frame's uncompressed headers block to the
604   // visitor in chunks. Returns true if the visitor has accepted all of the
605   // chunks.
606   bool IncrementallyDeliverControlFrameHeaderData(SpdyStreamId stream_id,
607                                                   const char* data,
608                                                   size_t len);
609
610   // Utility to copy the given data block to the current frame buffer, up
611   // to the given maximum number of bytes, and update the buffer
612   // data (pointer and length). Returns the number of bytes
613   // read, and:
614   //   *data is advanced the number of bytes read.
615   //   *len is reduced by the number of bytes read.
616   size_t UpdateCurrentFrameBuffer(const char** data, size_t* len,
617                                   size_t max_bytes);
618
619   void WriteHeaderBlockToZ(const SpdyHeaderBlock* headers,
620                            z_stream* out) const;
621
622   void SerializeNameValueBlockWithoutCompression(
623       SpdyFrameBuilder* builder,
624       const SpdyNameValueBlock& name_value_block) const;
625
626   // Compresses automatically according to enable_compression_.
627   void SerializeNameValueBlock(
628       SpdyFrameBuilder* builder,
629       const SpdyFrameWithNameValueBlockIR& frame);
630
631   // Set the error code and moves the framer into the error state.
632   void set_error(SpdyError error);
633
634   // The maximum size of the control frames that we support.
635   // This limit is arbitrary. We can enforce it here or at the application
636   // layer. We chose the framing layer, but this can be changed (or removed)
637   // if necessary later down the line.
638   size_t GetControlFrameBufferMaxSize() const {
639     // The theoretical maximum for SPDY3 and earlier is (2^24 - 1) +
640     // 8, since the length field does not count the size of the
641     // header.
642     if (spdy_version_ == SPDY2) {
643       return 64 * 1024;
644     }
645     if (spdy_version_ == SPDY3) {
646       return 16 * 1024 * 1024;
647     }
648     // Absolute maximum size of HTTP2 frame payload (section 4.2 "Frame size").
649     return (1<<14) - 1;
650   }
651
652   // The size of the control frame buffer.
653   // Since this is only used for control frame headers, the maximum control
654   // frame header size (SYN_STREAM) is sufficient; all remaining control
655   // frame data is streamed to the visitor.
656   static const size_t kControlFrameBufferSize;
657
658   SpdyState state_;
659   SpdyState previous_state_;
660   SpdyError error_code_;
661
662   // Note that for DATA frame, remaining_data_length_ is sum of lengths of
663   // frame header, padding length field (optional), data payload (optional) and
664   // padding payload (optional).
665   size_t remaining_data_length_;
666
667   // The length (in bytes) of the padding payload to be processed.
668   size_t remaining_padding_payload_length_;
669
670   // The length (in bytes) of the padding length field to be processed.
671   size_t remaining_padding_length_fields_;
672
673   // The number of bytes remaining to read from the current control frame's
674   // headers. Note that header data blocks (for control types that have them)
675   // are part of the frame's payload, and not the frame's headers.
676   size_t remaining_control_header_;
677
678   scoped_ptr<char[]> current_frame_buffer_;
679   // Number of bytes read into the current_frame_buffer_.
680   size_t current_frame_buffer_length_;
681
682   // The type of the frame currently being read.
683   SpdyFrameType current_frame_type_;
684
685   // The flags field of the frame currently being read.
686   uint8 current_frame_flags_;
687
688   // The total length of the frame currently being read, including frame header.
689   uint32 current_frame_length_;
690
691   // The stream ID field of the frame currently being read, if applicable.
692   SpdyStreamId current_frame_stream_id_;
693
694   // Scratch space for handling SETTINGS frames.
695   // TODO(hkhalil): Unify memory for this scratch space with
696   // current_frame_buffer_.
697   SpdySettingsScratch settings_scratch_;
698
699   bool enable_compression_;  // Controls all compression
700   // SPDY header compressors.
701   scoped_ptr<z_stream> header_compressor_;
702   scoped_ptr<z_stream> header_decompressor_;
703
704   HpackEncoder hpack_encoder_;
705   HpackDecoder hpack_decoder_;
706
707   SpdyFramerVisitorInterface* visitor_;
708   SpdyFramerDebugVisitorInterface* debug_visitor_;
709
710   std::string display_protocol_;
711
712   // The major SPDY version to be spoken/understood by this framer.
713   const SpdyMajorVersion spdy_version_;
714
715   // Tracks if we've ever gotten far enough in framing to see a control frame of
716   // type SYN_STREAM or SYN_REPLY.
717   //
718   // If we ever get something which looks like a data frame before we've had a
719   // SYN, we explicitly check to see if it looks like we got an HTTP response
720   // to a SPDY request.  This boolean lets us do that.
721   bool syn_frame_processed_;
722
723   // If we ever get a data frame before a SYN frame, we check to see if it
724   // starts with HTTP.  If it does, we likely have an HTTP response.   This
725   // isn't guaranteed though: we could have gotten a settings frame and then
726   // corrupt data that just looks like HTTP, but deterministic checking requires
727   // a lot more state.
728   bool probable_http_response_;
729
730   // Set this to the current stream when we receive a HEADERS, PUSH_PROMISE, or
731   // CONTINUATION frame without the END_HEADERS(0x4) bit set. These frames must
732   // be followed by a CONTINUATION frame, or else we throw a PROTOCOL_ERROR.
733   // A value of 0 indicates that we are not expecting a CONTINUATION frame.
734   SpdyStreamId expect_continuation_;
735
736   // If a HEADERS frame is followed by a CONTINUATION frame, the FIN/END_STREAM
737   // flag is still carried in the HEADERS frame. If it's set, flip this so that
738   // we know to terminate the stream when the entire header block has been
739   // processed.
740   bool end_stream_when_done_;
741 };
742
743 }  // namespace net
744
745 #endif  // NET_SPDY_SPDY_FRAMER_H_