#include "quiche/http2/core/spdy_framer.h"
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include "absl/base/attributes.h"
#include "absl/memory/memory.h"
#include "quiche/http2/core/spdy_alt_svc_wire_format.h"
#include "quiche/http2/core/spdy_frame_builder.h"
#include "quiche/http2/core/spdy_protocol.h"
#include "quiche/http2/core/zero_copy_output_buffer.h"
#include "quiche/http2/hpack/hpack_constants.h"
#include "quiche/http2/hpack/hpack_encoder.h"
#include "quiche/common/platform/api/quiche_bug_tracker.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/spdy/core/http2_header_block.h"
namespace spdy {
namespace {
uint32_t PackStreamDependencyValues(bool exclusive,
SpdyStreamId parent_stream_id) { … }
const uint8_t kNoFlags = …;
const size_t kPadLengthFieldSize = …;
const size_t kOneSettingParameterSize = …;
size_t GetUncompressedSerializedLength(const Http2HeaderBlock& headers) { … }
uint8_t SerializeHeaderFrameFlags(const SpdyHeadersIR& header_ir,
const bool end_headers) { … }
uint8_t SerializePushPromiseFrameFlags(const SpdyPushPromiseIR& push_promise_ir,
const bool end_headers) { … }
bool SerializeHeadersGivenEncoding(const SpdyHeadersIR& headers,
const std::string& encoding,
const bool end_headers,
ZeroCopyOutputBuffer* output) { … }
bool SerializePushPromiseGivenEncoding(const SpdyPushPromiseIR& push_promise,
const std::string& encoding,
const bool end_headers,
ZeroCopyOutputBuffer* output) { … }
bool WritePayloadWithContinuation(SpdyFrameBuilder* builder,
const std::string& hpack_encoding,
SpdyStreamId stream_id, SpdyFrameType type,
int padding_payload_len) { … }
void SerializeDataBuilderHelper(const SpdyDataIR& data_ir, uint8_t* flags,
int* num_padding_fields,
size_t* size_with_padding) { … }
void SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper(
const SpdyDataIR& data_ir, uint8_t* flags, size_t* frame_size,
size_t* num_padding_fields) { … }
void SerializeSettingsBuilderHelper(const SpdySettingsIR& settings,
uint8_t* flags, const SettingsMap* values,
size_t* size) { … }
void SerializeAltSvcBuilderHelper(const SpdyAltSvcIR& altsvc_ir,
std::string* value, size_t* size) { … }
}
SpdyFramer::SpdyFramer(CompressionOption option)
: … { … }
SpdyFramer::~SpdyFramer() = default;
void SpdyFramer::set_debug_visitor(
SpdyFramerDebugVisitorInterface* debug_visitor) { … }
SpdyFramer::SpdyFrameIterator::SpdyFrameIterator(SpdyFramer* framer)
: … { … }
SpdyFramer::SpdyFrameIterator::~SpdyFrameIterator() = default;
size_t SpdyFramer::SpdyFrameIterator::NextFrame(ZeroCopyOutputBuffer* output) { … }
bool SpdyFramer::SpdyFrameIterator::HasNextFrame() const { … }
SpdyFramer::SpdyHeaderFrameIterator::SpdyHeaderFrameIterator(
SpdyFramer* framer, std::unique_ptr<const SpdyHeadersIR> headers_ir)
: … { … }
SpdyFramer::SpdyHeaderFrameIterator::~SpdyHeaderFrameIterator() = default;
const SpdyFrameIR* SpdyFramer::SpdyHeaderFrameIterator::GetIR() const { … }
size_t SpdyFramer::SpdyHeaderFrameIterator::GetFrameSizeSansBlock() const { … }
bool SpdyFramer::SpdyHeaderFrameIterator::SerializeGivenEncoding(
const std::string& encoding, ZeroCopyOutputBuffer* output) const { … }
SpdyFramer::SpdyPushPromiseFrameIterator::SpdyPushPromiseFrameIterator(
SpdyFramer* framer,
std::unique_ptr<const SpdyPushPromiseIR> push_promise_ir)
: … { … }
SpdyFramer::SpdyPushPromiseFrameIterator::~SpdyPushPromiseFrameIterator() =
default;
const SpdyFrameIR* SpdyFramer::SpdyPushPromiseFrameIterator::GetIR() const { … }
size_t SpdyFramer::SpdyPushPromiseFrameIterator::GetFrameSizeSansBlock() const { … }
bool SpdyFramer::SpdyPushPromiseFrameIterator::SerializeGivenEncoding(
const std::string& encoding, ZeroCopyOutputBuffer* output) const { … }
SpdyFramer::SpdyControlFrameIterator::SpdyControlFrameIterator(
SpdyFramer* framer, std::unique_ptr<const SpdyFrameIR> frame_ir)
: … { … }
SpdyFramer::SpdyControlFrameIterator::~SpdyControlFrameIterator() = default;
size_t SpdyFramer::SpdyControlFrameIterator::NextFrame(
ZeroCopyOutputBuffer* output) { … }
bool SpdyFramer::SpdyControlFrameIterator::HasNextFrame() const { … }
const SpdyFrameIR* SpdyFramer::SpdyControlFrameIterator::GetIR() const { … }
std::unique_ptr<SpdyFrameSequence> SpdyFramer::CreateIterator(
SpdyFramer* framer, std::unique_ptr<const SpdyFrameIR> frame_ir) { … }
SpdySerializedFrame SpdyFramer::SerializeData(const SpdyDataIR& data_ir) { … }
SpdySerializedFrame SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
const SpdyDataIR& data_ir) { … }
SpdySerializedFrame SpdyFramer::SerializeRstStream(
const SpdyRstStreamIR& rst_stream) const { … }
SpdySerializedFrame SpdyFramer::SerializeSettings(
const SpdySettingsIR& settings) const { … }
SpdySerializedFrame SpdyFramer::SerializePing(const SpdyPingIR& ping) const { … }
SpdySerializedFrame SpdyFramer::SerializeGoAway(
const SpdyGoAwayIR& goaway) const { … }
void SpdyFramer::SerializeHeadersBuilderHelper(const SpdyHeadersIR& headers,
uint8_t* flags, size_t* size,
std::string* hpack_encoding,
int* weight,
size_t* length_field) { … }
SpdySerializedFrame SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers) { … }
SpdySerializedFrame SpdyFramer::SerializeWindowUpdate(
const SpdyWindowUpdateIR& window_update) { … }
void SpdyFramer::SerializePushPromiseBuilderHelper(
const SpdyPushPromiseIR& push_promise, uint8_t* flags,
std::string* hpack_encoding, size_t* size) { … }
SpdySerializedFrame SpdyFramer::SerializePushPromise(
const SpdyPushPromiseIR& push_promise) { … }
SpdySerializedFrame SpdyFramer::SerializeContinuation(
const SpdyContinuationIR& continuation) const { … }
SpdySerializedFrame SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir) { … }
SpdySerializedFrame SpdyFramer::SerializePriority(
const SpdyPriorityIR& priority) const { … }
SpdySerializedFrame SpdyFramer::SerializePriorityUpdate(
const SpdyPriorityUpdateIR& priority_update) const { … }
SpdySerializedFrame SpdyFramer::SerializeAcceptCh(
const SpdyAcceptChIR& accept_ch) const { … }
SpdySerializedFrame SpdyFramer::SerializeUnknown(
const SpdyUnknownIR& unknown) const { … }
namespace {
class FrameSerializationVisitor : public SpdyFrameVisitor { … };
class FlagsSerializationVisitor : public SpdyFrameVisitor { … };
}
SpdySerializedFrame SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { … }
uint8_t SpdyFramer::GetSerializedFlags(const SpdyFrameIR& frame) { … }
bool SpdyFramer::SerializeData(const SpdyDataIR& data_ir,
ZeroCopyOutputBuffer* output) const { … }
bool SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
const SpdyDataIR& data_ir, ZeroCopyOutputBuffer* output) const { … }
bool SpdyFramer::SerializeRstStream(const SpdyRstStreamIR& rst_stream,
ZeroCopyOutputBuffer* output) const { … }
bool SpdyFramer::SerializeSettings(const SpdySettingsIR& settings,
ZeroCopyOutputBuffer* output) const { … }
bool SpdyFramer::SerializePing(const SpdyPingIR& ping,
ZeroCopyOutputBuffer* output) const { … }
bool SpdyFramer::SerializeGoAway(const SpdyGoAwayIR& goaway,
ZeroCopyOutputBuffer* output) const { … }
bool SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers,
ZeroCopyOutputBuffer* output) { … }
bool SpdyFramer::SerializeWindowUpdate(const SpdyWindowUpdateIR& window_update,
ZeroCopyOutputBuffer* output) const { … }
bool SpdyFramer::SerializePushPromise(const SpdyPushPromiseIR& push_promise,
ZeroCopyOutputBuffer* output) { … }
bool SpdyFramer::SerializeContinuation(const SpdyContinuationIR& continuation,
ZeroCopyOutputBuffer* output) const { … }
bool SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir,
ZeroCopyOutputBuffer* output) { … }
bool SpdyFramer::SerializePriority(const SpdyPriorityIR& priority,
ZeroCopyOutputBuffer* output) const { … }
bool SpdyFramer::SerializePriorityUpdate(
const SpdyPriorityUpdateIR& priority_update,
ZeroCopyOutputBuffer* output) const { … }
bool SpdyFramer::SerializeAcceptCh(const SpdyAcceptChIR& accept_ch,
ZeroCopyOutputBuffer* output) const { … }
bool SpdyFramer::SerializeUnknown(const SpdyUnknownIR& unknown,
ZeroCopyOutputBuffer* output) const { … }
namespace {
class FrameSerializationVisitorWithOutput : public SpdyFrameVisitor { … };
}
size_t SpdyFramer::SerializeFrame(const SpdyFrameIR& frame,
ZeroCopyOutputBuffer* output) { … }
HpackEncoder* SpdyFramer::GetHpackEncoder() { … }
void SpdyFramer::UpdateHeaderEncoderTableSize(uint32_t value) { … }
size_t SpdyFramer::header_encoder_table_size() const { … }
}