blob: 4759e42c372b86529dc27e746aaa375a165f5a5d [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/core/qpack/qpack_encoder.h"
6
bnc95734b22019-07-17 07:06:53 -07007#include <list>
vasilvv872e7a32019-03-12 16:42:44 -07008
bnc5f88b0c2019-06-21 05:11:20 -07009#include "net/third_party/quiche/src/quic/core/qpack/qpack_constants.h"
10#include "net/third_party/quiche/src/quic/core/qpack/qpack_instruction_encoder.h"
bnc8873e572019-07-25 08:45:42 -070011#include "net/third_party/quiche/src/quic/core/qpack/qpack_required_insert_count.h"
bnc5f88b0c2019-06-21 05:11:20 -070012#include "net/third_party/quiche/src/quic/core/qpack/value_splitting_header_list.h"
vasilvv0fb44432019-03-13 22:47:36 -070013#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050014#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050015
16namespace quic {
17
18QpackEncoder::QpackEncoder(
19 DecoderStreamErrorDelegate* decoder_stream_error_delegate,
renjietangc2aa5cb2019-06-20 12:22:53 -070020 QpackStreamSenderDelegate* encoder_stream_sender_delegate)
QUICHE teama6ef0a62019-03-07 20:34:33 -050021 : decoder_stream_error_delegate_(decoder_stream_error_delegate),
22 decoder_stream_receiver_(this),
23 encoder_stream_sender_(encoder_stream_sender_delegate) {
24 DCHECK(decoder_stream_error_delegate_);
25 DCHECK(encoder_stream_sender_delegate);
26}
27
28QpackEncoder::~QpackEncoder() {}
29
bncf21c1ad2019-06-20 20:09:50 -070030std::string QpackEncoder::EncodeHeaderList(
bnc5f88b0c2019-06-21 05:11:20 -070031 QuicStreamId /* stream_id */,
bncf21c1ad2019-06-20 20:09:50 -070032 const spdy::SpdyHeaderBlock* header_list) {
bnc95734b22019-07-17 07:06:53 -070033 // First pass.
bnc5f88b0c2019-06-21 05:11:20 -070034
bnc95734b22019-07-17 07:06:53 -070035 // Encode into |instructions| which will be serialized during the second pass.
36 std::list<InstructionWithValues> instructions;
bnc5f88b0c2019-06-21 05:11:20 -070037
38 for (const auto& header : ValueSplittingHeaderList(header_list)) {
39 QuicStringPiece name = header.first;
40 QuicStringPiece value = header.second;
41
42 bool is_static;
43 uint64_t index;
44
45 auto match_type =
46 header_table_.FindHeaderField(name, value, &is_static, &index);
47
48 switch (match_type) {
49 case QpackHeaderTable::MatchType::kNameAndValue:
50 DCHECK(is_static) << "Dynamic table entries not supported yet.";
51
bnc95734b22019-07-17 07:06:53 -070052 instructions.push_back({QpackIndexedHeaderFieldInstruction(), {}});
53 instructions.back().values.s_bit = is_static;
54 instructions.back().values.varint = index;
bnc5f88b0c2019-06-21 05:11:20 -070055
56 break;
57 case QpackHeaderTable::MatchType::kName:
58 DCHECK(is_static) << "Dynamic table entries not supported yet.";
59
bnc95734b22019-07-17 07:06:53 -070060 instructions.push_back(
61 {QpackLiteralHeaderFieldNameReferenceInstruction(), {}});
62 instructions.back().values.s_bit = is_static;
63 instructions.back().values.varint = index;
64 instructions.back().values.value = value;
bnc5f88b0c2019-06-21 05:11:20 -070065
66 break;
67 case QpackHeaderTable::MatchType::kNoMatch:
bnc95734b22019-07-17 07:06:53 -070068 instructions.push_back({QpackLiteralHeaderFieldInstruction(), {}});
69 instructions.back().values.name = name;
70 instructions.back().values.value = value;
bnc5f88b0c2019-06-21 05:11:20 -070071
72 break;
73 }
bncf21c1ad2019-06-20 20:09:50 -070074 }
bnc5f88b0c2019-06-21 05:11:20 -070075
bnc8873e572019-07-25 08:45:42 -070076 // TODO(bnc): Implement dynamic entries and set Required Insert Count
77 // accordingly.
78 const uint64_t required_insert_count = 0;
79
bnc95734b22019-07-17 07:06:53 -070080 // Second pass.
81 QpackInstructionEncoder instruction_encoder;
82 std::string encoded_headers;
83
84 // Header block prefix.
bnc95734b22019-07-17 07:06:53 -070085 QpackInstructionEncoder::Values values;
bnc8873e572019-07-25 08:45:42 -070086 values.varint = QpackEncodeRequiredInsertCount(required_insert_count,
87 header_table_.max_entries());
bnc95734b22019-07-17 07:06:53 -070088 values.varint2 = 0; // Delta Base.
89 values.s_bit = false; // Delta Base sign.
90
91 instruction_encoder.Encode(QpackPrefixInstruction(), values,
92 &encoded_headers);
93
94 for (const auto& instruction : instructions) {
95 instruction_encoder.Encode(instruction.instruction, instruction.values,
96 &encoded_headers);
97 }
98
bncf21c1ad2019-06-20 20:09:50 -070099 return encoded_headers;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500100}
101
102void QpackEncoder::DecodeDecoderStreamData(QuicStringPiece data) {
103 decoder_stream_receiver_.Decode(data);
104}
105
dschinazi17d42422019-06-18 16:35:07 -0700106void QpackEncoder::OnInsertCountIncrement(uint64_t /*increment*/) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500107 // TODO(bnc): Implement dynamic table management for encoding.
108}
109
dschinazi17d42422019-06-18 16:35:07 -0700110void QpackEncoder::OnHeaderAcknowledgement(QuicStreamId /*stream_id*/) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500111 // TODO(bnc): Implement dynamic table management for encoding.
112}
113
dschinazi17d42422019-06-18 16:35:07 -0700114void QpackEncoder::OnStreamCancellation(QuicStreamId /*stream_id*/) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500115 // TODO(bnc): Implement dynamic table management for encoding.
116}
117
118void QpackEncoder::OnErrorDetected(QuicStringPiece error_message) {
119 decoder_stream_error_delegate_->OnDecoderStreamError(error_message);
120}
121
122} // namespace quic