1 // 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 "quiche/quic/core/http/http_encoder.h"
6
7 #include "absl/base/macros.h"
8 #include "quiche/quic/platform/api/quic_flags.h"
9 #include "quiche/quic/platform/api/quic_test.h"
10 #include "quiche/quic/test_tools/quic_test_utils.h"
11 #include "quiche/common/simple_buffer_allocator.h"
12 #include "quiche/common/test_tools/quiche_test_utils.h"
13
14 namespace quic {
15 namespace test {
16
TEST(HttpEncoderTest,SerializeDataFrameHeader)17 TEST(HttpEncoderTest, SerializeDataFrameHeader) {
18 quiche::QuicheBuffer buffer = HttpEncoder::SerializeDataFrameHeader(
19 /* payload_length = */ 5, quiche::SimpleBufferAllocator::Get());
20 char output[] = {0x00, // type (DATA)
21 0x05}; // length
22 EXPECT_EQ(ABSL_ARRAYSIZE(output), buffer.size());
23 quiche::test::CompareCharArraysWithHexError(
24 "DATA", buffer.data(), buffer.size(), output, ABSL_ARRAYSIZE(output));
25 }
26
TEST(HttpEncoderTest,SerializeHeadersFrameHeader)27 TEST(HttpEncoderTest, SerializeHeadersFrameHeader) {
28 std::string header =
29 HttpEncoder::SerializeHeadersFrameHeader(/* payload_length = */ 7);
30 char output[] = {0x01, // type (HEADERS)
31 0x07}; // length
32 quiche::test::CompareCharArraysWithHexError("HEADERS", header.data(),
33 header.length(), output,
34 ABSL_ARRAYSIZE(output));
35 }
36
TEST(HttpEncoderTest,SerializeSettingsFrame)37 TEST(HttpEncoderTest, SerializeSettingsFrame) {
38 SettingsFrame settings;
39 settings.values[1] = 2;
40 settings.values[6] = 5;
41 settings.values[256] = 4;
42 char output[] = {0x04, // type (SETTINGS)
43 0x07, // length
44 0x01, // identifier (SETTINGS_QPACK_MAX_TABLE_CAPACITY)
45 0x02, // content
46 0x06, // identifier (SETTINGS_MAX_HEADER_LIST_SIZE)
47 0x05, // content
48 0x41, 0x00, // identifier 0x100, varint encoded
49 0x04}; // content
50 std::string frame = HttpEncoder::SerializeSettingsFrame(settings);
51 quiche::test::CompareCharArraysWithHexError(
52 "SETTINGS", frame.data(), frame.length(), output, ABSL_ARRAYSIZE(output));
53 }
54
TEST(HttpEncoderTest,SerializeGoAwayFrame)55 TEST(HttpEncoderTest, SerializeGoAwayFrame) {
56 GoAwayFrame goaway;
57 goaway.id = 0x1;
58 char output[] = {0x07, // type (GOAWAY)
59 0x1, // length
60 0x01}; // ID
61 std::string frame = HttpEncoder::SerializeGoAwayFrame(goaway);
62 quiche::test::CompareCharArraysWithHexError(
63 "GOAWAY", frame.data(), frame.length(), output, ABSL_ARRAYSIZE(output));
64 }
65
TEST(HttpEncoderTest,SerializePriorityUpdateFrame)66 TEST(HttpEncoderTest, SerializePriorityUpdateFrame) {
67 PriorityUpdateFrame priority_update1;
68 priority_update1.prioritized_element_id = 0x03;
69 uint8_t output1[] = {0x80, 0x0f, 0x07, 0x00, // type (PRIORITY_UPDATE)
70 0x01, // length
71 0x03}; // prioritized element id
72
73 std::string frame1 =
74 HttpEncoder::SerializePriorityUpdateFrame(priority_update1);
75 quiche::test::CompareCharArraysWithHexError(
76 "PRIORITY_UPDATE", frame1.data(), frame1.length(),
77 reinterpret_cast<char*>(output1), ABSL_ARRAYSIZE(output1));
78
79 PriorityUpdateFrame priority_update2;
80 priority_update2.prioritized_element_id = 0x05;
81 priority_update2.priority_field_value = "foo";
82
83 uint8_t output2[] = {0x80, 0x0f, 0x07, 0x00, // type (PRIORITY_UPDATE)
84 0x04, // length
85 0x05, // prioritized element id
86 0x66, 0x6f, 0x6f}; // priority field value: "foo"
87
88 std::string frame2 =
89 HttpEncoder::SerializePriorityUpdateFrame(priority_update2);
90 quiche::test::CompareCharArraysWithHexError(
91 "PRIORITY_UPDATE", frame2.data(), frame2.length(),
92 reinterpret_cast<char*>(output2), ABSL_ARRAYSIZE(output2));
93 }
94
TEST(HttpEncoderTest,SerializeAcceptChFrame)95 TEST(HttpEncoderTest, SerializeAcceptChFrame) {
96 AcceptChFrame accept_ch;
97 uint8_t output1[] = {0x40, 0x89, // type (ACCEPT_CH)
98 0x00}; // length
99
100 std::string frame1 = HttpEncoder::SerializeAcceptChFrame(accept_ch);
101 quiche::test::CompareCharArraysWithHexError(
102 "ACCEPT_CH", frame1.data(), frame1.length(),
103 reinterpret_cast<char*>(output1), ABSL_ARRAYSIZE(output1));
104
105 accept_ch.entries.push_back({"foo", "bar"});
106 uint8_t output2[] = {0x40, 0x89, // type (ACCEPT_CH)
107 0x08, // payload length
108 0x03, 0x66, 0x6f, 0x6f, // length of "foo"; "foo"
109 0x03, 0x62, 0x61, 0x72}; // length of "bar"; "bar"
110
111 std::string frame2 = HttpEncoder::SerializeAcceptChFrame(accept_ch);
112 quiche::test::CompareCharArraysWithHexError(
113 "ACCEPT_CH", frame2.data(), frame2.length(),
114 reinterpret_cast<char*>(output2), ABSL_ARRAYSIZE(output2));
115 }
116
TEST(HttpEncoderTest,SerializeWebTransportStreamFrameHeader)117 TEST(HttpEncoderTest, SerializeWebTransportStreamFrameHeader) {
118 WebTransportSessionId session_id = 0x17;
119 char output[] = {0x40, 0x41, // type (WEBTRANSPORT_STREAM)
120 0x17}; // session ID
121
122 std::string frame =
123 HttpEncoder::SerializeWebTransportStreamFrameHeader(session_id);
124 quiche::test::CompareCharArraysWithHexError("WEBTRANSPORT_STREAM",
125 frame.data(), frame.length(),
126 output, sizeof(output));
127 }
128
TEST(HttpEncoderTest,SerializeMetadataFrameHeader)129 TEST(HttpEncoderTest, SerializeMetadataFrameHeader) {
130 std::string frame = HttpEncoder::SerializeMetadataFrameHeader(
131 /* payload_length = */ 7);
132 char output[] = {0x40, 0x4d, // type (METADATA, 0x4d, varint encoded)
133 0x07}; // length
134 quiche::test::CompareCharArraysWithHexError(
135 "METADATA", frame.data(), frame.length(), output, ABSL_ARRAYSIZE(output));
136 }
137
138 } // namespace test
139 } // namespace quic
140