13 #include <glog/logging.h> 24 using namespace folly;
33 if (isalpha(
ch) && !islower(
ch)) {
61 vector<Header>&& headers) {
62 unique_ptr<IOBuf> encoded = encoder.
encode(headers);
64 return decode(decoder,
c,
c.totalLength());
67 uint64_t bufLen(
const std::unique_ptr<IOBuf>& buf) {
84 for (
int i = 0;
i < 3;
i++) {
92 vector<vector<string>> headers = {
93 {
"content-length",
"80"},
94 {
"content-encoding",
"gzip"},
95 {
"x-fb-debug",
"sdfgrwer"}
99 for (
int i = 0;
i < 3;
i++) {
110 client.setEncodeHeadroom(headroom);
111 unique_ptr<IOBuf> encodedReq = client.encode(req);
113 Cursor cursor(encodedReq.get());
114 auto result =
decode(server, cursor, cursor.totalLength());
123 vector<vector<string>> headers = {
124 {
"Content-Length",
"80"},
125 {
"Content-Encoding",
"gzip"},
126 {
"X-FB-Debug",
"bleah"}
130 auto& decoded = result->headers;
131 CHECK_EQ(decoded.size(), 6);
132 for (
int i = 0;
i < 6;
i += 2) {
142 vector<vector<string>> headers = {
143 {
"Content-Length",
"80"},
144 {
"Content-Encoding",
"gzip"},
145 {
"X-FB-Dup",
"bleah"},
146 {
"X-FB-Dup",
"hahaha"}
150 auto& decoded = result->headers;
151 CHECK_EQ(decoded.size(), 8);
153 for (
int i = 0;
i < 8;
i += 2) {
154 if (decoded[
i].str ==
"x-fb-dup") {
165 vector<vector<string>> headers = {
166 {
"Content-Length",
"80"}
170 unique_ptr<IOBuf> encodedReq = server.encode(req);
172 Cursor cursor(encodedReq.get());
175 client.setStats(&stats);
176 auto result =
decode(client, cursor, cursor.totalLength());
179 EXPECT_EQ(result.error(), HPACK::DecodeError::INVALID_INDEX);
181 client.setStats(
nullptr);
188 vector<vector<string>> headers = {
189 {
"Content-Length",
"80"},
190 {
"Content-Encoding",
"gzip"},
191 {
"X-FB-Debug",
"eirtijvdgtccffkutnbttcgbfieghgev"}
197 server.setStats(&stats);
198 unique_ptr<IOBuf> encodedResp = server.encode(resp);
206 server.setStats(
nullptr);
209 Cursor cursor(encodedResp.get());
211 client.setStats(&stats);
212 auto result =
decode(client, cursor, cursor.totalLength());
214 auto& decoded = result->headers;
215 CHECK_EQ(decoded.size(), 3 * 2);
222 client.setStats(
nullptr);
229 vector<vector<string>> headers;
231 string contentLength =
"Content-Length";
232 for (
int i = 0;
i < 10000;
i++) {
233 string value = folly::to<string>(
i);
234 vector<string> header = {contentLength, value};
235 headers.push_back(header);
239 EXPECT_EQ(result.error(), HPACK::DecodeError::HEADERS_TOO_LARGE);
247 vector<vector<string>> headers;
249 string contentLength =
"Content-Length";
250 for (
int i = 0;
i < 10000;
i++) {
251 string value = folly::to<string>(
i);
252 vector<string> header = {contentLength, value};
253 headers.push_back(header);
256 unique_ptr<IOBuf> encoded = client.encode(encHeaders);
257 Cursor cursor(encoded.get());
260 server.setStats(&stats);
261 server.decodeStreaming(cursor, cursor.totalLength(), &cb);
262 auto result = cb.getResult();
264 EXPECT_EQ(result.error(), HPACK::DecodeError::HEADERS_TOO_LARGE);
270 size_t headersIndexableSize = 4;
273 client.encode(headers);
274 EXPECT_EQ(client.getHPACKTableInfo().egressHeadersStored_,
275 headersIndexableSize);
281 vector<vector<string>> noIndexHeadersStrings = {
282 {
"content-length",
"80"},
283 {
":path",
"/some/random/file.jpg"},
284 {
":path",
"checks_for_="},
285 {
"if-modified-since",
"some_value"},
286 {
"last-modified",
"some_value"}
289 headers.insert(headers.end(), noIndexHeaders.begin(), noIndexHeaders.end());
290 HPACKCodec testCodec{TransportDirection::UPSTREAM};
291 testCodec.
encode(headers);
293 testCodec.getHPACKTableInfo().egressHeadersStored_, headersIndexableSize);
313 for (
int i = 0;
i < 3;
i++) {
314 unique_ptr<IOBuf> encodedReq = client.encode(req);
315 auto len = bufLen(encodedReq);
317 queue->enqueueHeaderBlock(
i,
std::move(encodedReq), len, &cb,
false);
328 for (
int i = 0;
i < 4;
i++) {
332 std::vector<int> insertOrder{1, 3, 2, 0};
333 for (
auto i: insertOrder) {
334 auto& encodedReq = data[
i].first;
335 auto len = bufLen(encodedReq);
336 queue->enqueueHeaderBlock(
i,
std::move(encodedReq), len, &data[
i].second,
339 for (
auto& d: data) {
340 auto result = d.second.getResult();
351 for (
int i = 0;
i < 4;
i++) {
355 std::vector<int> insertOrder{0, 3, 2, 1};
356 for (
auto i: insertOrder) {
357 auto& encodedReq = data[
i].first;
358 auto len = bufLen(encodedReq);
360 queue->enqueueHeaderBlock(
i,
std::move(encodedReq), len, &data[
i].second,
363 for (
auto& d: data) {
364 auto result = d.second.getResult();
375 bool expectOk =
true;
377 for (
auto i: std::vector<int>({0, 0, 1, 0, 3, 3, 2})) {
378 unique_ptr<IOBuf> encodedReq = client.encode(req);
379 auto len = bufLen(encodedReq);
381 queue->enqueueHeaderBlock(
i,
std::move(encodedReq), len, &cb,
true);
388 EXPECT_EQ(result.error(), HPACK::DecodeError::BAD_SEQUENCE_NUMBER);
390 expectOk = !expectOk;
398 for (
int i = 0;
i < 4;
i++) {
400 if (
i == GetParam()) {
401 data.back().second.headersCompleteCb = [&] { queue.reset(); };
405 std::vector<int> insertOrder{0, 3, 2, 1};
406 for (
auto i: insertOrder) {
407 auto& encodedReq = data[
i].first;
408 auto len = bufLen(encodedReq);
411 queue->enqueueHeaderBlock(
i,
std::move(encodedReq), len, &data[
i].second,
421 ::testing::Values(0, 1, 2, 3));
std::unique_ptr< HPACKQueue > queue
void decodeStreaming(folly::io::Cursor &cursor, uint32_t length, HPACK::StreamingCallback *streamingCb) noexcept
bool isLowercase(StringPiece str)
vector< compress::Header > basicHeaders()
INSTANTIATE_TEST_CASE_P(Queue, HPACKQueueTests,::testing::Values(0, 1, 2, 3))
#define EXPECT_EQ(val1, val2)
TokenBindingMessage decode(folly::io::Cursor &cursor)
constexpr detail::Map< Move > move
vector< compress::Header > headersFromArray(vector< vector< string >> &a)
—— Concurrent Priority Queue Implementation ——
requires E e noexcept(noexcept(s.error(std::move(e))))
std::deque< HeaderPiece > HeaderPieceList
constexpr Unexpected< typename std::decay< Error >::type > makeUnexpected(Error &&)
std::size_t headroom() const
constexpr auto data(C &c) -> decltype(c.data())
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&...args)
TEST_F(AsyncSSLSocketWriteTest, write_coalescing1)
std::size_t computeChainDataLength() const
#define EXPECT_TRUE(condition)
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
TEST_P(HPACKQueueTests, QueueDeleted)
std::unique_ptr< folly::IOBuf > encode(std::vector< compress::Header > &headers) noexcept
void encodeDecode(vector< HPACKHeader > &headers, HPACKEncoder &encoder, HPACKDecoder &decoder)
folly::Expected< HeaderDecodeResult, HPACK::DecodeError > getResult()
#define EXPECT_GT(val1, val2)