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 #include "net/spdy/core/spdy_framer.h" | 5 #include "net/spdy/core/spdy_framer.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <cctype> | 10 #include <cctype> |
(...skipping 1656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1667 } | 1667 } |
1668 | 1668 |
1669 SpdyFramer::SpdyFrameIterator::SpdyFrameIterator(SpdyFramer* framer) | 1669 SpdyFramer::SpdyFrameIterator::SpdyFrameIterator(SpdyFramer* framer) |
1670 : framer_(framer), | 1670 : framer_(framer), |
1671 is_first_frame_(true), | 1671 is_first_frame_(true), |
1672 has_next_frame_(true), | 1672 has_next_frame_(true), |
1673 debug_total_size_(0) {} | 1673 debug_total_size_(0) {} |
1674 | 1674 |
1675 SpdyFramer::SpdyFrameIterator::~SpdyFrameIterator() {} | 1675 SpdyFramer::SpdyFrameIterator::~SpdyFrameIterator() {} |
1676 | 1676 |
1677 bool SpdyFramer::SpdyFrameIterator::NextFrame(ZeroCopyOutputBuffer* output) { | 1677 size_t SpdyFramer::SpdyFrameIterator::NextFrame(ZeroCopyOutputBuffer* output) { |
1678 SpdyFrameWithHeaderBlockIR* frame_ir = GetIR(); | 1678 SpdyFrameWithHeaderBlockIR* frame_ir = GetIR(); |
1679 if (frame_ir == nullptr) { | 1679 if (frame_ir == nullptr) { |
1680 LOG(WARNING) << "frame_ir doesn't exist."; | 1680 LOG(WARNING) << "frame_ir doesn't exist."; |
1681 return false; | 1681 return false; |
1682 } | 1682 } |
1683 if (!has_next_frame_) { | 1683 if (!has_next_frame_) { |
1684 SPDY_BUG << "SpdyFramer::SpdyFrameIterator::NextFrame called without " | 1684 SPDY_BUG << "SpdyFramer::SpdyFrameIterator::NextFrame called without " |
1685 << "a next frame."; | 1685 << "a next frame."; |
1686 return false; | 1686 return false; |
1687 } | 1687 } |
(...skipping 17 matching lines...) Expand all Loading... | |
1705 framer_->GetSerializedLength(&frame_ir->header_block()); | 1705 framer_->GetSerializedLength(&frame_ir->header_block()); |
1706 framer_->debug_visitor_->OnSendCompressedFrame( | 1706 framer_->debug_visitor_->OnSendCompressedFrame( |
1707 frame_ir->stream_id(), frame_ir->frame_type(), debug_payload_len, | 1707 frame_ir->stream_id(), frame_ir->frame_type(), debug_payload_len, |
1708 debug_total_size_); | 1708 debug_total_size_); |
1709 } | 1709 } |
1710 } | 1710 } |
1711 | 1711 |
1712 if (is_first_frame_) { | 1712 if (is_first_frame_) { |
1713 is_first_frame_ = false; | 1713 is_first_frame_ = false; |
1714 frame_ir->set_end_headers(!has_next_frame_); | 1714 frame_ir->set_end_headers(!has_next_frame_); |
1715 return SerializeGivenEncoding(*encoding, output); | 1715 size_t free_bytes_before = output->BytesFree(); |
1716 bool ok = SerializeGivenEncoding(*encoding, output); | |
1717 return ok ? free_bytes_before - output->BytesFree() : 0; | |
1716 } else { | 1718 } else { |
1717 SpdyContinuationIR continuation_ir(frame_ir->stream_id()); | 1719 SpdyContinuationIR continuation_ir(frame_ir->stream_id()); |
1718 continuation_ir.set_end_headers(!has_next_frame_); | 1720 continuation_ir.set_end_headers(!has_next_frame_); |
1719 continuation_ir.take_encoding(std::move(encoding)); | 1721 continuation_ir.take_encoding(std::move(encoding)); |
1720 return framer_->SerializeContinuation(continuation_ir, output); | 1722 return framer_->SerializeContinuation(continuation_ir, output); |
1721 } | 1723 } |
1722 } | 1724 } |
1723 | 1725 |
1724 bool SpdyFramer::SpdyFrameIterator::HasNextFrame() const { | 1726 bool SpdyFramer::SpdyFrameIterator::HasNextFrame() const { |
1725 return has_next_frame_; | 1727 return has_next_frame_; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1767 return GetFramer()->GetPushPromiseFrameSizeSansBlock(*push_promise_ir_); | 1769 return GetFramer()->GetPushPromiseFrameSizeSansBlock(*push_promise_ir_); |
1768 } | 1770 } |
1769 | 1771 |
1770 bool SpdyFramer::SpdyPushPromiseFrameIterator::SerializeGivenEncoding( | 1772 bool SpdyFramer::SpdyPushPromiseFrameIterator::SerializeGivenEncoding( |
1771 const SpdyString& encoding, | 1773 const SpdyString& encoding, |
1772 ZeroCopyOutputBuffer* output) const { | 1774 ZeroCopyOutputBuffer* output) const { |
1773 return GetFramer()->SerializePushPromiseGivenEncoding(*push_promise_ir_, | 1775 return GetFramer()->SerializePushPromiseGivenEncoding(*push_promise_ir_, |
1774 encoding, output); | 1776 encoding, output); |
1775 } | 1777 } |
1776 | 1778 |
1779 SpdyFramer::SpdyControlFrameIterator::SpdyControlFrameIterator( | |
1780 SpdyFramer* framer, | |
1781 std::unique_ptr<SpdyFrameIR> frame_ir) | |
1782 : framer_(framer), frame_ir_(std::move(frame_ir)) {} | |
1783 | |
1784 SpdyFramer::SpdyControlFrameIterator::~SpdyControlFrameIterator() {} | |
1785 | |
1786 size_t SpdyFramer::SpdyControlFrameIterator::NextFrame( | |
1787 ZeroCopyOutputBuffer* output) { | |
1788 size_t size_written = framer_->SerializeFrame(*frame_ir_, output); | |
1789 frame_ir_.reset(); | |
1790 return size_written; | |
1791 } | |
1792 | |
1793 bool SpdyFramer::SpdyControlFrameIterator::HasNextFrame() const { | |
1794 return frame_ir_ != nullptr; | |
1795 } | |
1796 | |
1797 // TODO(yasong): remove all the down_casts. | |
Lei Zhang
2017/05/04 21:22:46
I don't see any down_casts?
yasong
2017/05/09 20:42:06
Good catch! This code is merged from google3, and
| |
1798 std::unique_ptr<SpdyFrameSequence> SpdyFramer::CreateIterator( | |
1799 SpdyFramer* framer, | |
1800 std::unique_ptr<SpdyFrameIR> frame_ir) { | |
1801 std::unique_ptr<SpdyFrameSequence> result = nullptr; | |
Lei Zhang
2017/05/04 21:22:46
You don't have to explicitly initialize std::uniqu
Bence
2017/05/09 18:27:51
Acknowledged.
yasong
2017/05/09 20:42:06
Will be Fixed by cl/155545539.
| |
1802 switch (frame_ir->frame_type()) { | |
1803 case SpdyFrameType::DATA: { | |
1804 DLOG(ERROR) << "Data should use a different path to write"; | |
1805 result = nullptr; | |
Lei Zhang
2017/05/04 21:22:46
Or further set them to nullptr when they already a
Bence
2017/05/09 18:27:52
Acknowledged.
yasong
2017/05/09 20:42:06
Fixed by 155536594.
| |
1806 break; | |
1807 } | |
1808 case SpdyFrameType::HEADERS: { | |
1809 result = base::MakeUnique<SpdyHeaderFrameIterator>( | |
1810 framer, | |
1811 base::WrapUnique(static_cast<SpdyHeadersIR*>(frame_ir.get()))); | |
Lei Zhang
2017/05/04 21:22:46
Wait, how does this work? You can creating a new u
Bence
2017/05/09 18:27:51
Oops, good catch! Thank you.
yasong
2017/05/09 20:42:06
Fixed by 155536594.
| |
1812 break; | |
1813 } | |
1814 case SpdyFrameType::PUSH_PROMISE: { | |
1815 result = base::MakeUnique<SpdyPushPromiseFrameIterator>( | |
1816 framer, | |
1817 base::WrapUnique(static_cast<SpdyPushPromiseIR*>(frame_ir.get()))); | |
1818 break; | |
1819 } | |
1820 default: { | |
1821 result = base::MakeUnique<SpdyControlFrameIterator>(framer, | |
1822 std::move(frame_ir)); | |
1823 } | |
1824 } | |
1825 return result; | |
1826 } | |
1827 | |
1777 void SpdyFramer::SerializeDataBuilderHelper(const SpdyDataIR& data_ir, | 1828 void SpdyFramer::SerializeDataBuilderHelper(const SpdyDataIR& data_ir, |
1778 uint8_t* flags, | 1829 uint8_t* flags, |
1779 int* num_padding_fields, | 1830 int* num_padding_fields, |
1780 size_t* size_with_padding) const { | 1831 size_t* size_with_padding) const { |
1781 if (data_ir.fin()) { | 1832 if (data_ir.fin()) { |
1782 *flags = DATA_FLAG_FIN; | 1833 *flags = DATA_FLAG_FIN; |
1783 } | 1834 } |
1784 | 1835 |
1785 if (data_ir.padded()) { | 1836 if (data_ir.padded()) { |
1786 *flags = *flags | DATA_FLAG_PADDED; | 1837 *flags = *flags | DATA_FLAG_PADDED; |
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2699 | 2750 |
2700 namespace { | 2751 namespace { |
2701 | 2752 |
2702 class FrameSerializationVisitorWithOutput : public SpdyFrameVisitor { | 2753 class FrameSerializationVisitorWithOutput : public SpdyFrameVisitor { |
2703 public: | 2754 public: |
2704 explicit FrameSerializationVisitorWithOutput(SpdyFramer* framer, | 2755 explicit FrameSerializationVisitorWithOutput(SpdyFramer* framer, |
2705 ZeroCopyOutputBuffer* output) | 2756 ZeroCopyOutputBuffer* output) |
2706 : framer_(framer), output_(output), result_(false) {} | 2757 : framer_(framer), output_(output), result_(false) {} |
2707 ~FrameSerializationVisitorWithOutput() override {} | 2758 ~FrameSerializationVisitorWithOutput() override {} |
2708 | 2759 |
2709 bool Result() { return result_; } | 2760 size_t Result() { return result_; } |
2710 | 2761 |
2711 void VisitData(const SpdyDataIR& data) override { | 2762 void VisitData(const SpdyDataIR& data) override { |
2712 result_ = framer_->SerializeData(data, output_); | 2763 result_ = framer_->SerializeData(data, output_); |
2713 } | 2764 } |
2714 void VisitRstStream(const SpdyRstStreamIR& rst_stream) override { | 2765 void VisitRstStream(const SpdyRstStreamIR& rst_stream) override { |
2715 result_ = framer_->SerializeRstStream(rst_stream, output_); | 2766 result_ = framer_->SerializeRstStream(rst_stream, output_); |
2716 } | 2767 } |
2717 void VisitSettings(const SpdySettingsIR& settings) override { | 2768 void VisitSettings(const SpdySettingsIR& settings) override { |
2718 result_ = framer_->SerializeSettings(settings, output_); | 2769 result_ = framer_->SerializeSettings(settings, output_); |
2719 } | 2770 } |
(...skipping 23 matching lines...) Expand all Loading... | |
2743 } | 2794 } |
2744 | 2795 |
2745 private: | 2796 private: |
2746 SpdyFramer* framer_; | 2797 SpdyFramer* framer_; |
2747 ZeroCopyOutputBuffer* output_; | 2798 ZeroCopyOutputBuffer* output_; |
2748 bool result_; | 2799 bool result_; |
2749 }; | 2800 }; |
2750 | 2801 |
2751 } // namespace | 2802 } // namespace |
2752 | 2803 |
2753 bool SpdyFramer::SerializeFrame(const SpdyFrameIR& frame, | 2804 size_t SpdyFramer::SerializeFrame(const SpdyFrameIR& frame, |
2754 ZeroCopyOutputBuffer* output) { | 2805 ZeroCopyOutputBuffer* output) { |
2755 FrameSerializationVisitorWithOutput visitor(this, output); | 2806 FrameSerializationVisitorWithOutput visitor(this, output); |
2807 size_t free_bytes_before = output->BytesFree(); | |
2756 frame.Visit(&visitor); | 2808 frame.Visit(&visitor); |
2757 return visitor.Result(); | 2809 return visitor.Result() ? free_bytes_before - output->BytesFree() : 0; |
2758 } | 2810 } |
2759 | 2811 |
2760 size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) { | 2812 size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) { |
2761 DCHECK_GT(size, kMaxControlFrameSize); | 2813 DCHECK_GT(size, kMaxControlFrameSize); |
2762 size_t overflow = size - kMaxControlFrameSize; | 2814 size_t overflow = size - kMaxControlFrameSize; |
2763 size_t payload_size = kMaxControlFrameSize - GetContinuationMinimumSize(); | 2815 size_t payload_size = kMaxControlFrameSize - GetContinuationMinimumSize(); |
2764 // This is ceiling(overflow/payload_size) using integer arithmetics. | 2816 // This is ceiling(overflow/payload_size) using integer arithmetics. |
2765 return (overflow - 1) / payload_size + 1; | 2817 return (overflow - 1) / payload_size + 1; |
2766 } | 2818 } |
2767 | 2819 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2950 builder->WriteUInt32(header_block.size()); | 3002 builder->WriteUInt32(header_block.size()); |
2951 | 3003 |
2952 // Serialize each header. | 3004 // Serialize each header. |
2953 for (const auto& header : header_block) { | 3005 for (const auto& header : header_block) { |
2954 builder->WriteStringPiece32(base::ToLowerASCII(header.first)); | 3006 builder->WriteStringPiece32(base::ToLowerASCII(header.first)); |
2955 builder->WriteStringPiece32(header.second); | 3007 builder->WriteStringPiece32(header.second); |
2956 } | 3008 } |
2957 } | 3009 } |
2958 | 3010 |
2959 } // namespace net | 3011 } // namespace net |
OLD | NEW |