| 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 |