blob: a64f91596fc7b16a6934f2b468cb69950fe42647 [file] [log] [blame]
QUICHE teama296f272021-04-06 12:54:53 -07001#include "http2/adapter/test_frame_sequence.h"
2
3#include "http2/adapter/http2_util.h"
QUICHE team2bec7dd2021-05-17 13:57:31 -07004#include "http2/adapter/oghttp2_util.h"
QUICHE team27fe0d52021-06-24 12:38:08 -07005#include "spdy/core/hpack/hpack_encoder.h"
QUICHE teama296f272021-04-06 12:54:53 -07006#include "spdy/core/spdy_framer.h"
7
8namespace http2 {
9namespace adapter {
10namespace test {
11
QUICHE teamf723cd92021-05-17 11:09:51 -070012std::vector<const Header> ToHeaders(
13 absl::Span<const std::pair<absl::string_view, absl::string_view>> headers) {
14 std::vector<const Header> out;
15 for (auto [name, value] : headers) {
16 out.push_back(std::make_pair(HeaderRep(name), HeaderRep(value)));
17 }
18 return out;
19}
20
QUICHE teama296f272021-04-06 12:54:53 -070021TestFrameSequence& TestFrameSequence::ClientPreface() {
22 preface_ = spdy::kHttp2ConnectionHeaderPrefix;
23 frames_.push_back(absl::make_unique<spdy::SpdySettingsIR>());
24 return *this;
25}
26
27TestFrameSequence& TestFrameSequence::ServerPreface() {
28 frames_.push_back(absl::make_unique<spdy::SpdySettingsIR>());
29 return *this;
30}
31
32TestFrameSequence& TestFrameSequence::Data(Http2StreamId stream_id,
33 absl::string_view payload,
34 bool fin,
35 absl::optional<int> padding_length) {
36 auto data = absl::make_unique<spdy::SpdyDataIR>(stream_id, payload);
37 data->set_fin(fin);
38 if (padding_length) {
39 data->set_padding_len(padding_length.value());
40 }
41 frames_.push_back(std::move(data));
42 return *this;
43}
44
45TestFrameSequence& TestFrameSequence::RstStream(Http2StreamId stream_id,
46 Http2ErrorCode error) {
47 frames_.push_back(absl::make_unique<spdy::SpdyRstStreamIR>(
48 stream_id, TranslateErrorCode(error)));
49 return *this;
50}
51
52TestFrameSequence& TestFrameSequence::Settings(
53 absl::Span<Http2Setting> values) {
54 auto settings = absl::make_unique<spdy::SpdySettingsIR>();
55 for (const Http2Setting& setting : values) {
56 settings->AddSetting(setting.id, setting.value);
57 }
58 frames_.push_back(std::move(settings));
59 return *this;
60}
61
62TestFrameSequence& TestFrameSequence::SettingsAck() {
63 auto settings = absl::make_unique<spdy::SpdySettingsIR>();
64 settings->set_is_ack(true);
65 frames_.push_back(std::move(settings));
66 return *this;
67}
68
69TestFrameSequence& TestFrameSequence::Ping(Http2PingId id) {
70 frames_.push_back(absl::make_unique<spdy::SpdyPingIR>(id));
71 return *this;
72}
73
74TestFrameSequence& TestFrameSequence::PingAck(Http2PingId id) {
75 auto ping = absl::make_unique<spdy::SpdyPingIR>(id);
76 ping->set_is_ack(true);
77 frames_.push_back(std::move(ping));
78 return *this;
79}
80
81TestFrameSequence& TestFrameSequence::GoAway(Http2StreamId last_good_stream_id,
82 Http2ErrorCode error,
83 absl::string_view payload) {
84 frames_.push_back(absl::make_unique<spdy::SpdyGoAwayIR>(
85 last_good_stream_id, TranslateErrorCode(error), std::string(payload)));
86 return *this;
87}
88
QUICHE teamf723cd92021-05-17 11:09:51 -070089TestFrameSequence& TestFrameSequence::Headers(
90 Http2StreamId stream_id,
91 absl::Span<const std::pair<absl::string_view, absl::string_view>> headers,
92 bool fin) {
93 return Headers(stream_id, ToHeaders(headers), fin);
94}
95
QUICHE teama296f272021-04-06 12:54:53 -070096TestFrameSequence& TestFrameSequence::Headers(Http2StreamId stream_id,
97 spdy::Http2HeaderBlock block,
98 bool fin) {
99 auto headers =
100 absl::make_unique<spdy::SpdyHeadersIR>(stream_id, std::move(block));
101 headers->set_fin(fin);
102 frames_.push_back(std::move(headers));
103 return *this;
104}
105
106TestFrameSequence& TestFrameSequence::Headers(Http2StreamId stream_id,
107 absl::Span<const Header> headers,
108 bool fin) {
QUICHE team2bec7dd2021-05-17 13:57:31 -0700109 return Headers(stream_id, ToHeaderBlock(headers), fin);
QUICHE teama296f272021-04-06 12:54:53 -0700110}
111
112TestFrameSequence& TestFrameSequence::WindowUpdate(Http2StreamId stream_id,
113 int32_t delta) {
114 frames_.push_back(
115 absl::make_unique<spdy::SpdyWindowUpdateIR>(stream_id, delta));
116 return *this;
117}
118
119TestFrameSequence& TestFrameSequence::Priority(Http2StreamId stream_id,
120 Http2StreamId parent_stream_id,
121 int weight,
122 bool exclusive) {
123 frames_.push_back(absl::make_unique<spdy::SpdyPriorityIR>(
124 stream_id, parent_stream_id, weight, exclusive));
125 return *this;
126}
127
QUICHE team27fe0d52021-06-24 12:38:08 -0700128TestFrameSequence& TestFrameSequence::Metadata(Http2StreamId stream_id,
129 absl::string_view payload) {
130 // Encode the payload using a header block.
131 spdy::SpdyHeaderBlock block;
132 block["example-payload"] = payload;
133 spdy::HpackEncoder encoder;
134 encoder.DisableCompression();
135 std::string encoded_payload;
136 encoder.EncodeHeaderSet(block, &encoded_payload);
137 frames_.push_back(absl::make_unique<spdy::SpdyUnknownIR>(
138 stream_id, kMetadataFrameType, kMetadataEndFlag,
139 std::move(encoded_payload)));
140 return *this;
141}
142
QUICHE teama296f272021-04-06 12:54:53 -0700143std::string TestFrameSequence::Serialize() {
144 std::string result;
145 if (!preface_.empty()) {
146 result = preface_;
147 }
148 spdy::SpdyFramer framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
149 for (const auto& frame : frames_) {
150 spdy::SpdySerializedFrame f = framer.SerializeFrame(*frame);
151 absl::StrAppend(&result, absl::string_view(f));
152 }
153 return result;
154}
155
156} // namespace test
157} // namespace adapter
158} // namespace http2