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. |
| 1798 std::unique_ptr<SpdyFrameSequence> SpdyFramer::CreateIterator( |
| 1799 SpdyFramer* framer, |
| 1800 std::unique_ptr<SpdyFrameIR> frame_ir) { |
| 1801 std::unique_ptr<SpdyFrameSequence> result = nullptr; |
| 1802 switch (frame_ir->frame_type()) { |
| 1803 case SpdyFrameType::DATA: { |
| 1804 DLOG(ERROR) << "Data should use a different path to write"; |
| 1805 result = nullptr; |
| 1806 break; |
| 1807 } |
| 1808 case SpdyFrameType::HEADERS: { |
| 1809 result = base::MakeUnique<SpdyHeaderFrameIterator>( |
| 1810 framer, |
| 1811 base::WrapUnique(static_cast<SpdyHeadersIR*>(frame_ir.get()))); |
| 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 |