OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef NET_SPDY_SPDY_FRAMER_H_ | 5 #ifndef NET_SPDY_SPDY_FRAMER_H_ |
6 #define NET_SPDY_SPDY_FRAMER_H_ | 6 #define NET_SPDY_SPDY_FRAMER_H_ |
7 | 7 |
8 #include <list> | 8 #include <list> |
9 #include <map> | 9 #include <map> |
| 10 #include <memory> |
10 #include <string> | 11 #include <string> |
11 #include <utility> | 12 #include <utility> |
12 #include <vector> | 13 #include <vector> |
13 | 14 |
14 #include "base/basictypes.h" | 15 #include "base/basictypes.h" |
15 #include "base/gtest_prod_util.h" | 16 #include "base/gtest_prod_util.h" |
16 #include "base/memory/scoped_ptr.h" | 17 #include "base/memory/scoped_ptr.h" |
| 18 #include "base/strings/string_piece.h" |
17 #include "base/sys_byteorder.h" | 19 #include "base/sys_byteorder.h" |
18 #include "net/base/net_export.h" | 20 #include "net/base/net_export.h" |
19 #include "net/spdy/hpack_decoder.h" | 21 #include "net/spdy/hpack_decoder.h" |
20 #include "net/spdy/hpack_encoder.h" | 22 #include "net/spdy/hpack_encoder.h" |
21 #include "net/spdy/spdy_header_block.h" | 23 #include "net/spdy/spdy_header_block.h" |
22 #include "net/spdy/spdy_protocol.h" | 24 #include "net/spdy/spdy_protocol.h" |
23 | 25 |
24 // TODO(akalin): Remove support for CREDENTIAL frames. | 26 // TODO(akalin): Remove support for CREDENTIAL frames. |
25 | 27 |
26 typedef struct z_stream_s z_stream; // Forward declaration for zlib. | 28 typedef struct z_stream_s z_stream; // Forward declaration for zlib. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 | 96 |
95 // The amount of the buffer that is filled with valid data. | 97 // The amount of the buffer that is filled with valid data. |
96 size_t setting_buf_len; | 98 size_t setting_buf_len; |
97 | 99 |
98 // The ID of the last setting that was processed in the current SETTINGS | 100 // 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 | 101 // 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. | 102 // frame. Set to -1 before first key/value pair is processed. |
101 int last_setting_id; | 103 int last_setting_id; |
102 }; | 104 }; |
103 | 105 |
| 106 // Scratch space necessary for processing ALTSVC frames. |
| 107 struct NET_EXPORT_PRIVATE SpdyAltSvcScratch { |
| 108 SpdyAltSvcScratch(); |
| 109 ~SpdyAltSvcScratch(); |
| 110 |
| 111 void Reset() { |
| 112 max_age = 0; |
| 113 port = 0; |
| 114 pid_len = 0; |
| 115 host_len = 0; |
| 116 origin_len = 0; |
| 117 pid_buf_len = 0; |
| 118 host_buf_len = 0; |
| 119 origin_buf_len = 0; |
| 120 protocol_id.reset(); |
| 121 host.reset(); |
| 122 origin.reset(); |
| 123 } |
| 124 |
| 125 uint32 max_age; |
| 126 uint16 port; |
| 127 uint8 pid_len; |
| 128 uint8 host_len; |
| 129 size_t origin_len; |
| 130 size_t pid_buf_len; |
| 131 size_t host_buf_len; |
| 132 size_t origin_buf_len; |
| 133 scoped_ptr<char[]> protocol_id; |
| 134 scoped_ptr<char[]> host; |
| 135 scoped_ptr<char[]> origin; |
| 136 }; |
| 137 |
104 // SpdyFramerVisitorInterface is a set of callbacks for the SpdyFramer. | 138 // SpdyFramerVisitorInterface is a set of callbacks for the SpdyFramer. |
105 // Implement this interface to receive event callbacks as frames are | 139 // Implement this interface to receive event callbacks as frames are |
106 // decoded from the framer. | 140 // decoded from the framer. |
107 // | 141 // |
108 // Control frames that contain SPDY header blocks (SYN_STREAM, SYN_REPLY, | 142 // Control frames that contain SPDY header blocks (SYN_STREAM, SYN_REPLY, |
109 // HEADER, and PUSH_PROMISE) are processed in fashion that allows the | 143 // HEADER, and PUSH_PROMISE) are processed in fashion that allows the |
110 // decompressed header block to be delivered in chunks to the visitor. | 144 // decompressed header block to be delivered in chunks to the visitor. |
111 // The following steps are followed: | 145 // The following steps are followed: |
112 // 1. OnSynStream, OnSynReply, OnHeaders, or OnPushPromise is called. | 146 // 1. OnSynStream, OnSynReply, OnHeaders, or OnPushPromise is called. |
113 // 2. Repeated: OnControlFrameHeaderData is called with chunks of the | 147 // 2. Repeated: OnControlFrameHeaderData is called with chunks of the |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 // Note that header block data is not included. See | 269 // Note that header block data is not included. See |
236 // OnControlFrameHeaderData(). | 270 // OnControlFrameHeaderData(). |
237 virtual void OnPushPromise(SpdyStreamId stream_id, | 271 virtual void OnPushPromise(SpdyStreamId stream_id, |
238 SpdyStreamId promised_stream_id, | 272 SpdyStreamId promised_stream_id, |
239 bool end) = 0; | 273 bool end) = 0; |
240 | 274 |
241 // Called when a CONTINUATION frame is received. | 275 // Called when a CONTINUATION frame is received. |
242 // Note that header block data is not included. See | 276 // Note that header block data is not included. See |
243 // OnControlFrameHeaderData(). | 277 // OnControlFrameHeaderData(). |
244 virtual void OnContinuation(SpdyStreamId stream_id, bool end) = 0; | 278 virtual void OnContinuation(SpdyStreamId stream_id, bool end) = 0; |
| 279 |
| 280 // Called when an ALTSVC frame has been parsed. |
| 281 virtual void OnAltSvc(SpdyStreamId stream_id, |
| 282 uint32 max_age, |
| 283 uint16 port, |
| 284 base::StringPiece protocol_id, |
| 285 base::StringPiece host, |
| 286 base::StringPiece origin) {} |
245 }; | 287 }; |
246 | 288 |
247 // Optionally, and in addition to SpdyFramerVisitorInterface, a class supporting | 289 // Optionally, and in addition to SpdyFramerVisitorInterface, a class supporting |
248 // SpdyFramerDebugVisitorInterface may be used in conjunction with SpdyFramer in | 290 // SpdyFramerDebugVisitorInterface may be used in conjunction with SpdyFramer in |
249 // order to extract debug/internal information about the SpdyFramer as it | 291 // order to extract debug/internal information about the SpdyFramer as it |
250 // operates. | 292 // operates. |
251 // | 293 // |
252 // Most SPDY implementations need not bother with this interface at all. | 294 // Most SPDY implementations need not bother with this interface at all. |
253 class NET_EXPORT_PRIVATE SpdyFramerDebugVisitorInterface { | 295 class NET_EXPORT_PRIVATE SpdyFramerDebugVisitorInterface { |
254 public: | 296 public: |
(...skipping 29 matching lines...) Expand all Loading... |
284 SPDY_CONTROL_FRAME_PAYLOAD, | 326 SPDY_CONTROL_FRAME_PAYLOAD, |
285 SPDY_READ_PADDING_LENGTH, | 327 SPDY_READ_PADDING_LENGTH, |
286 SPDY_CONSUME_PADDING, | 328 SPDY_CONSUME_PADDING, |
287 SPDY_IGNORE_REMAINING_PAYLOAD, | 329 SPDY_IGNORE_REMAINING_PAYLOAD, |
288 SPDY_FORWARD_STREAM_FRAME, | 330 SPDY_FORWARD_STREAM_FRAME, |
289 SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, | 331 SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, |
290 SPDY_CONTROL_FRAME_HEADER_BLOCK, | 332 SPDY_CONTROL_FRAME_HEADER_BLOCK, |
291 SPDY_GOAWAY_FRAME_PAYLOAD, | 333 SPDY_GOAWAY_FRAME_PAYLOAD, |
292 SPDY_RST_STREAM_FRAME_PAYLOAD, | 334 SPDY_RST_STREAM_FRAME_PAYLOAD, |
293 SPDY_SETTINGS_FRAME_PAYLOAD, | 335 SPDY_SETTINGS_FRAME_PAYLOAD, |
| 336 SPDY_ALTSVC_FRAME_PAYLOAD, |
294 }; | 337 }; |
295 | 338 |
296 // SPDY error codes. | 339 // SPDY error codes. |
297 enum SpdyError { | 340 enum SpdyError { |
298 SPDY_NO_ERROR, | 341 SPDY_NO_ERROR, |
299 SPDY_INVALID_CONTROL_FRAME, // Control frame is mal-formatted. | 342 SPDY_INVALID_CONTROL_FRAME, // Control frame is mal-formatted. |
300 SPDY_CONTROL_PAYLOAD_TOO_LARGE, // Control frame payload was too large. | 343 SPDY_CONTROL_PAYLOAD_TOO_LARGE, // Control frame payload was too large. |
301 SPDY_ZLIB_INIT_FAILURE, // The Zlib library could not initialize. | 344 SPDY_ZLIB_INIT_FAILURE, // The Zlib library could not initialize. |
302 SPDY_UNSUPPORTED_VERSION, // Control frame has unsupported version. | 345 SPDY_UNSUPPORTED_VERSION, // Control frame has unsupported version. |
303 SPDY_DECOMPRESS_FAILURE, // There was an error decompressing. | 346 SPDY_DECOMPRESS_FAILURE, // There was an error decompressing. |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 const SpdyPushPromiseIR& push_promise); | 467 const SpdyPushPromiseIR& push_promise); |
425 | 468 |
426 // Serializes a CONTINUATION frame. The CONTINUATION frame is used | 469 // Serializes a CONTINUATION frame. The CONTINUATION frame is used |
427 // to continue a sequence of header block fragments. | 470 // to continue a sequence of header block fragments. |
428 // TODO(jgraettinger): This implementation is incorrect. The continuation | 471 // TODO(jgraettinger): This implementation is incorrect. The continuation |
429 // frame continues a previously-begun HPACK encoding; it doesn't begin a | 472 // frame continues a previously-begun HPACK encoding; it doesn't begin a |
430 // new one. Figure out whether it makes sense to keep SerializeContinuation(). | 473 // new one. Figure out whether it makes sense to keep SerializeContinuation(). |
431 SpdySerializedFrame* SerializeContinuation( | 474 SpdySerializedFrame* SerializeContinuation( |
432 const SpdyContinuationIR& continuation); | 475 const SpdyContinuationIR& continuation); |
433 | 476 |
| 477 // Serializes an ALTSVC frame. The ALTSVC frame advertises the |
| 478 // availability of an alternative service to the client. |
| 479 SpdySerializedFrame* SerializeAltSvc(const SpdyAltSvcIR& altsvc); |
| 480 |
434 // Serialize a frame of unknown type. | 481 // Serialize a frame of unknown type. |
435 SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame); | 482 SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame); |
436 | 483 |
437 // NOTES about frame compression. | 484 // NOTES about frame compression. |
438 // We want spdy to compress headers across the entire session. As long as | 485 // 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 | 486 // 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 | 487 // 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 | 488 // 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 | 489 // 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 | 490 // placed over a UDP based protocol and yet still benefit from some |
(...skipping 25 matching lines...) Expand all Loading... |
469 size_t GetSynReplyMinimumSize() const; | 516 size_t GetSynReplyMinimumSize() const; |
470 size_t GetRstStreamMinimumSize() const; | 517 size_t GetRstStreamMinimumSize() const; |
471 size_t GetSettingsMinimumSize() const; | 518 size_t GetSettingsMinimumSize() const; |
472 size_t GetPingSize() const; | 519 size_t GetPingSize() const; |
473 size_t GetGoAwayMinimumSize() const; | 520 size_t GetGoAwayMinimumSize() const; |
474 size_t GetHeadersMinimumSize() const; | 521 size_t GetHeadersMinimumSize() const; |
475 size_t GetWindowUpdateSize() const; | 522 size_t GetWindowUpdateSize() const; |
476 size_t GetBlockedSize() const; | 523 size_t GetBlockedSize() const; |
477 size_t GetPushPromiseMinimumSize() const; | 524 size_t GetPushPromiseMinimumSize() const; |
478 size_t GetContinuationMinimumSize() const; | 525 size_t GetContinuationMinimumSize() const; |
| 526 size_t GetAltSvcMinimumSize() const; |
| 527 size_t GetPrioritySize() const; |
479 | 528 |
480 // Returns the minimum size a frame can be (data or control). | 529 // Returns the minimum size a frame can be (data or control). |
481 size_t GetFrameMinimumSize() const; | 530 size_t GetFrameMinimumSize() const; |
482 | 531 |
483 // Returns the maximum size a frame can be (data or control). | 532 // Returns the maximum size a frame can be (data or control). |
484 size_t GetFrameMaximumSize() const; | 533 size_t GetFrameMaximumSize() const; |
485 | 534 |
486 // Returns the maximum size that a control frame can be. | 535 // Returns the maximum size that a control frame can be. |
487 size_t GetControlFrameMaximumSize() const; | 536 size_t GetControlFrameMaximumSize() const; |
488 | 537 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 // whether data is treated as HPACK- vs SPDY3-encoded. | 612 // whether data is treated as HPACK- vs SPDY3-encoded. |
564 size_t ProcessControlFrameHeaderBlock(const char* data, | 613 size_t ProcessControlFrameHeaderBlock(const char* data, |
565 size_t len, | 614 size_t len, |
566 bool is_hpack_header_block); | 615 bool is_hpack_header_block); |
567 size_t ProcessFramePaddingLength(const char* data, size_t len); | 616 size_t ProcessFramePaddingLength(const char* data, size_t len); |
568 size_t ProcessFramePadding(const char* data, size_t len); | 617 size_t ProcessFramePadding(const char* data, size_t len); |
569 size_t ProcessDataFramePayload(const char* data, size_t len); | 618 size_t ProcessDataFramePayload(const char* data, size_t len); |
570 size_t ProcessGoAwayFramePayload(const char* data, size_t len); | 619 size_t ProcessGoAwayFramePayload(const char* data, size_t len); |
571 size_t ProcessRstStreamFramePayload(const char* data, size_t len); | 620 size_t ProcessRstStreamFramePayload(const char* data, size_t len); |
572 size_t ProcessSettingsFramePayload(const char* data, size_t len); | 621 size_t ProcessSettingsFramePayload(const char* data, size_t len); |
| 622 size_t ProcessAltSvcFramePayload(const char* data, size_t len); |
573 size_t ProcessIgnoredControlFramePayload(/*const char* data,*/ size_t len); | 623 size_t ProcessIgnoredControlFramePayload(/*const char* data,*/ size_t len); |
574 | 624 |
575 // TODO(jgraettinger): To be removed with migration to | 625 // TODO(jgraettinger): To be removed with migration to |
576 // SpdyHeadersHandlerInterface. | 626 // SpdyHeadersHandlerInterface. |
577 // Serializes the last-processed header block of |hpack_decoder_| as | 627 // Serializes the last-processed header block of |hpack_decoder_| as |
578 // a SPDY3 format block, and delivers it to the visitor via reentrant | 628 // a SPDY3 format block, and delivers it to the visitor via reentrant |
579 // call to ProcessControlFrameHeaderBlock(). | 629 // call to ProcessControlFrameHeaderBlock(). |
580 void DeliverHpackBlockAsSpdy3Block(); | 630 void DeliverHpackBlockAsSpdy3Block(); |
581 | 631 |
582 // Helpers for above internal breakouts from ProcessInput. | 632 // Helpers for above internal breakouts from ProcessInput. |
583 void ProcessControlFrameHeader(uint16 control_frame_type_field); | 633 void ProcessControlFrameHeader(uint16 control_frame_type_field); |
584 // Always passed exactly 1 setting's worth of data. | 634 // Always passed exactly 1 setting's worth of data. |
585 bool ProcessSetting(const char* data); | 635 bool ProcessSetting(const char* data); |
586 | 636 |
587 // Retrieve serialized length of SpdyHeaderBlock. If compression is enabled, a | 637 // Retrieve serialized length of SpdyHeaderBlock. If compression is enabled, a |
588 // maximum estimate is returned. | 638 // maximum estimate is returned. |
589 size_t GetSerializedLength(const SpdyHeaderBlock& headers); | 639 size_t GetSerializedLength(const SpdyHeaderBlock& headers); |
590 | 640 |
591 // Get (and lazily initialize) the ZLib state. | 641 // Get (and lazily initialize) the ZLib state. |
592 z_stream* GetHeaderCompressor(); | 642 z_stream* GetHeaderCompressor(); |
593 z_stream* GetHeaderDecompressor(); | 643 z_stream* GetHeaderDecompressor(); |
594 | 644 |
| 645 // Get (and lazily initialize) the HPACK state. |
| 646 HpackEncoder* GetHpackEncoder(); |
| 647 HpackDecoder* GetHpackDecoder(); |
| 648 |
595 size_t GetNumberRequiredContinuationFrames(size_t size); | 649 size_t GetNumberRequiredContinuationFrames(size_t size); |
596 | 650 |
597 void WritePayloadWithContinuation(SpdyFrameBuilder* builder, | 651 void WritePayloadWithContinuation(SpdyFrameBuilder* builder, |
598 const std::string& hpack_encoding, | 652 const std::string& hpack_encoding, |
599 SpdyStreamId stream_id, | 653 SpdyStreamId stream_id, |
600 SpdyFrameType type); | 654 SpdyFrameType type); |
601 | 655 |
602 private: | 656 private: |
603 // Deliver the given control frame's uncompressed headers block to the | 657 // 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 | 658 // visitor in chunks. Returns true if the visitor has accepted all of the |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 uint32 current_frame_length_; | 743 uint32 current_frame_length_; |
690 | 744 |
691 // The stream ID field of the frame currently being read, if applicable. | 745 // The stream ID field of the frame currently being read, if applicable. |
692 SpdyStreamId current_frame_stream_id_; | 746 SpdyStreamId current_frame_stream_id_; |
693 | 747 |
694 // Scratch space for handling SETTINGS frames. | 748 // Scratch space for handling SETTINGS frames. |
695 // TODO(hkhalil): Unify memory for this scratch space with | 749 // TODO(hkhalil): Unify memory for this scratch space with |
696 // current_frame_buffer_. | 750 // current_frame_buffer_. |
697 SpdySettingsScratch settings_scratch_; | 751 SpdySettingsScratch settings_scratch_; |
698 | 752 |
| 753 SpdyAltSvcScratch altsvc_scratch_; |
| 754 |
699 bool enable_compression_; // Controls all compression | 755 bool enable_compression_; // Controls all compression |
700 // SPDY header compressors. | 756 // SPDY header compressors. |
701 scoped_ptr<z_stream> header_compressor_; | 757 scoped_ptr<z_stream> header_compressor_; |
702 scoped_ptr<z_stream> header_decompressor_; | 758 scoped_ptr<z_stream> header_decompressor_; |
703 | 759 |
704 scoped_ptr<HpackEncoder> hpack_encoder_; | 760 scoped_ptr<HpackEncoder> hpack_encoder_; |
705 scoped_ptr<HpackDecoder> hpack_decoder_; | 761 scoped_ptr<HpackDecoder> hpack_decoder_; |
706 | 762 |
707 SpdyFramerVisitorInterface* visitor_; | 763 SpdyFramerVisitorInterface* visitor_; |
708 SpdyFramerDebugVisitorInterface* debug_visitor_; | 764 SpdyFramerDebugVisitorInterface* debug_visitor_; |
(...skipping 27 matching lines...) Expand all Loading... |
736 // If a HEADERS frame is followed by a CONTINUATION frame, the FIN/END_STREAM | 792 // 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 | 793 // 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 | 794 // we know to terminate the stream when the entire header block has been |
739 // processed. | 795 // processed. |
740 bool end_stream_when_done_; | 796 bool end_stream_when_done_; |
741 }; | 797 }; |
742 | 798 |
743 } // namespace net | 799 } // namespace net |
744 | 800 |
745 #endif // NET_SPDY_SPDY_FRAMER_H_ | 801 #endif // NET_SPDY_SPDY_FRAMER_H_ |
OLD | NEW |