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_CORE_SPDY_FRAMER_H_ | 5 #ifndef NET_SPDY_CORE_SPDY_FRAMER_H_ |
6 #define NET_SPDY_CORE_SPDY_FRAMER_H_ | 6 #define NET_SPDY_CORE_SPDY_FRAMER_H_ |
7 | 7 |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
(...skipping 27 matching lines...) Expand all Loading... |
38 class SpdyStreamTest; | 38 class SpdyStreamTest; |
39 | 39 |
40 class SpdyFramer; | 40 class SpdyFramer; |
41 class SpdyFrameBuilder; | 41 class SpdyFrameBuilder; |
42 class SpdyFramerDecoderAdapter; | 42 class SpdyFramerDecoderAdapter; |
43 | 43 |
44 namespace test { | 44 namespace test { |
45 | 45 |
46 class TestSpdyVisitor; | 46 class TestSpdyVisitor; |
47 class SpdyFramerPeer; | 47 class SpdyFramerPeer; |
| 48 class SpdyFramerTest_MultipleContinuationFramesWithIterator_Test; |
| 49 class SpdyFramerTest_PushPromiseFramesWithIterator_Test; |
48 | 50 |
49 } // namespace test | 51 } // namespace test |
50 | 52 |
51 // SpdyFramerVisitorInterface is a set of callbacks for the SpdyFramer. | 53 // SpdyFramerVisitorInterface is a set of callbacks for the SpdyFramer. |
52 // Implement this interface to receive event callbacks as frames are | 54 // Implement this interface to receive event callbacks as frames are |
53 // decoded from the framer. | 55 // decoded from the framer. |
54 // | 56 // |
55 // Control frames that contain HTTP2 header blocks (HEADER, and PUSH_PROMISE) | 57 // Control frames that contain HTTP2 header blocks (HEADER, and PUSH_PROMISE) |
56 // are processed in fashion that allows the decompressed header block to be | 58 // are processed in fashion that allows the decompressed header block to be |
57 // delivered in chunks to the visitor. | 59 // delivered in chunks to the visitor. |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 int weight, | 205 int weight, |
204 bool exclusive) {} | 206 bool exclusive) {} |
205 | 207 |
206 // Called when a frame type we don't recognize is received. | 208 // Called when a frame type we don't recognize is received. |
207 // Return true if this appears to be a valid extension frame, false otherwise. | 209 // Return true if this appears to be a valid extension frame, false otherwise. |
208 // We distinguish between extension frames and nonsense by checking | 210 // We distinguish between extension frames and nonsense by checking |
209 // whether the stream id is valid. | 211 // whether the stream id is valid. |
210 virtual bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) = 0; | 212 virtual bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) = 0; |
211 }; | 213 }; |
212 | 214 |
213 class SpdyFrameSequence { | 215 class SPDY_EXPORT_PRIVATE SpdyFrameSequence { |
214 public: | 216 public: |
215 virtual ~SpdyFrameSequence() {} | 217 virtual ~SpdyFrameSequence() {} |
216 | 218 |
217 // Serializes the next frame in the sequence to |output|. Returns the number | 219 // Serializes the next frame in the sequence to |output|. Returns the number |
218 // of bytes written to |output|. | 220 // of bytes written to |output|. |
219 virtual size_t NextFrame(ZeroCopyOutputBuffer* output) = 0; | 221 virtual size_t NextFrame(ZeroCopyOutputBuffer* output) = 0; |
220 | 222 |
221 // Returns true iff there is at least one more frame in the sequence. | 223 // Returns true iff there is at least one more frame in the sequence. |
222 virtual bool HasNextFrame() const = 0; | 224 virtual bool HasNextFrame() const = 0; |
223 }; | 225 }; |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 SpdyState state() const; | 386 SpdyState state() const; |
385 bool HasError() const { return state() == SPDY_ERROR; } | 387 bool HasError() const { return state() == SPDY_ERROR; } |
386 | 388 |
387 // Given a buffer containing a serialized header block parse out a | 389 // Given a buffer containing a serialized header block parse out a |
388 // SpdyHeaderBlock, putting the results in the given header block. | 390 // SpdyHeaderBlock, putting the results in the given header block. |
389 // Returns true if successfully parsed, false otherwise. | 391 // Returns true if successfully parsed, false otherwise. |
390 bool ParseHeaderBlockInBuffer(const char* header_data, | 392 bool ParseHeaderBlockInBuffer(const char* header_data, |
391 size_t header_length, | 393 size_t header_length, |
392 SpdyHeaderBlock* block) const; | 394 SpdyHeaderBlock* block) const; |
393 | 395 |
394 // Iteratively converts a SpdyFrameWithHeaderBlockIR into an appropriate | 396 // Create a SpdyFrameSequence to serialize |frame_ir|. |
395 // sequence of SpdySerializedFrames. | 397 static std::unique_ptr<SpdyFrameSequence> CreateIterator( |
396 class SPDY_EXPORT_PRIVATE SpdyFrameIterator { | 398 SpdyFramer* framer, |
397 public: | 399 std::unique_ptr<SpdyFrameIR> frame_ir); |
398 // Creates an iterator with the provided framer. | |
399 // Does not take ownership of |framer|. | |
400 // |framer| must outlive this instance. | |
401 explicit SpdyFrameIterator(SpdyFramer* framer); | |
402 virtual ~SpdyFrameIterator(); | |
403 | |
404 // Serializes the next frame in the sequence to |output|. Returns the number | |
405 // of bytes written to |output|. | |
406 virtual bool NextFrame(ZeroCopyOutputBuffer* output); | |
407 | |
408 // Returns true iff there is at least one more frame in the sequence. | |
409 virtual bool HasNextFrame() const; | |
410 | |
411 // SpdyFrameIterator is neither copyable nor movable. | |
412 SpdyFrameIterator(const SpdyFrameIterator&) = delete; | |
413 SpdyFrameIterator& operator=(const SpdyFrameIterator&) = delete; | |
414 | |
415 protected: | |
416 virtual SpdyFrameWithHeaderBlockIR* GetIR() const = 0; | |
417 virtual size_t GetFrameSizeSansBlock() const = 0; | |
418 virtual bool SerializeGivenEncoding(const SpdyString& encoding, | |
419 ZeroCopyOutputBuffer* output) const = 0; | |
420 | |
421 SpdyFramer* GetFramer() const { return framer_; } | |
422 void SetEncoder(SpdyFrameWithHeaderBlockIR* ir) { | |
423 encoder_ = | |
424 framer_->GetHpackEncoder()->EncodeHeaderSet(ir->header_block()); | |
425 } | |
426 | |
427 private: | |
428 SpdyFramer* const framer_; | |
429 std::unique_ptr<HpackEncoder::ProgressiveEncoder> encoder_; | |
430 bool is_first_frame_; | |
431 bool has_next_frame_; | |
432 | |
433 // Field for debug reporting. | |
434 size_t debug_total_size_; | |
435 }; | |
436 | |
437 // Iteratively converts a SpdyHeadersIR (with a possibly huge | |
438 // SpdyHeaderBlock) into an appropriate sequence of SpdySerializedFrames, and | |
439 // write to the output. | |
440 class SPDY_EXPORT_PRIVATE SpdyHeaderFrameIterator : public SpdyFrameIterator { | |
441 public: | |
442 // Does not take ownership of |framer|. Take ownership of |headers_ir|. | |
443 SpdyHeaderFrameIterator(SpdyFramer* framer, | |
444 std::unique_ptr<SpdyHeadersIR> headers_ir); | |
445 | |
446 ~SpdyHeaderFrameIterator() override; | |
447 | |
448 private: | |
449 SpdyFrameWithHeaderBlockIR* GetIR() const override; | |
450 size_t GetFrameSizeSansBlock() const override; | |
451 bool SerializeGivenEncoding(const SpdyString& encoding, | |
452 ZeroCopyOutputBuffer* output) const override; | |
453 | |
454 const std::unique_ptr<SpdyHeadersIR> headers_ir_; | |
455 }; | |
456 | |
457 // Iteratively converts a SpdyPushPromiseIR (with a possibly huge | |
458 // SpdyHeaderBlock) into an appropriate sequence of SpdySerializedFrames, and | |
459 // write to the output. | |
460 class SPDY_EXPORT_PRIVATE SpdyPushPromiseFrameIterator | |
461 : public SpdyFrameIterator { | |
462 public: | |
463 // Does not take ownership of |framer|. Take ownership of |push_promise_ir|. | |
464 SpdyPushPromiseFrameIterator( | |
465 SpdyFramer* framer, | |
466 std::unique_ptr<SpdyPushPromiseIR> push_promise_ir); | |
467 | |
468 ~SpdyPushPromiseFrameIterator() override; | |
469 | |
470 private: | |
471 SpdyFrameWithHeaderBlockIR* GetIR() const override; | |
472 size_t GetFrameSizeSansBlock() const override; | |
473 bool SerializeGivenEncoding(const SpdyString& encoding, | |
474 ZeroCopyOutputBuffer* output) const override; | |
475 | |
476 const std::unique_ptr<SpdyPushPromiseIR> push_promise_ir_; | |
477 }; | |
478 | 400 |
479 // Serialize a data frame. | 401 // Serialize a data frame. |
480 SpdySerializedFrame SerializeData(const SpdyDataIR& data) const; | 402 SpdySerializedFrame SerializeData(const SpdyDataIR& data) const; |
481 // Serializes the data frame header and optionally padding length fields, | 403 // Serializes the data frame header and optionally padding length fields, |
482 // excluding actual data payload and padding. | 404 // excluding actual data payload and padding. |
483 SpdySerializedFrame SerializeDataFrameHeaderWithPaddingLengthField( | 405 SpdySerializedFrame SerializeDataFrameHeaderWithPaddingLengthField( |
484 const SpdyDataIR& data) const; | 406 const SpdyDataIR& data) const; |
485 | 407 |
486 SpdySerializedFrame SerializeRstStream( | 408 SpdySerializedFrame SerializeRstStream( |
487 const SpdyRstStreamIR& rst_stream) const; | 409 const SpdyRstStreamIR& rst_stream) const; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 // availability of an alternative service to the client. | 510 // availability of an alternative service to the client. |
589 bool SerializeAltSvc(const SpdyAltSvcIR& altsvc, | 511 bool SerializeAltSvc(const SpdyAltSvcIR& altsvc, |
590 ZeroCopyOutputBuffer* output); | 512 ZeroCopyOutputBuffer* output); |
591 | 513 |
592 // Serializes a PRIORITY frame. The PRIORITY frame advises a change in | 514 // Serializes a PRIORITY frame. The PRIORITY frame advises a change in |
593 // the relative priority of the given stream. | 515 // the relative priority of the given stream. |
594 bool SerializePriority(const SpdyPriorityIR& priority, | 516 bool SerializePriority(const SpdyPriorityIR& priority, |
595 ZeroCopyOutputBuffer* output) const; | 517 ZeroCopyOutputBuffer* output) const; |
596 | 518 |
597 // Serialize a frame of unknown type. | 519 // Serialize a frame of unknown type. |
598 bool SerializeFrame(const SpdyFrameIR& frame, ZeroCopyOutputBuffer* output); | 520 size_t SerializeFrame(const SpdyFrameIR& frame, ZeroCopyOutputBuffer* output); |
599 | 521 |
600 // Returns whether this SpdyFramer will compress header blocks using HPACK. | 522 // Returns whether this SpdyFramer will compress header blocks using HPACK. |
601 bool compression_enabled() const { | 523 bool compression_enabled() const { |
602 return compression_option_ == ENABLE_COMPRESSION; | 524 return compression_option_ == ENABLE_COMPRESSION; |
603 } | 525 } |
604 | 526 |
605 void SetHpackIndexingPolicy(HpackEncoder::IndexingPolicy policy) { | 527 void SetHpackIndexingPolicy(HpackEncoder::IndexingPolicy policy) { |
606 GetHpackEncoder()->SetIndexingPolicy(std::move(policy)); | 528 GetHpackEncoder()->SetIndexingPolicy(std::move(policy)); |
607 } | 529 } |
608 | 530 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 friend class HttpNetworkLayer; // This is temporary for the server. | 607 friend class HttpNetworkLayer; // This is temporary for the server. |
686 friend class HttpNetworkTransactionTest; | 608 friend class HttpNetworkTransactionTest; |
687 friend class HttpProxyClientSocketPoolTest; | 609 friend class HttpProxyClientSocketPoolTest; |
688 friend class SpdyHttpStreamTest; | 610 friend class SpdyHttpStreamTest; |
689 friend class SpdyNetworkTransactionTest; | 611 friend class SpdyNetworkTransactionTest; |
690 friend class SpdyProxyClientSocketTest; | 612 friend class SpdyProxyClientSocketTest; |
691 friend class SpdySessionTest; | 613 friend class SpdySessionTest; |
692 friend class SpdyStreamTest; | 614 friend class SpdyStreamTest; |
693 friend class test::TestSpdyVisitor; | 615 friend class test::TestSpdyVisitor; |
694 friend class test::SpdyFramerPeer; | 616 friend class test::SpdyFramerPeer; |
| 617 friend class test::SpdyFramerTest_MultipleContinuationFramesWithIterator_Test; |
| 618 friend class test::SpdyFramerTest_PushPromiseFramesWithIterator_Test; |
| 619 |
| 620 // Iteratively converts a SpdyFrameIR into an appropriate sequence of Spdy |
| 621 // frames. |
| 622 // Example usage: |
| 623 // std::unique_ptr<SpdyFrameSequence> it = CreateIterator(framer, frame_ir); |
| 624 // while (it->HasNextFrame()) { |
| 625 // if(it->NextFrame(output) == 0) { |
| 626 // // Write failed; |
| 627 // } |
| 628 // } |
| 629 class SPDY_EXPORT_PRIVATE SpdyFrameIterator : public SpdyFrameSequence { |
| 630 public: |
| 631 // Creates an iterator with the provided framer. Does not take ownership of |
| 632 // |framer|, |framer| must outlive this instance. |
| 633 explicit SpdyFrameIterator(SpdyFramer* framer); |
| 634 ~SpdyFrameIterator() override; |
| 635 |
| 636 // Serializes the next frame in the sequence to |output|. Returns the number |
| 637 // of bytes written to |output|. |
| 638 size_t NextFrame(ZeroCopyOutputBuffer* output) override; |
| 639 |
| 640 // Returns true iff there is at least one more frame in the sequence. |
| 641 bool HasNextFrame() const override; |
| 642 |
| 643 // SpdyFrameIterator is neither copyable nor movable. |
| 644 SpdyFrameIterator(const SpdyFrameIterator&) = delete; |
| 645 SpdyFrameIterator& operator=(const SpdyFrameIterator&) = delete; |
| 646 |
| 647 protected: |
| 648 virtual SpdyFrameWithHeaderBlockIR* GetIR() const = 0; |
| 649 virtual size_t GetFrameSizeSansBlock() const = 0; |
| 650 virtual bool SerializeGivenEncoding(const SpdyString& encoding, |
| 651 ZeroCopyOutputBuffer* output) const = 0; |
| 652 |
| 653 SpdyFramer* GetFramer() const { return framer_; } |
| 654 void SetEncoder(SpdyFrameWithHeaderBlockIR* ir) { |
| 655 encoder_ = |
| 656 framer_->GetHpackEncoder()->EncodeHeaderSet(ir->header_block()); |
| 657 } |
| 658 |
| 659 private: |
| 660 SpdyFramer* const framer_; |
| 661 std::unique_ptr<HpackEncoder::ProgressiveEncoder> encoder_; |
| 662 bool is_first_frame_; |
| 663 bool has_next_frame_; |
| 664 |
| 665 // Field for debug reporting. |
| 666 size_t debug_total_size_; |
| 667 }; |
| 668 |
| 669 // Iteratively converts a SpdyHeadersIR (with a possibly huge |
| 670 // SpdyHeaderBlock) into an appropriate sequence of SpdySerializedFrames, and |
| 671 // write to the output. |
| 672 class SPDY_EXPORT_PRIVATE SpdyHeaderFrameIterator : public SpdyFrameIterator { |
| 673 public: |
| 674 // Does not take ownership of |framer|. Take ownership of |headers_ir|. |
| 675 SpdyHeaderFrameIterator(SpdyFramer* framer, |
| 676 std::unique_ptr<SpdyHeadersIR> headers_ir); |
| 677 |
| 678 ~SpdyHeaderFrameIterator() override; |
| 679 |
| 680 private: |
| 681 SpdyFrameWithHeaderBlockIR* GetIR() const override; |
| 682 size_t GetFrameSizeSansBlock() const override; |
| 683 bool SerializeGivenEncoding(const SpdyString& encoding, |
| 684 ZeroCopyOutputBuffer* output) const override; |
| 685 |
| 686 const std::unique_ptr<SpdyHeadersIR> headers_ir_; |
| 687 }; |
| 688 |
| 689 // Iteratively converts a SpdyPushPromiseIR (with a possibly huge |
| 690 // SpdyHeaderBlock) into an appropriate sequence of SpdySerializedFrames, and |
| 691 // write to the output. |
| 692 class SPDY_EXPORT_PRIVATE SpdyPushPromiseFrameIterator |
| 693 : public SpdyFrameIterator { |
| 694 public: |
| 695 // Does not take ownership of |framer|. Take ownership of |push_promise_ir|. |
| 696 SpdyPushPromiseFrameIterator( |
| 697 SpdyFramer* framer, |
| 698 std::unique_ptr<SpdyPushPromiseIR> push_promise_ir); |
| 699 |
| 700 ~SpdyPushPromiseFrameIterator() override; |
| 701 |
| 702 private: |
| 703 SpdyFrameWithHeaderBlockIR* GetIR() const override; |
| 704 size_t GetFrameSizeSansBlock() const override; |
| 705 bool SerializeGivenEncoding(const SpdyString& encoding, |
| 706 ZeroCopyOutputBuffer* output) const override; |
| 707 |
| 708 const std::unique_ptr<SpdyPushPromiseIR> push_promise_ir_; |
| 709 }; |
| 710 |
| 711 // Converts a SpdyFrameIR into one Spdy frame (a sequence of length 1), and |
| 712 // write it to the output. |
| 713 class SpdyControlFrameIterator : public SpdyFrameSequence { |
| 714 public: |
| 715 SpdyControlFrameIterator(SpdyFramer* framer, |
| 716 std::unique_ptr<SpdyFrameIR> frame_ir); |
| 717 ~SpdyControlFrameIterator() override; |
| 718 |
| 719 size_t NextFrame(ZeroCopyOutputBuffer* output) override; |
| 720 |
| 721 bool HasNextFrame() const override; |
| 722 |
| 723 private: |
| 724 SpdyFramer* const framer_; |
| 725 std::unique_ptr<SpdyFrameIR> frame_ir_; |
| 726 }; |
695 | 727 |
696 private: | 728 private: |
697 class CharBuffer { | 729 class CharBuffer { |
698 public: | 730 public: |
699 explicit CharBuffer(size_t capacity); | 731 explicit CharBuffer(size_t capacity); |
700 ~CharBuffer(); | 732 ~CharBuffer(); |
701 | 733 |
702 void CopyFrom(const char* data, size_t size); | 734 void CopyFrom(const char* data, size_t size); |
703 void Rewind(); | 735 void Rewind(); |
704 | 736 |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 // rather than reading all available input. | 980 // rather than reading all available input. |
949 bool process_single_input_frame_ = false; | 981 bool process_single_input_frame_ = false; |
950 | 982 |
951 // Latched value of FLAGS_chromium_http2_flag_remove_rewritelength. | 983 // Latched value of FLAGS_chromium_http2_flag_remove_rewritelength. |
952 bool skip_rewritelength_ = false; | 984 bool skip_rewritelength_ = false; |
953 }; | 985 }; |
954 | 986 |
955 } // namespace net | 987 } // namespace net |
956 | 988 |
957 #endif // NET_SPDY_CORE_SPDY_FRAMER_H_ | 989 #endif // NET_SPDY_CORE_SPDY_FRAMER_H_ |
OLD | NEW |