1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 250aadb33SDmitri Tikhonov#include <assert.h> 350aadb33SDmitri Tikhonov#include <errno.h> 450aadb33SDmitri Tikhonov#include <stdio.h> 550aadb33SDmitri Tikhonov#include <stdlib.h> 650aadb33SDmitri Tikhonov#include <string.h> 7461e84d8SAmol Deshpande#ifndef WIN32 850aadb33SDmitri Tikhonov#include <unistd.h> 9461e84d8SAmol Deshpande#else 10461e84d8SAmol Deshpande#include <getopt.h> 11461e84d8SAmol Deshpande#endif 1250aadb33SDmitri Tikhonov#include <sys/queue.h> 1350aadb33SDmitri Tikhonov 1450aadb33SDmitri Tikhonov#include "lsquic.h" 1550aadb33SDmitri Tikhonov#include "lsquic_frame_common.h" 16bea64822SDmitri Tikhonov#include "lshpack.h" 1750aadb33SDmitri Tikhonov#include "lsquic_mm.h" 183b55e6aeSDmitri Tikhonov#include "lsquic_int_types.h" 193b55e6aeSDmitri Tikhonov#include "lsquic_conn_flow.h" 203b55e6aeSDmitri Tikhonov#include "lsquic_sfcw.h" 213b55e6aeSDmitri Tikhonov#include "lsquic_rtt.h" 225392f7a3SLiteSpeed Tech#include "lsquic_hash.h" 233b55e6aeSDmitri Tikhonov#include "lsquic_conn.h" 245392f7a3SLiteSpeed Tech#include "lsquic_varint.h" 255392f7a3SLiteSpeed Tech#include "lsquic_hq.h" 263b55e6aeSDmitri Tikhonov#include "lsquic_stream.h" 273b55e6aeSDmitri Tikhonov#include "lsquic_conn_public.h" 2850aadb33SDmitri Tikhonov#include "lsquic_logger.h" 2919f667fbSDmitri Tikhonov#if LSQUIC_CONN_STATS 3019f667fbSDmitri Tikhonov#include "lsquic_int_types.h" 3119f667fbSDmitri Tikhonov#include "lsquic_conn.h" 3219f667fbSDmitri Tikhonov#endif 3350aadb33SDmitri Tikhonov 3450aadb33SDmitri Tikhonov#include "lsquic_frame_reader.h" 353b55e6aeSDmitri Tikhonov#include "lsquic_headers.h" 363b55e6aeSDmitri Tikhonov#include "lsquic_http1x_if.h" 3750aadb33SDmitri Tikhonov 3850aadb33SDmitri Tikhonov 3950aadb33SDmitri Tikhonovstruct callback_value /* What callback returns */ 4050aadb33SDmitri Tikhonov{ 4150aadb33SDmitri Tikhonov enum { 4250aadb33SDmitri Tikhonov CV_HEADERS, 4350aadb33SDmitri Tikhonov CV_SETTINGS, 4450aadb33SDmitri Tikhonov CV_PUSH_PROMISE, 4550aadb33SDmitri Tikhonov CV_PRIORITY, 4650aadb33SDmitri Tikhonov CV_ERROR, 4750aadb33SDmitri Tikhonov } type; 4850aadb33SDmitri Tikhonov unsigned stream_off; /* Checked only if not zero */ 4950aadb33SDmitri Tikhonov union { 503b55e6aeSDmitri Tikhonov struct headers { 513b55e6aeSDmitri Tikhonov uint32_t stream_id; 523b55e6aeSDmitri Tikhonov uint32_t oth_stream_id; 533b55e6aeSDmitri Tikhonov unsigned short weight; 543b55e6aeSDmitri Tikhonov signed char exclusive; 553b55e6aeSDmitri Tikhonov unsigned char flags; 563b55e6aeSDmitri Tikhonov unsigned size; 573b55e6aeSDmitri Tikhonov unsigned off; 583b55e6aeSDmitri Tikhonov char buf[0x100]; 593b55e6aeSDmitri Tikhonov } headers; 6050aadb33SDmitri Tikhonov struct { 6150aadb33SDmitri Tikhonov uint16_t id; 6250aadb33SDmitri Tikhonov uint32_t value; 6350aadb33SDmitri Tikhonov } setting; 6450aadb33SDmitri Tikhonov void *push_promise; 6550aadb33SDmitri Tikhonov struct cv_error { 6650aadb33SDmitri Tikhonov enum frame_reader_error code; 675392f7a3SLiteSpeed Tech lsquic_stream_id_t stream_id; 6850aadb33SDmitri Tikhonov } error; 6950aadb33SDmitri Tikhonov struct cv_priority { 705392f7a3SLiteSpeed Tech lsquic_stream_id_t stream_id; 7150aadb33SDmitri Tikhonov int exclusive; 725392f7a3SLiteSpeed Tech lsquic_stream_id_t dep_stream_id; 7350aadb33SDmitri Tikhonov unsigned weight; 7450aadb33SDmitri Tikhonov } priority; 7550aadb33SDmitri Tikhonov } u; 7650aadb33SDmitri Tikhonov}; 7750aadb33SDmitri Tikhonov 7850aadb33SDmitri Tikhonov 7950aadb33SDmitri Tikhonovvoid 803b55e6aeSDmitri Tikhonovcompare_headers (const struct headers *got_h, const struct headers *exp_h) 8150aadb33SDmitri Tikhonov{ 823b55e6aeSDmitri Tikhonov assert(got_h->stream_id == exp_h->stream_id); 833b55e6aeSDmitri Tikhonov assert(got_h->oth_stream_id == exp_h->oth_stream_id); 843b55e6aeSDmitri Tikhonov assert(got_h->weight == exp_h->weight); 853b55e6aeSDmitri Tikhonov assert(got_h->exclusive == exp_h->exclusive); 863b55e6aeSDmitri Tikhonov assert(got_h->size == exp_h->size); 873b55e6aeSDmitri Tikhonov assert(strlen(got_h->buf) == got_h->size); 883b55e6aeSDmitri Tikhonov assert(got_h->off == exp_h->off); 893b55e6aeSDmitri Tikhonov assert(got_h->flags == exp_h->flags); 903b55e6aeSDmitri Tikhonov assert(0 == memcmp(got_h->buf, exp_h->buf, got_h->size)); 9150aadb33SDmitri Tikhonov} 9250aadb33SDmitri Tikhonov 9350aadb33SDmitri Tikhonov 9450aadb33SDmitri Tikhonovvoid 953b55e6aeSDmitri Tikhonovcompare_push_promises (const struct headers *got_h, const struct headers *exp_h) 9650aadb33SDmitri Tikhonov{ 973b55e6aeSDmitri Tikhonov assert(got_h->stream_id == exp_h->stream_id); 983b55e6aeSDmitri Tikhonov assert(got_h->oth_stream_id == exp_h->oth_stream_id); 993b55e6aeSDmitri Tikhonov assert(got_h->size == exp_h->size); 1003b55e6aeSDmitri Tikhonov assert(strlen(got_h->buf) == got_h->size); 1013b55e6aeSDmitri Tikhonov assert(got_h->off == exp_h->off); 1023b55e6aeSDmitri Tikhonov assert(got_h->flags == exp_h->flags); 1033b55e6aeSDmitri Tikhonov assert(0 == memcmp(got_h->buf, exp_h->buf, got_h->size)); 10450aadb33SDmitri Tikhonov} 10550aadb33SDmitri Tikhonov 10650aadb33SDmitri Tikhonov 10750aadb33SDmitri Tikhonovvoid 10850aadb33SDmitri Tikhonovcompare_priorities (const struct cv_priority *got_prio, 10950aadb33SDmitri Tikhonov const struct cv_priority *exp_prio) 11050aadb33SDmitri Tikhonov{ 11150aadb33SDmitri Tikhonov assert(got_prio->stream_id == exp_prio->stream_id); 11250aadb33SDmitri Tikhonov assert(got_prio->exclusive == exp_prio->exclusive); 11350aadb33SDmitri Tikhonov assert(got_prio->dep_stream_id == exp_prio->dep_stream_id); 11450aadb33SDmitri Tikhonov assert(got_prio->weight == exp_prio->weight); 11550aadb33SDmitri Tikhonov} 11650aadb33SDmitri Tikhonov 11750aadb33SDmitri Tikhonov 11850aadb33SDmitri Tikhonovvoid 11950aadb33SDmitri Tikhonovcompare_errors (const struct cv_error *got_err, 12050aadb33SDmitri Tikhonov const struct cv_error *exp_err) 12150aadb33SDmitri Tikhonov{ 12250aadb33SDmitri Tikhonov assert(got_err->code == exp_err->code); 12350aadb33SDmitri Tikhonov assert(got_err->stream_id == exp_err->stream_id); 12450aadb33SDmitri Tikhonov} 12550aadb33SDmitri Tikhonov 12650aadb33SDmitri Tikhonov 12750aadb33SDmitri Tikhonovstatic void 12850aadb33SDmitri Tikhonovcompare_cb_vals (const struct callback_value *got, 12950aadb33SDmitri Tikhonov const struct callback_value *exp) 13050aadb33SDmitri Tikhonov{ 13150aadb33SDmitri Tikhonov assert(got->type == exp->type); 13250aadb33SDmitri Tikhonov if (exp->stream_off) 13350aadb33SDmitri Tikhonov assert(exp->stream_off == got->stream_off); 13450aadb33SDmitri Tikhonov switch (got->type) 13550aadb33SDmitri Tikhonov { 13650aadb33SDmitri Tikhonov case CV_HEADERS: 1373b55e6aeSDmitri Tikhonov compare_headers(&got->u.headers, &exp->u.headers); 13850aadb33SDmitri Tikhonov break; 13950aadb33SDmitri Tikhonov case CV_PUSH_PROMISE: 1403b55e6aeSDmitri Tikhonov compare_push_promises(&got->u.headers, &exp->u.headers); 14150aadb33SDmitri Tikhonov break; 14250aadb33SDmitri Tikhonov case CV_ERROR: 14350aadb33SDmitri Tikhonov compare_errors(&got->u.error, &exp->u.error); 14450aadb33SDmitri Tikhonov break; 14550aadb33SDmitri Tikhonov case CV_PRIORITY: 14650aadb33SDmitri Tikhonov compare_priorities(&got->u.priority, &exp->u.priority); 14750aadb33SDmitri Tikhonov break; 14850aadb33SDmitri Tikhonov case CV_SETTINGS: 14950aadb33SDmitri Tikhonov /* TODO */ 15050aadb33SDmitri Tikhonov break; 15150aadb33SDmitri Tikhonov } 15250aadb33SDmitri Tikhonov} 15350aadb33SDmitri Tikhonov 15450aadb33SDmitri Tikhonov 15550aadb33SDmitri Tikhonovstatic struct { 15650aadb33SDmitri Tikhonov size_t in_sz; 15750aadb33SDmitri Tikhonov size_t in_off; 15850aadb33SDmitri Tikhonov size_t in_max_req_sz; 15950aadb33SDmitri Tikhonov size_t in_max_sz; 16050aadb33SDmitri Tikhonov unsigned char in_buf[0x1000]; 16150aadb33SDmitri Tikhonov} input; 16250aadb33SDmitri Tikhonov 16350aadb33SDmitri Tikhonov 16450aadb33SDmitri Tikhonovstatic struct cb_ctx { 16550aadb33SDmitri Tikhonov unsigned n_cb_vals; 16650aadb33SDmitri Tikhonov struct callback_value cb_vals[10]; 16750aadb33SDmitri Tikhonov} g_cb_ctx; 16850aadb33SDmitri Tikhonov 16950aadb33SDmitri Tikhonov 17050aadb33SDmitri Tikhonovstatic void 17150aadb33SDmitri Tikhonovreset_cb_ctx (struct cb_ctx *cb_ctx) 17250aadb33SDmitri Tikhonov{ 17350aadb33SDmitri Tikhonov cb_ctx->n_cb_vals = 0; 17450aadb33SDmitri Tikhonov memset(&cb_ctx->cb_vals, 0xA5, sizeof(cb_ctx->cb_vals)); 17550aadb33SDmitri Tikhonov} 17650aadb33SDmitri Tikhonov 17750aadb33SDmitri Tikhonov 1783b55e6aeSDmitri Tikhonovstatic void 1793b55e6aeSDmitri Tikhonovcopy_uh_to_headers (const struct uncompressed_headers *uh, struct headers *h) 18050aadb33SDmitri Tikhonov{ 1813b55e6aeSDmitri Tikhonov const struct http1x_headers *h1h = uh->uh_hset; 1823b55e6aeSDmitri Tikhonov h->flags = uh->uh_flags; 1833b55e6aeSDmitri Tikhonov h->weight = uh->uh_weight; 1843b55e6aeSDmitri Tikhonov h->stream_id = uh->uh_stream_id; 1853b55e6aeSDmitri Tikhonov h->exclusive = uh->uh_exclusive; 1863b55e6aeSDmitri Tikhonov h->oth_stream_id = uh->uh_oth_stream_id; 1873b55e6aeSDmitri Tikhonov h->size = h1h->h1h_size; 1883b55e6aeSDmitri Tikhonov h->off = h1h->h1h_off; 1893b55e6aeSDmitri Tikhonov memcpy(h->buf, h1h->h1h_buf, h->size); 1903b55e6aeSDmitri Tikhonov h->buf[h->size] = '\0'; 19150aadb33SDmitri Tikhonov} 19250aadb33SDmitri Tikhonov 19350aadb33SDmitri Tikhonov 19450aadb33SDmitri Tikhonovstatic void 19550aadb33SDmitri Tikhonovon_incoming_headers (void *ctx, struct uncompressed_headers *uh) 19650aadb33SDmitri Tikhonov{ 19750aadb33SDmitri Tikhonov struct cb_ctx *cb_ctx = ctx; 19850aadb33SDmitri Tikhonov assert(cb_ctx == &g_cb_ctx); 19950aadb33SDmitri Tikhonov unsigned i = cb_ctx->n_cb_vals++; 20050aadb33SDmitri Tikhonov assert(i < sizeof(cb_ctx->cb_vals) / sizeof(cb_ctx->cb_vals[0])); 20150aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].type = CV_HEADERS; 20250aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].stream_off = input.in_off; 2033b55e6aeSDmitri Tikhonov copy_uh_to_headers(uh, &cb_ctx->cb_vals[i].u.headers); 2043b55e6aeSDmitri Tikhonov assert(uh->uh_flags & UH_H1H); 2053b55e6aeSDmitri Tikhonov lsquic_http1x_if->hsi_discard_header_set(uh->uh_hset); 20650aadb33SDmitri Tikhonov free(uh); 20750aadb33SDmitri Tikhonov} 20850aadb33SDmitri Tikhonov 20950aadb33SDmitri Tikhonov 21050aadb33SDmitri Tikhonovstatic void 21150aadb33SDmitri Tikhonovon_push_promise (void *ctx, struct uncompressed_headers *uh) 21250aadb33SDmitri Tikhonov{ 21350aadb33SDmitri Tikhonov struct cb_ctx *cb_ctx = ctx; 21450aadb33SDmitri Tikhonov assert(cb_ctx == &g_cb_ctx); 21550aadb33SDmitri Tikhonov unsigned i = cb_ctx->n_cb_vals++; 21650aadb33SDmitri Tikhonov assert(i < sizeof(cb_ctx->cb_vals) / sizeof(cb_ctx->cb_vals[0])); 21750aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].type = CV_PUSH_PROMISE; 21850aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].stream_off = input.in_off; 2193b55e6aeSDmitri Tikhonov copy_uh_to_headers(uh, &cb_ctx->cb_vals[i].u.headers); 2203b55e6aeSDmitri Tikhonov assert(uh->uh_flags & UH_H1H); 2213b55e6aeSDmitri Tikhonov lsquic_http1x_if->hsi_discard_header_set(uh->uh_hset); 22250aadb33SDmitri Tikhonov free(uh); 22350aadb33SDmitri Tikhonov} 22450aadb33SDmitri Tikhonov 22550aadb33SDmitri Tikhonov 22650aadb33SDmitri Tikhonovstatic void 2275392f7a3SLiteSpeed Techon_error (void *ctx, lsquic_stream_id_t stream_id, enum frame_reader_error error) 22850aadb33SDmitri Tikhonov{ 22950aadb33SDmitri Tikhonov struct cb_ctx *cb_ctx = ctx; 23050aadb33SDmitri Tikhonov assert(cb_ctx == &g_cb_ctx); 23150aadb33SDmitri Tikhonov unsigned i = cb_ctx->n_cb_vals++; 23250aadb33SDmitri Tikhonov assert(i < sizeof(cb_ctx->cb_vals) / sizeof(cb_ctx->cb_vals[0])); 23350aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].type = CV_ERROR; 23450aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].u.error.stream_id = stream_id; 23550aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].u.error.code = error; 23650aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].stream_off = input.in_off; 23750aadb33SDmitri Tikhonov} 23850aadb33SDmitri Tikhonov 23950aadb33SDmitri Tikhonov 24050aadb33SDmitri Tikhonovstatic void 24150aadb33SDmitri Tikhonovon_settings (void *ctx, uint16_t id, uint32_t value) 24250aadb33SDmitri Tikhonov{ 24350aadb33SDmitri Tikhonov struct cb_ctx *cb_ctx = ctx; 24450aadb33SDmitri Tikhonov assert(cb_ctx == &g_cb_ctx); 24550aadb33SDmitri Tikhonov unsigned i = cb_ctx->n_cb_vals++; 24650aadb33SDmitri Tikhonov assert(i < sizeof(cb_ctx->cb_vals) / sizeof(cb_ctx->cb_vals[0])); 24750aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].type = CV_SETTINGS; 24850aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].u.setting.id = id; 24950aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].u.setting.value = value; 25050aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].stream_off = input.in_off; 25150aadb33SDmitri Tikhonov} 25250aadb33SDmitri Tikhonov 25350aadb33SDmitri Tikhonov 25450aadb33SDmitri Tikhonovstatic void 2555392f7a3SLiteSpeed Techon_priority (void *ctx, lsquic_stream_id_t stream_id, int exclusive, 2565392f7a3SLiteSpeed Tech lsquic_stream_id_t dep_stream_id, unsigned weight) 25750aadb33SDmitri Tikhonov{ 25850aadb33SDmitri Tikhonov struct cb_ctx *cb_ctx = ctx; 25950aadb33SDmitri Tikhonov assert(cb_ctx == &g_cb_ctx); 26050aadb33SDmitri Tikhonov unsigned i = cb_ctx->n_cb_vals++; 26150aadb33SDmitri Tikhonov assert(i < sizeof(cb_ctx->cb_vals) / sizeof(cb_ctx->cb_vals[0])); 26250aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].type = CV_PRIORITY; 26350aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].u.priority.stream_id = stream_id; 26450aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].u.priority.exclusive = exclusive; 26550aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].u.priority.dep_stream_id = dep_stream_id; 26650aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].u.priority.weight = weight; 26750aadb33SDmitri Tikhonov cb_ctx->cb_vals[i].stream_off = input.in_off; 26850aadb33SDmitri Tikhonov} 26950aadb33SDmitri Tikhonov 27050aadb33SDmitri Tikhonov 27150aadb33SDmitri Tikhonovstatic const struct frame_reader_callbacks frame_callbacks = { 27250aadb33SDmitri Tikhonov .frc_on_headers = on_incoming_headers, 27350aadb33SDmitri Tikhonov .frc_on_push_promise = on_push_promise, 27450aadb33SDmitri Tikhonov .frc_on_settings = on_settings, 27550aadb33SDmitri Tikhonov .frc_on_priority = on_priority, 27650aadb33SDmitri Tikhonov .frc_on_error = on_error, 27750aadb33SDmitri Tikhonov}; 27850aadb33SDmitri Tikhonov 27950aadb33SDmitri Tikhonov 28050aadb33SDmitri Tikhonovstatic ssize_t 28150aadb33SDmitri Tikhonovread_from_stream (struct lsquic_stream *stream, void *buf, size_t sz) 28250aadb33SDmitri Tikhonov{ 28350aadb33SDmitri Tikhonov if (sz > input.in_max_req_sz) 28450aadb33SDmitri Tikhonov input.in_max_req_sz = sz; 28550aadb33SDmitri Tikhonov if (input.in_sz - input.in_off < sz) 28650aadb33SDmitri Tikhonov sz = input.in_sz - input.in_off; 28750aadb33SDmitri Tikhonov if (sz > input.in_max_sz) 28850aadb33SDmitri Tikhonov sz = input.in_max_sz; 28950aadb33SDmitri Tikhonov memcpy(buf, input.in_buf + input.in_off, sz); 29050aadb33SDmitri Tikhonov input.in_off += sz; 29150aadb33SDmitri Tikhonov return sz; 29250aadb33SDmitri Tikhonov} 29350aadb33SDmitri Tikhonov 29450aadb33SDmitri Tikhonov 29550aadb33SDmitri Tikhonovstruct frame_reader_test { 29650aadb33SDmitri Tikhonov unsigned frt_lineno; 29750aadb33SDmitri Tikhonov /* Input */ 29850aadb33SDmitri Tikhonov enum frame_reader_flags frt_fr_flags; 29950aadb33SDmitri Tikhonov unsigned char frt_buf[0x100]; 30050aadb33SDmitri Tikhonov unsigned short frt_bufsz; 30150aadb33SDmitri Tikhonov unsigned frt_max_headers_sz; 30250aadb33SDmitri Tikhonov /* Output */ 30350aadb33SDmitri Tikhonov unsigned short frt_in_off; 30450aadb33SDmitri Tikhonov int frt_err; /* True if expecting error */ 30550aadb33SDmitri Tikhonov unsigned frt_n_cb_vals; 30650aadb33SDmitri Tikhonov struct callback_value frt_cb_vals[10]; 30750aadb33SDmitri Tikhonov}; 30850aadb33SDmitri Tikhonov 30950aadb33SDmitri Tikhonov 3103b55e6aeSDmitri Tikhonov#define HEADERS(str) .buf = (str), .size = sizeof(str) - 1 31150aadb33SDmitri Tikhonov 31250aadb33SDmitri Tikhonovstatic const struct frame_reader_test tests[] = { 31350aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 31450aadb33SDmitri Tikhonov .frt_fr_flags = 0, 31550aadb33SDmitri Tikhonov .frt_buf = { 31650aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x04, 31750aadb33SDmitri Tikhonov /* Type: */ 0x01, 31850aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS, 31950aadb33SDmitri Tikhonov 0x80| /* <----- This bit must be ignored */ 32050aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 32150aadb33SDmitri Tikhonov /* Block fragment: */ 32250aadb33SDmitri Tikhonov 0x48, 0x82, 0x64, 0x02, 32350aadb33SDmitri Tikhonov }, 32450aadb33SDmitri Tikhonov .frt_bufsz = 13, 32550aadb33SDmitri Tikhonov .frt_n_cb_vals = 1, 32650aadb33SDmitri Tikhonov .frt_cb_vals = { 32750aadb33SDmitri Tikhonov { 32850aadb33SDmitri Tikhonov .type = CV_HEADERS, 3293b55e6aeSDmitri Tikhonov .u.headers = { 3303b55e6aeSDmitri Tikhonov .stream_id = 12345, 3313b55e6aeSDmitri Tikhonov .oth_stream_id = 0, 3323b55e6aeSDmitri Tikhonov .weight = 0, 3333b55e6aeSDmitri Tikhonov .exclusive = -1, 3343b55e6aeSDmitri Tikhonov .off = 0, 3353b55e6aeSDmitri Tikhonov .flags = UH_H1H, 3363b55e6aeSDmitri Tikhonov HEADERS("HTTP/1.1 302 Found\r\n\r\n"), 33750aadb33SDmitri Tikhonov }, 33850aadb33SDmitri Tikhonov }, 33950aadb33SDmitri Tikhonov }, 34050aadb33SDmitri Tikhonov }, 34150aadb33SDmitri Tikhonov 34250aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 34350aadb33SDmitri Tikhonov .frt_fr_flags = 0, 34450aadb33SDmitri Tikhonov .frt_buf = { 34550aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x16, 34650aadb33SDmitri Tikhonov /* Type: */ 0x01, 34750aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS|HFHF_PADDED, 34850aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 34950aadb33SDmitri Tikhonov /* Padding length */0x11, 35050aadb33SDmitri Tikhonov /* Block fragment: */ 35150aadb33SDmitri Tikhonov 0x48, 0x82, 0x64, 0x02, 35250aadb33SDmitri Tikhonov /* Padding: */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 35350aadb33SDmitri Tikhonov 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 35450aadb33SDmitri Tikhonov 0xFF, 35550aadb33SDmitri Tikhonov }, 35650aadb33SDmitri Tikhonov .frt_bufsz = 9 + 1 + 4 + 17, 35750aadb33SDmitri Tikhonov .frt_n_cb_vals = 1, 35850aadb33SDmitri Tikhonov .frt_cb_vals = { 35950aadb33SDmitri Tikhonov { 36050aadb33SDmitri Tikhonov .type = CV_HEADERS, 3613b55e6aeSDmitri Tikhonov .u.headers = { 3623b55e6aeSDmitri Tikhonov .stream_id = 12345, 3633b55e6aeSDmitri Tikhonov .oth_stream_id = 0, 3643b55e6aeSDmitri Tikhonov .weight = 0, 3653b55e6aeSDmitri Tikhonov .exclusive = -1, 3663b55e6aeSDmitri Tikhonov .off = 0, 3673b55e6aeSDmitri Tikhonov .flags = UH_H1H, 3683b55e6aeSDmitri Tikhonov HEADERS("HTTP/1.1 302 Found\r\n\r\n"), 36950aadb33SDmitri Tikhonov }, 37050aadb33SDmitri Tikhonov }, 37150aadb33SDmitri Tikhonov }, 37250aadb33SDmitri Tikhonov }, 37350aadb33SDmitri Tikhonov 37450aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 37550aadb33SDmitri Tikhonov .frt_fr_flags = 0, 37650aadb33SDmitri Tikhonov .frt_buf = { 37750aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x1B, 37850aadb33SDmitri Tikhonov /* Type: */ 0x01, 37950aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS|HFHF_PADDED|HFHF_PRIORITY| 38050aadb33SDmitri Tikhonov HFHF_END_STREAM, 38150aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 38250aadb33SDmitri Tikhonov /* Padding length */0x11, 38350aadb33SDmitri Tikhonov /* Exclusive: */ 0x80| 38450aadb33SDmitri Tikhonov /* Dep Stream Id: */ 38550aadb33SDmitri Tikhonov 0x00, 0x00, 0x12, 0x34, 38650aadb33SDmitri Tikhonov /* Weight: */ 0xFF, 38750aadb33SDmitri Tikhonov /* Block fragment: */ 38850aadb33SDmitri Tikhonov 0x48, 0x82, 0x64, 0x02, 38950aadb33SDmitri Tikhonov /* Padding: */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 39050aadb33SDmitri Tikhonov 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 39150aadb33SDmitri Tikhonov 0xFF, 39250aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x05, 39350aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_PRIORITY, 39450aadb33SDmitri Tikhonov /* Flags: */ 0x00, 39550aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x00, 0x39, 39650aadb33SDmitri Tikhonov /* Dep Stream Id: */0x80, 0x00, 0x00, 0x19, 39750aadb33SDmitri Tikhonov /* Weight: */ 0x77, 39850aadb33SDmitri Tikhonov }, 39950aadb33SDmitri Tikhonov .frt_bufsz = 9 + 1 + 5 + 4 + 17 40050aadb33SDmitri Tikhonov + 9 + 5, 40150aadb33SDmitri Tikhonov .frt_n_cb_vals = 2, 40250aadb33SDmitri Tikhonov .frt_cb_vals = { 40350aadb33SDmitri Tikhonov { 40450aadb33SDmitri Tikhonov .type = CV_HEADERS, 4053b55e6aeSDmitri Tikhonov .u.headers = { 4063b55e6aeSDmitri Tikhonov .stream_id = 12345, 4073b55e6aeSDmitri Tikhonov .oth_stream_id = 0x1234, 4083b55e6aeSDmitri Tikhonov .weight = 0xFF + 1, 4093b55e6aeSDmitri Tikhonov .exclusive = 1, 4103b55e6aeSDmitri Tikhonov .off = 0, 4113b55e6aeSDmitri Tikhonov .flags = UH_FIN | UH_H1H, 4123b55e6aeSDmitri Tikhonov HEADERS("HTTP/1.1 302 Found\r\n\r\n"), 41350aadb33SDmitri Tikhonov }, 41450aadb33SDmitri Tikhonov }, 41550aadb33SDmitri Tikhonov { 41650aadb33SDmitri Tikhonov .type = CV_PRIORITY, 41750aadb33SDmitri Tikhonov .u.priority = { 41850aadb33SDmitri Tikhonov .stream_id = 0x39, 41950aadb33SDmitri Tikhonov .exclusive = 1, 42050aadb33SDmitri Tikhonov .dep_stream_id = 0x19, 42150aadb33SDmitri Tikhonov .weight = 0x77 + 1, 42250aadb33SDmitri Tikhonov }, 42350aadb33SDmitri Tikhonov }, 42450aadb33SDmitri Tikhonov }, 42550aadb33SDmitri Tikhonov }, 42650aadb33SDmitri Tikhonov 42750aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 42850aadb33SDmitri Tikhonov .frt_fr_flags = 0, 42950aadb33SDmitri Tikhonov .frt_buf = { 43050aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x09, 43150aadb33SDmitri Tikhonov /* Type: */ 0x01, 43250aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS|HFHF_PRIORITY, 43350aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 43450aadb33SDmitri Tikhonov /* Exclusive: */ 0x00| 43550aadb33SDmitri Tikhonov /* Dep Stream Id: */ 43650aadb33SDmitri Tikhonov 0x00, 0x00, 0x12, 0x34, 43750aadb33SDmitri Tikhonov /* Weight: */ 0x00, 43850aadb33SDmitri Tikhonov /* Block fragment: */ 43950aadb33SDmitri Tikhonov 0x48, 0x82, 0x64, 0x02, 44050aadb33SDmitri Tikhonov }, 44150aadb33SDmitri Tikhonov .frt_bufsz = 9 + 5 + 4, 44250aadb33SDmitri Tikhonov .frt_n_cb_vals = 1, 44350aadb33SDmitri Tikhonov .frt_cb_vals = { 44450aadb33SDmitri Tikhonov { 44550aadb33SDmitri Tikhonov .type = CV_HEADERS, 4463b55e6aeSDmitri Tikhonov .u.headers = { 4473b55e6aeSDmitri Tikhonov .stream_id = 12345, 4483b55e6aeSDmitri Tikhonov .oth_stream_id = 0x1234, 4493b55e6aeSDmitri Tikhonov .weight = 1, 4503b55e6aeSDmitri Tikhonov .exclusive = 0, 4513b55e6aeSDmitri Tikhonov .off = 0, 4523b55e6aeSDmitri Tikhonov .flags = UH_H1H, 4533b55e6aeSDmitri Tikhonov HEADERS("HTTP/1.1 302 Found\r\n\r\n"), 45450aadb33SDmitri Tikhonov }, 45550aadb33SDmitri Tikhonov }, 45650aadb33SDmitri Tikhonov }, 45750aadb33SDmitri Tikhonov }, 45850aadb33SDmitri Tikhonov 45950aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 46050aadb33SDmitri Tikhonov .frt_fr_flags = 0, 46150aadb33SDmitri Tikhonov .frt_buf = { 46250aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x0E, 46350aadb33SDmitri Tikhonov /* Type: */ 0x01, 46450aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS|HFHF_PRIORITY, 46550aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 46650aadb33SDmitri Tikhonov /* Exclusive: */ 0x00| 46750aadb33SDmitri Tikhonov /* Dep Stream Id: */ 46850aadb33SDmitri Tikhonov 0x00, 0x00, 0x12, 0x34, 46950aadb33SDmitri Tikhonov /* Weight: */ 0x00, 47050aadb33SDmitri Tikhonov /* Block fragment: */ 47150aadb33SDmitri Tikhonov 0x48, 0x82, 0x64, 0x02, 47250aadb33SDmitri Tikhonov 0x60, 0x03, 0x61, 0x3d, 0x62, 47350aadb33SDmitri Tikhonov }, 47450aadb33SDmitri Tikhonov .frt_bufsz = 9 + 5 + 4 + 5, 47550aadb33SDmitri Tikhonov .frt_n_cb_vals = 1, 47650aadb33SDmitri Tikhonov .frt_cb_vals = { 47750aadb33SDmitri Tikhonov { 47850aadb33SDmitri Tikhonov .type = CV_HEADERS, 4793b55e6aeSDmitri Tikhonov .u.headers = { 4803b55e6aeSDmitri Tikhonov .stream_id = 12345, 4813b55e6aeSDmitri Tikhonov .oth_stream_id = 0x1234, 4823b55e6aeSDmitri Tikhonov .weight = 1, 4833b55e6aeSDmitri Tikhonov .exclusive = 0, 4843b55e6aeSDmitri Tikhonov .off = 0, 4853b55e6aeSDmitri Tikhonov .flags = UH_H1H, 4863b55e6aeSDmitri Tikhonov HEADERS("HTTP/1.1 302 Found\r\n" 48750aadb33SDmitri Tikhonov "Cookie: a=b\r\n\r\n"), 48850aadb33SDmitri Tikhonov }, 48950aadb33SDmitri Tikhonov }, 49050aadb33SDmitri Tikhonov }, 49150aadb33SDmitri Tikhonov }, 49250aadb33SDmitri Tikhonov 49350aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 49450aadb33SDmitri Tikhonov .frt_fr_flags = 0, 49550aadb33SDmitri Tikhonov .frt_buf = { 49650aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x18, 49750aadb33SDmitri Tikhonov /* Type: */ 0x01, 49850aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS|HFHF_PRIORITY, 49950aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 50050aadb33SDmitri Tikhonov /* Exclusive: */ 0x00| 50150aadb33SDmitri Tikhonov /* Dep Stream Id: */ 50250aadb33SDmitri Tikhonov 0x00, 0x00, 0x12, 0x34, 50350aadb33SDmitri Tikhonov /* Weight: */ 0x00, 50450aadb33SDmitri Tikhonov /* Block fragment: */ 50550aadb33SDmitri Tikhonov 0x48, 0x82, 0x64, 0x02, 50650aadb33SDmitri Tikhonov 0x60, 0x03, 0x61, 0x3d, 0x62, 50750aadb33SDmitri Tikhonov 0x60, 0x03, 0x63, 0x3d, 0x64, 50850aadb33SDmitri Tikhonov 0x60, 0x03, 0x65, 0x3d, 0x66, 50950aadb33SDmitri Tikhonov }, 51050aadb33SDmitri Tikhonov .frt_bufsz = 9 + 5 + 4 + 15, 51150aadb33SDmitri Tikhonov .frt_n_cb_vals = 1, 51250aadb33SDmitri Tikhonov .frt_cb_vals = { 51350aadb33SDmitri Tikhonov { 51450aadb33SDmitri Tikhonov .type = CV_HEADERS, 5153b55e6aeSDmitri Tikhonov .u.headers = { 5163b55e6aeSDmitri Tikhonov .stream_id = 12345, 5173b55e6aeSDmitri Tikhonov .oth_stream_id = 0x1234, 5183b55e6aeSDmitri Tikhonov .weight = 1, 5193b55e6aeSDmitri Tikhonov .exclusive = 0, 5203b55e6aeSDmitri Tikhonov .off = 0, 5213b55e6aeSDmitri Tikhonov .flags = UH_H1H, 5223b55e6aeSDmitri Tikhonov HEADERS("HTTP/1.1 302 Found\r\n" 52350aadb33SDmitri Tikhonov "Cookie: a=b; c=d; e=f\r\n\r\n"), 52450aadb33SDmitri Tikhonov }, 52550aadb33SDmitri Tikhonov }, 52650aadb33SDmitri Tikhonov }, 52750aadb33SDmitri Tikhonov }, 52850aadb33SDmitri Tikhonov 52950aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 53050aadb33SDmitri Tikhonov .frt_fr_flags = FRF_SERVER, 53150aadb33SDmitri Tikhonov .frt_buf = { 53250aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x16, 53350aadb33SDmitri Tikhonov /* Type: */ 0x01, 53450aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS|HFHF_PRIORITY, 53550aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 53650aadb33SDmitri Tikhonov /* Exclusive: */ 0x00| 53750aadb33SDmitri Tikhonov /* Dep Stream Id: */ 53850aadb33SDmitri Tikhonov 0x00, 0x00, 0x12, 0x34, 53950aadb33SDmitri Tikhonov /* Weight: */ 0x00, 54050aadb33SDmitri Tikhonov /* Block fragment: */ 54150aadb33SDmitri Tikhonov 0x82, 0x84, 0x86, 0x41, 0x8c, 0xf1, 0xe3, 0xc2, 54250aadb33SDmitri Tikhonov 0xe5, 0xf2, 0x3a, 0x6b, 0xa0, 0xab, 0x90, 0xf4, 54350aadb33SDmitri Tikhonov 0xff, 54450aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0xEE, 54550aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_CONTINUATION, 54650aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS, 54750aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 54850aadb33SDmitri Tikhonov /* Block fragment: */ 54950aadb33SDmitri Tikhonov 'W', 'H', 'A', 'T', 'E', 'V', 'E', 'R', 55050aadb33SDmitri Tikhonov }, 55150aadb33SDmitri Tikhonov .frt_bufsz = 9 + 5 + 17 55250aadb33SDmitri Tikhonov + 9 + 0 + 8, 55350aadb33SDmitri Tikhonov .frt_err = 1, 55450aadb33SDmitri Tikhonov .frt_in_off = 9 + 5 + 17 + 9, 55550aadb33SDmitri Tikhonov .frt_n_cb_vals = 1, 55650aadb33SDmitri Tikhonov .frt_cb_vals = { 55750aadb33SDmitri Tikhonov { 55850aadb33SDmitri Tikhonov .type = CV_HEADERS, 5593b55e6aeSDmitri Tikhonov .u.headers = { 5603b55e6aeSDmitri Tikhonov .stream_id = 12345, 5613b55e6aeSDmitri Tikhonov .oth_stream_id = 0x1234, 5623b55e6aeSDmitri Tikhonov .weight = 1, 5633b55e6aeSDmitri Tikhonov .exclusive = 0, 5643b55e6aeSDmitri Tikhonov .off = 0, 5653b55e6aeSDmitri Tikhonov .flags = UH_H1H, 5663b55e6aeSDmitri Tikhonov HEADERS("GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"), 56750aadb33SDmitri Tikhonov }, 56850aadb33SDmitri Tikhonov }, 56950aadb33SDmitri Tikhonov }, 57050aadb33SDmitri Tikhonov }, 57150aadb33SDmitri Tikhonov 57250aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 57350aadb33SDmitri Tikhonov .frt_fr_flags = FRF_SERVER, 57450aadb33SDmitri Tikhonov .frt_buf = { 57550aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x16, 57650aadb33SDmitri Tikhonov /* Type: */ 0x01, 57750aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS|HFHF_PRIORITY, 57850aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 57950aadb33SDmitri Tikhonov /* Exclusive: */ 0x00| 58050aadb33SDmitri Tikhonov /* Dep Stream Id: */ 58150aadb33SDmitri Tikhonov 0x00, 0x00, 0x12, 0x34, 58250aadb33SDmitri Tikhonov /* Weight: */ 0x00, 58350aadb33SDmitri Tikhonov /* Block fragment: */ 58450aadb33SDmitri Tikhonov 0x82, 0x84, 0x86, 0x41, 0x8c, 0xf1, 0xe3, 0xc2, 58550aadb33SDmitri Tikhonov 0xe5, 0xf2, 0x3a, 0x6b, 0xa0, 0xab, 0x90, 0xf4, 58650aadb33SDmitri Tikhonov 0xff, 58750aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0xEE, 58850aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_CONTINUATION, 58950aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS, 59050aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 59150aadb33SDmitri Tikhonov /* Block fragment: */ 59250aadb33SDmitri Tikhonov 'W', 'H', 'A', 'T', 'E', 'V', 'E', 'R', 59350aadb33SDmitri Tikhonov }, 59450aadb33SDmitri Tikhonov .frt_bufsz = 9 + 5 + 17 59550aadb33SDmitri Tikhonov + 9 + 0 + 8, 59650aadb33SDmitri Tikhonov .frt_err = 1, 59750aadb33SDmitri Tikhonov .frt_in_off = 9 + 5 + 17 + 9, 59850aadb33SDmitri Tikhonov .frt_n_cb_vals = 1, 59950aadb33SDmitri Tikhonov .frt_cb_vals = { 60050aadb33SDmitri Tikhonov { 60150aadb33SDmitri Tikhonov .type = CV_HEADERS, 6023b55e6aeSDmitri Tikhonov .u.headers = { 6033b55e6aeSDmitri Tikhonov .stream_id = 12345, 6043b55e6aeSDmitri Tikhonov .oth_stream_id = 0x1234, 6053b55e6aeSDmitri Tikhonov .weight = 1, 6063b55e6aeSDmitri Tikhonov .exclusive = 0, 6073b55e6aeSDmitri Tikhonov .off = 0, 6083b55e6aeSDmitri Tikhonov .flags = UH_H1H, 6093b55e6aeSDmitri Tikhonov HEADERS("GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"), 61050aadb33SDmitri Tikhonov }, 61150aadb33SDmitri Tikhonov }, 61250aadb33SDmitri Tikhonov }, 61350aadb33SDmitri Tikhonov }, 61450aadb33SDmitri Tikhonov 61550aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 61650aadb33SDmitri Tikhonov .frt_fr_flags = FRF_SERVER, 61750aadb33SDmitri Tikhonov .frt_buf = { 61850aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x16, 61950aadb33SDmitri Tikhonov /* Type: */ 0x01, 62050aadb33SDmitri Tikhonov /* Flags: */ HFHF_PRIORITY, 62150aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 62250aadb33SDmitri Tikhonov /* Exclusive: */ 0x00| 62350aadb33SDmitri Tikhonov /* Dep Stream Id: */ 62450aadb33SDmitri Tikhonov 0x00, 0x00, 0x12, 0x34, 62550aadb33SDmitri Tikhonov /* Weight: */ 0x00, 62650aadb33SDmitri Tikhonov /* Block fragment: */ 62750aadb33SDmitri Tikhonov 0x82, 0x84, 0x86, 0x41, 0x8c, 0xf1, 0xe3, 0xc2, 62850aadb33SDmitri Tikhonov 0xe5, 0xf2, 0x3a, 0x6b, 0xa0, 0xab, 0x90, 0xf4, 62950aadb33SDmitri Tikhonov 0xff, 63050aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0xEE, 63150aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_CONTINUATION, 63250aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS, 63350aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0xFF, 0x30, 0x39, /* Stream ID does not match */ 63450aadb33SDmitri Tikhonov /* Block fragment: */ 63550aadb33SDmitri Tikhonov 'W', 'H', 'A', 'T', 'E', 'V', 'E', 'R', 63650aadb33SDmitri Tikhonov }, 63750aadb33SDmitri Tikhonov .frt_bufsz = 9 + 5 + 17 63850aadb33SDmitri Tikhonov + 9 + 0 + 8, 63950aadb33SDmitri Tikhonov .frt_err = 1, 64050aadb33SDmitri Tikhonov .frt_in_off = 9 + 5 + 17 + 9, 64150aadb33SDmitri Tikhonov .frt_n_cb_vals = 0, 64250aadb33SDmitri Tikhonov }, 64350aadb33SDmitri Tikhonov 64450aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 64550aadb33SDmitri Tikhonov .frt_fr_flags = FRF_SERVER, 64650aadb33SDmitri Tikhonov .frt_buf = { 64750aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0xEE, 64850aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_CONTINUATION, 64950aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS, 65050aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 65150aadb33SDmitri Tikhonov /* Block fragment: */ 65250aadb33SDmitri Tikhonov 'W', 'H', 'A', 'T', 'E', 'V', 'E', 'R', 65350aadb33SDmitri Tikhonov }, 65450aadb33SDmitri Tikhonov .frt_bufsz = 9 + 0 + 8, 65550aadb33SDmitri Tikhonov .frt_err = 1, 65650aadb33SDmitri Tikhonov .frt_in_off = 9, 65750aadb33SDmitri Tikhonov .frt_n_cb_vals = 0, 65850aadb33SDmitri Tikhonov }, 65950aadb33SDmitri Tikhonov 66050aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 66150aadb33SDmitri Tikhonov .frt_fr_flags = FRF_SERVER, 66250aadb33SDmitri Tikhonov .frt_buf = { 66350aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x10, 66450aadb33SDmitri Tikhonov /* Type: */ 0x01, 66550aadb33SDmitri Tikhonov /* Flags: */ 0x00, /* Note absence of HFHF_END_HEADERS */ 66650aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 66750aadb33SDmitri Tikhonov /* Block fragment: 66850aadb33SDmitri Tikhonov * perl hpack.pl :method GET :path / host www.example.com 66950aadb33SDmitri Tikhonov */ 67050aadb33SDmitri Tikhonov 0x82, 0x84, 0x66, 0x8c, 0xf1, 0xe3, 0xc2, 0xe5, 67150aadb33SDmitri Tikhonov 0xf2, 0x3a, 0x6b, 0xa0, 0xab, 0x90, 0xf4, 0xff, 67250aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x08, 67350aadb33SDmitri Tikhonov /* Type: */ 0x01, 67450aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS, 67550aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 67650aadb33SDmitri Tikhonov /* Block fragment: */ 67750aadb33SDmitri Tikhonov 'W', 'H', 'A', 'T', 'E', 'V', 'E', 'R', 67850aadb33SDmitri Tikhonov }, 67950aadb33SDmitri Tikhonov .frt_bufsz = 9 + 0 + 16 68050aadb33SDmitri Tikhonov + 9 + 0 + 8, 68150aadb33SDmitri Tikhonov .frt_in_off = 9 + 16 + 9, 68250aadb33SDmitri Tikhonov .frt_err = 1, 68350aadb33SDmitri Tikhonov .frt_n_cb_vals = 1, 68450aadb33SDmitri Tikhonov .frt_cb_vals = { 68550aadb33SDmitri Tikhonov { 68650aadb33SDmitri Tikhonov .type = CV_ERROR, 68750aadb33SDmitri Tikhonov .u.error = { 68850aadb33SDmitri Tikhonov .stream_id = 0x3039, 68950aadb33SDmitri Tikhonov .code = FR_ERR_EXPECTED_CONTIN, 69050aadb33SDmitri Tikhonov }, 69150aadb33SDmitri Tikhonov }, 69250aadb33SDmitri Tikhonov }, 69350aadb33SDmitri Tikhonov }, 69450aadb33SDmitri Tikhonov 69550aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 69650aadb33SDmitri Tikhonov .frt_fr_flags = FRF_SERVER, 69750aadb33SDmitri Tikhonov .frt_buf = { 69850aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x10, 69950aadb33SDmitri Tikhonov /* Type: */ 0x01, 70050aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS, 70150aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 70250aadb33SDmitri Tikhonov /* Block fragment: 70350aadb33SDmitri Tikhonov * perl hpack.pl :method GET :path / host www.example.com 70450aadb33SDmitri Tikhonov */ 70550aadb33SDmitri Tikhonov 0x82, 0x84, 0x66, 0x8c, 0xf1, 0xe3, 0xc2, 0xe5, 70650aadb33SDmitri Tikhonov 0xf2, 0x3a, 0x6b, 0xa0, 0xab, 0x90, 0xf4, 0xff, 70750aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x1A, 70850aadb33SDmitri Tikhonov /* Type: */ 0x01, 70950aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS|HFHF_PRIORITY, 71050aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 71150aadb33SDmitri Tikhonov /* Exclusive: */ 0x00| 71250aadb33SDmitri Tikhonov /* Dep Stream Id: */ 71350aadb33SDmitri Tikhonov 0x00, 0x00, 0x12, 0x34, 71450aadb33SDmitri Tikhonov /* Weight: */ 0x00, 71550aadb33SDmitri Tikhonov /* Block fragment: 71650aadb33SDmitri Tikhonov * perl hpack.pl :method GET :path / :scheme http Host www.example.com 71750aadb33SDmitri Tikhonov */ 71850aadb33SDmitri Tikhonov 0x82, 0x84, 0x86, 0x40, 0x83, 0xc6, 0x74, 0x27, 71950aadb33SDmitri Tikhonov 0x8c, 0xf1, 0xe3, 0xc2, 0xe5, 0xf2, 0x3a, 0x6b, 72050aadb33SDmitri Tikhonov 0xa0, 0xab, 0x90, 0xf4, 0xff, 72150aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x11, 72250aadb33SDmitri Tikhonov /* Type: */ 0x01, 72350aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS, 72450aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 72550aadb33SDmitri Tikhonov /* Block fragment: */ 72650aadb33SDmitri Tikhonov 0x82, 0x84, 0x86, 0x41, 0x8c, 0xf1, 0xe3, 0xc2, 72750aadb33SDmitri Tikhonov 0xe5, 0xf2, 0x3a, 0x6b, 0xa0, 0xab, 0x90, 0xf4, 72850aadb33SDmitri Tikhonov 0xff, 72950aadb33SDmitri Tikhonov }, 73050aadb33SDmitri Tikhonov .frt_bufsz = 9 + 0 + 16 73150aadb33SDmitri Tikhonov + 9 + 5 + 21 73250aadb33SDmitri Tikhonov + 9 + 0 + 17, 73350aadb33SDmitri Tikhonov .frt_n_cb_vals = 3, 73450aadb33SDmitri Tikhonov .frt_cb_vals = { 73550aadb33SDmitri Tikhonov { 73650aadb33SDmitri Tikhonov .type = CV_ERROR, 73750aadb33SDmitri Tikhonov .u.error = { 73850aadb33SDmitri Tikhonov .stream_id = 12345, 739a5fa05f9SDmitri Tikhonov .code = FR_ERR_BAD_HEADER, 74050aadb33SDmitri Tikhonov }, 74150aadb33SDmitri Tikhonov }, 74250aadb33SDmitri Tikhonov { 74350aadb33SDmitri Tikhonov .type = CV_ERROR, 74450aadb33SDmitri Tikhonov .u.error = { 74550aadb33SDmitri Tikhonov .stream_id = 12345, 746a5fa05f9SDmitri Tikhonov .code = FR_ERR_BAD_HEADER, 74750aadb33SDmitri Tikhonov }, 74850aadb33SDmitri Tikhonov }, 74950aadb33SDmitri Tikhonov { 75050aadb33SDmitri Tikhonov .type = CV_HEADERS, 7513b55e6aeSDmitri Tikhonov .u.headers = { 7523b55e6aeSDmitri Tikhonov .stream_id = 12345, 7533b55e6aeSDmitri Tikhonov .oth_stream_id = 0, 7543b55e6aeSDmitri Tikhonov .weight = 0, 7553b55e6aeSDmitri Tikhonov .exclusive = -1, 7563b55e6aeSDmitri Tikhonov .off = 0, 7573b55e6aeSDmitri Tikhonov .flags = UH_H1H, 7583b55e6aeSDmitri Tikhonov HEADERS("GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"), 75950aadb33SDmitri Tikhonov }, 76050aadb33SDmitri Tikhonov }, 76150aadb33SDmitri Tikhonov }, 76250aadb33SDmitri Tikhonov }, 76350aadb33SDmitri Tikhonov 76450aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 76550aadb33SDmitri Tikhonov .frt_fr_flags = 0, 76650aadb33SDmitri Tikhonov .frt_buf = { 76750aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x15, 76850aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_PUSH_PROMISE, 76950aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS, 77050aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 77150aadb33SDmitri Tikhonov /* Dep stream Id: */0x00, 0x12, 0x34, 0x56, 77250aadb33SDmitri Tikhonov /* Block fragment: */ 77350aadb33SDmitri Tikhonov 0x82, 0x84, 0x86, 0x41, 0x8c, 0xf1, 0xe3, 0xc2, 77450aadb33SDmitri Tikhonov 0xe5, 0xf2, 0x3a, 0x6b, 0xa0, 0xab, 0x90, 0xf4, 77550aadb33SDmitri Tikhonov 0xff, 77650aadb33SDmitri Tikhonov }, 77750aadb33SDmitri Tikhonov .frt_bufsz = 9 + 0 + 0x15, 77850aadb33SDmitri Tikhonov .frt_n_cb_vals = 1, 77950aadb33SDmitri Tikhonov .frt_cb_vals = { 78050aadb33SDmitri Tikhonov { 78150aadb33SDmitri Tikhonov .type = CV_PUSH_PROMISE, 7823b55e6aeSDmitri Tikhonov .u.headers = { 7833b55e6aeSDmitri Tikhonov .stream_id = 12345, 7843b55e6aeSDmitri Tikhonov .oth_stream_id = 0x123456, 7853b55e6aeSDmitri Tikhonov .flags = UH_PP | UH_H1H, 7863b55e6aeSDmitri Tikhonov HEADERS("GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n"), 78750aadb33SDmitri Tikhonov }, 78850aadb33SDmitri Tikhonov }, 78950aadb33SDmitri Tikhonov }, 79050aadb33SDmitri Tikhonov }, 79150aadb33SDmitri Tikhonov 79250aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 79350aadb33SDmitri Tikhonov .frt_fr_flags = 0, 79450aadb33SDmitri Tikhonov .frt_buf = { 79550aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x02, 79650aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_HEADERS, 79750aadb33SDmitri Tikhonov /* Flags: */ 0x00, 79850aadb33SDmitri Tikhonov 0x80| /* <----- This bit must be ignored */ 79950aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 80050aadb33SDmitri Tikhonov /* Block fragment: */ 80150aadb33SDmitri Tikhonov 0x48, 0x82, 80250aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x02, 80350aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_CONTINUATION, 80450aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS, 80550aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 80650aadb33SDmitri Tikhonov /* Block fragment: */ 80750aadb33SDmitri Tikhonov 0x64, 0x02, 80850aadb33SDmitri Tikhonov }, 80950aadb33SDmitri Tikhonov .frt_bufsz = 9 + 2 + 9 + 2, 81050aadb33SDmitri Tikhonov .frt_n_cb_vals = 1, 81150aadb33SDmitri Tikhonov .frt_cb_vals = { 81250aadb33SDmitri Tikhonov { 81350aadb33SDmitri Tikhonov .type = CV_HEADERS, 8143b55e6aeSDmitri Tikhonov .u.headers = { 8153b55e6aeSDmitri Tikhonov .stream_id = 12345, 8163b55e6aeSDmitri Tikhonov .oth_stream_id = 0, 8173b55e6aeSDmitri Tikhonov .weight = 0, 8183b55e6aeSDmitri Tikhonov .exclusive = -1, 8193b55e6aeSDmitri Tikhonov .off = 0, 8203b55e6aeSDmitri Tikhonov .flags = UH_H1H, 8213b55e6aeSDmitri Tikhonov HEADERS("HTTP/1.1 302 Found\r\n\r\n"), 82250aadb33SDmitri Tikhonov }, 82350aadb33SDmitri Tikhonov }, 82450aadb33SDmitri Tikhonov }, 82550aadb33SDmitri Tikhonov }, 82650aadb33SDmitri Tikhonov 82750aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 82850aadb33SDmitri Tikhonov .frt_fr_flags = 0, 82950aadb33SDmitri Tikhonov .frt_buf = { 83050aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x00, 83150aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_SETTINGS, 83250aadb33SDmitri Tikhonov /* Flags: */ 0x00, 83350aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 83450aadb33SDmitri Tikhonov }, 83550aadb33SDmitri Tikhonov .frt_bufsz = 9, 83650aadb33SDmitri Tikhonov .frt_n_cb_vals = 1, 83750aadb33SDmitri Tikhonov .frt_err = 1, 83850aadb33SDmitri Tikhonov .frt_cb_vals = { 83950aadb33SDmitri Tikhonov { 84050aadb33SDmitri Tikhonov .type = CV_ERROR, 84150aadb33SDmitri Tikhonov .u.error.code = FR_ERR_INVALID_FRAME_SIZE, 84250aadb33SDmitri Tikhonov .u.error.stream_id = 12345, 84350aadb33SDmitri Tikhonov }, 84450aadb33SDmitri Tikhonov }, 84550aadb33SDmitri Tikhonov }, 84650aadb33SDmitri Tikhonov 84750aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 84850aadb33SDmitri Tikhonov .frt_fr_flags = 0, 84950aadb33SDmitri Tikhonov .frt_buf = { 85050aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x07, 85150aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_SETTINGS, 85250aadb33SDmitri Tikhonov /* Flags: */ 0x00, 85350aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 85450aadb33SDmitri Tikhonov 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 85550aadb33SDmitri Tikhonov }, 85650aadb33SDmitri Tikhonov .frt_bufsz = 9 + 7, 85750aadb33SDmitri Tikhonov .frt_n_cb_vals = 1, 85850aadb33SDmitri Tikhonov .frt_err = 1, 85950aadb33SDmitri Tikhonov .frt_in_off = 9, 86050aadb33SDmitri Tikhonov .frt_cb_vals = { 86150aadb33SDmitri Tikhonov { 86250aadb33SDmitri Tikhonov .type = CV_ERROR, 86350aadb33SDmitri Tikhonov .u.error.code = FR_ERR_INVALID_FRAME_SIZE, 86450aadb33SDmitri Tikhonov .u.error.stream_id = 12345, 86550aadb33SDmitri Tikhonov }, 86650aadb33SDmitri Tikhonov }, 86750aadb33SDmitri Tikhonov }, 86850aadb33SDmitri Tikhonov 86950aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 87050aadb33SDmitri Tikhonov .frt_fr_flags = 0, 87150aadb33SDmitri Tikhonov .frt_buf = { 87250aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x06, 87350aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_SETTINGS, 87450aadb33SDmitri Tikhonov /* Flags: */ 0x00, 87550aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 87650aadb33SDmitri Tikhonov 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 87750aadb33SDmitri Tikhonov }, 87850aadb33SDmitri Tikhonov .frt_bufsz = 9 + 6, 87950aadb33SDmitri Tikhonov .frt_n_cb_vals = 1, 88050aadb33SDmitri Tikhonov .frt_err = 1, 88150aadb33SDmitri Tikhonov .frt_in_off = 9, 88250aadb33SDmitri Tikhonov .frt_cb_vals = { 88350aadb33SDmitri Tikhonov { 88450aadb33SDmitri Tikhonov .type = CV_ERROR, 88550aadb33SDmitri Tikhonov .u.error.code = FR_ERR_NONZERO_STREAM_ID, 88650aadb33SDmitri Tikhonov .u.error.stream_id = 12345, 88750aadb33SDmitri Tikhonov }, 88850aadb33SDmitri Tikhonov }, 88950aadb33SDmitri Tikhonov }, 89050aadb33SDmitri Tikhonov 89150aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 89250aadb33SDmitri Tikhonov .frt_fr_flags = 0, 89350aadb33SDmitri Tikhonov .frt_buf = { 89450aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x0C, 89550aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_SETTINGS, 89650aadb33SDmitri Tikhonov /* Flags: */ 0x00, 89750aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x00, 0x00, 89850aadb33SDmitri Tikhonov 0x00, SETTINGS_INITIAL_WINDOW_SIZE, 89950aadb33SDmitri Tikhonov 0x01, 0x02, 0x03, 0x04, 90050aadb33SDmitri Tikhonov 0x00, SETTINGS_HEADER_TABLE_SIZE, 90150aadb33SDmitri Tikhonov 0x02, 0x03, 0x04, 0x05, 90250aadb33SDmitri Tikhonov }, 90350aadb33SDmitri Tikhonov .frt_bufsz = 9 + 12, 90450aadb33SDmitri Tikhonov .frt_n_cb_vals = 2, 90550aadb33SDmitri Tikhonov .frt_cb_vals = { 90650aadb33SDmitri Tikhonov { 90750aadb33SDmitri Tikhonov .type = CV_SETTINGS, 90850aadb33SDmitri Tikhonov .u.setting.id = SETTINGS_INITIAL_WINDOW_SIZE, 90950aadb33SDmitri Tikhonov .u.setting.value = 0x01020304, 91050aadb33SDmitri Tikhonov }, 91150aadb33SDmitri Tikhonov { 91250aadb33SDmitri Tikhonov .type = CV_SETTINGS, 91350aadb33SDmitri Tikhonov .u.setting.id = SETTINGS_HEADER_TABLE_SIZE, 91450aadb33SDmitri Tikhonov .u.setting.value = 0x02030405, 91550aadb33SDmitri Tikhonov }, 91650aadb33SDmitri Tikhonov }, 91750aadb33SDmitri Tikhonov }, 91850aadb33SDmitri Tikhonov 91950aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 92050aadb33SDmitri Tikhonov .frt_fr_flags = 0, 92150aadb33SDmitri Tikhonov .frt_buf = { 92250aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x09, 92350aadb33SDmitri Tikhonov /* Type: */ 0x01, 92450aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS|HFHF_PRIORITY, 92550aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 92650aadb33SDmitri Tikhonov /* Exclusive: */ 0x00| 92750aadb33SDmitri Tikhonov /* Dep Stream Id: */ 92850aadb33SDmitri Tikhonov 0x00, 0x00, 0x12, 0x34, 92950aadb33SDmitri Tikhonov /* Weight: */ 0x00, 93050aadb33SDmitri Tikhonov /* Block fragment: */ 93150aadb33SDmitri Tikhonov 0x48, 0x82, 0x64, 0x02, 93250aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x06, 93350aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_SETTINGS, 93450aadb33SDmitri Tikhonov /* Flags: */ 0x00, 93550aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x00, 0x00, 93650aadb33SDmitri Tikhonov 0x00, SETTINGS_INITIAL_WINDOW_SIZE, 93750aadb33SDmitri Tikhonov 0x01, 0x02, 0x03, 0x04, 93850aadb33SDmitri Tikhonov }, 93950aadb33SDmitri Tikhonov .frt_bufsz = 9 + 5 + 4 + 9 + 6, 94050aadb33SDmitri Tikhonov .frt_max_headers_sz = 10, 94150aadb33SDmitri Tikhonov .frt_n_cb_vals = 2, 94250aadb33SDmitri Tikhonov .frt_cb_vals = { 94350aadb33SDmitri Tikhonov { 94450aadb33SDmitri Tikhonov .type = CV_ERROR, 94550aadb33SDmitri Tikhonov .stream_off = 9 + 5 + 4, 946a5fa05f9SDmitri Tikhonov .u.error.code = FR_ERR_BAD_HEADER, 94750aadb33SDmitri Tikhonov .u.error.stream_id = 12345, 94850aadb33SDmitri Tikhonov }, 94950aadb33SDmitri Tikhonov { 95050aadb33SDmitri Tikhonov .type = CV_SETTINGS, 95150aadb33SDmitri Tikhonov .u.setting.id = SETTINGS_INITIAL_WINDOW_SIZE, 95250aadb33SDmitri Tikhonov .u.setting.value = 0x01020304, 95350aadb33SDmitri Tikhonov }, 95450aadb33SDmitri Tikhonov }, 95550aadb33SDmitri Tikhonov }, 95650aadb33SDmitri Tikhonov 95750aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 95850aadb33SDmitri Tikhonov .frt_fr_flags = 0, 95950aadb33SDmitri Tikhonov .frt_buf = { 96050aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x11, 96150aadb33SDmitri Tikhonov /* Type: */ 0x01, 96250aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS, 96350aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 96450aadb33SDmitri Tikhonov /* Block fragment: */ 96550aadb33SDmitri Tikhonov /* 0x11 bytes of no consequence: they are not 96650aadb33SDmitri Tikhonov * parsed. 96750aadb33SDmitri Tikhonov */ 96850aadb33SDmitri Tikhonov 000, 001, 002, 003, 004, 005, 006, 007, 96950aadb33SDmitri Tikhonov 010, 011, 012, 013, 014, 015, 016, 017, 97050aadb33SDmitri Tikhonov 020, 97150aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x06, 97250aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_SETTINGS, 97350aadb33SDmitri Tikhonov /* Flags: */ 0x00, 97450aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x00, 0x00, 97550aadb33SDmitri Tikhonov 0x00, SETTINGS_INITIAL_WINDOW_SIZE, 97650aadb33SDmitri Tikhonov 0x01, 0x02, 0x03, 0x04, 97750aadb33SDmitri Tikhonov }, 97850aadb33SDmitri Tikhonov .frt_bufsz = 9 + 0 + 0x11 + 9 + 6, 97950aadb33SDmitri Tikhonov .frt_max_headers_sz = 0x10, 98050aadb33SDmitri Tikhonov .frt_n_cb_vals = 2, 98150aadb33SDmitri Tikhonov .frt_cb_vals = { 98250aadb33SDmitri Tikhonov { 98350aadb33SDmitri Tikhonov .type = CV_ERROR, 98450aadb33SDmitri Tikhonov .stream_off = 9, 985a5fa05f9SDmitri Tikhonov .u.error.code = FR_ERR_BAD_HEADER, 98650aadb33SDmitri Tikhonov .u.error.stream_id = 12345, 98750aadb33SDmitri Tikhonov }, 98850aadb33SDmitri Tikhonov { 98950aadb33SDmitri Tikhonov .type = CV_SETTINGS, 99050aadb33SDmitri Tikhonov .u.setting.id = SETTINGS_INITIAL_WINDOW_SIZE, 99150aadb33SDmitri Tikhonov .u.setting.value = 0x01020304, 99250aadb33SDmitri Tikhonov }, 99350aadb33SDmitri Tikhonov }, 99450aadb33SDmitri Tikhonov }, 99550aadb33SDmitri Tikhonov 99650aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 99750aadb33SDmitri Tikhonov .frt_fr_flags = 0, 99850aadb33SDmitri Tikhonov .frt_buf = { 99950aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x10, 100050aadb33SDmitri Tikhonov /* Type: */ 0x01, 100150aadb33SDmitri Tikhonov /* Flags: */ 0x00, 100250aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 100350aadb33SDmitri Tikhonov /* Block fragment: */ 100450aadb33SDmitri Tikhonov /* 0x10 bytes of no consequence: they are not 100550aadb33SDmitri Tikhonov * parsed. 100650aadb33SDmitri Tikhonov */ 100750aadb33SDmitri Tikhonov 000, 001, 002, 003, 004, 005, 006, 007, 100850aadb33SDmitri Tikhonov 010, 011, 012, 013, 014, 015, 016, 017, 100950aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x10, 101050aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_CONTINUATION, 101150aadb33SDmitri Tikhonov /* Flags: */ 0x00, 101250aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 101350aadb33SDmitri Tikhonov /* Block fragment: */ 101450aadb33SDmitri Tikhonov 000, 001, 002, 003, 004, 005, 006, 007, 101550aadb33SDmitri Tikhonov 010, 011, 012, 013, 014, 015, 016, 017, 101650aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x10, 101750aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_CONTINUATION, 101850aadb33SDmitri Tikhonov /* Flags: */ HFHF_END_HEADERS, 101950aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x30, 0x39, 102050aadb33SDmitri Tikhonov /* Block fragment: */ 102150aadb33SDmitri Tikhonov 000, 001, 002, 003, 004, 005, 006, 007, 102250aadb33SDmitri Tikhonov 010, 011, 012, 013, 014, 015, 016, 017, 102350aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x06, 102450aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_SETTINGS, 102550aadb33SDmitri Tikhonov /* Flags: */ 0x00, 102650aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x00, 0x00, 102750aadb33SDmitri Tikhonov 0x00, SETTINGS_INITIAL_WINDOW_SIZE, 102850aadb33SDmitri Tikhonov 0x01, 0x02, 0x03, 0x04, 102950aadb33SDmitri Tikhonov }, 103050aadb33SDmitri Tikhonov .frt_bufsz = 9 + 0 + 0x10 + 9 + 0 + 0x10 + 9 + 0 + 0x10 + 9 + 6, 103150aadb33SDmitri Tikhonov .frt_max_headers_sz = 0x19, 103250aadb33SDmitri Tikhonov .frt_n_cb_vals = 2, 103350aadb33SDmitri Tikhonov .frt_cb_vals = { 103450aadb33SDmitri Tikhonov { 103550aadb33SDmitri Tikhonov .type = CV_ERROR, 103650aadb33SDmitri Tikhonov .stream_off = 9 + 0 + 0x10 + 9, 1037a5fa05f9SDmitri Tikhonov .u.error.code = FR_ERR_BAD_HEADER, 103850aadb33SDmitri Tikhonov .u.error.stream_id = 12345, 103950aadb33SDmitri Tikhonov }, 104050aadb33SDmitri Tikhonov { 104150aadb33SDmitri Tikhonov .type = CV_SETTINGS, 104250aadb33SDmitri Tikhonov .u.setting.id = SETTINGS_INITIAL_WINDOW_SIZE, 104350aadb33SDmitri Tikhonov .u.setting.value = 0x01020304, 104450aadb33SDmitri Tikhonov }, 104550aadb33SDmitri Tikhonov }, 104650aadb33SDmitri Tikhonov }, 104750aadb33SDmitri Tikhonov 104850aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 104950aadb33SDmitri Tikhonov .frt_fr_flags = 0, 105050aadb33SDmitri Tikhonov .frt_buf = { 105150aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 105250aadb33SDmitri Tikhonov 0x04, /* <-- wrong payload size */ 105350aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_PRIORITY, 105450aadb33SDmitri Tikhonov /* Flags: */ 0x00, 105550aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x00, 0x39, 105650aadb33SDmitri Tikhonov /* Dep Stream Id: */0x80, 0x00, 0x00, 0x19, 105750aadb33SDmitri Tikhonov /* Weight: */ 0x77, 105850aadb33SDmitri Tikhonov }, 105950aadb33SDmitri Tikhonov .frt_bufsz = 9 + 5, 106050aadb33SDmitri Tikhonov .frt_n_cb_vals = 1, 106150aadb33SDmitri Tikhonov .frt_err = 1, 106250aadb33SDmitri Tikhonov .frt_in_off = 9, 106350aadb33SDmitri Tikhonov .frt_cb_vals = { 106450aadb33SDmitri Tikhonov { 106550aadb33SDmitri Tikhonov .type = CV_ERROR, 106650aadb33SDmitri Tikhonov .stream_off = 9, 106750aadb33SDmitri Tikhonov .u.error.code = FR_ERR_INVALID_FRAME_SIZE, 106850aadb33SDmitri Tikhonov .u.error.stream_id = 0x39, 106950aadb33SDmitri Tikhonov } 107050aadb33SDmitri Tikhonov }, 107150aadb33SDmitri Tikhonov }, 107250aadb33SDmitri Tikhonov 107350aadb33SDmitri Tikhonov { .frt_lineno = __LINE__, 107450aadb33SDmitri Tikhonov .frt_fr_flags = 0, 107550aadb33SDmitri Tikhonov .frt_buf = { 107650aadb33SDmitri Tikhonov /* Length: */ 0x00, 0x00, 0x05, 107750aadb33SDmitri Tikhonov /* Type: */ HTTP_FRAME_PRIORITY, 107850aadb33SDmitri Tikhonov /* Flags: */ 0x00, 107950aadb33SDmitri Tikhonov /* Stream Id: */ 0x00, 0x00, 0x00, 0x00, /* Invalid stream ID */ 108050aadb33SDmitri Tikhonov /* Dep Stream Id: */0x80, 0x00, 0x00, 0x19, 108150aadb33SDmitri Tikhonov /* Weight: */ 0x77, 108250aadb33SDmitri Tikhonov }, 108350aadb33SDmitri Tikhonov .frt_bufsz = 9 + 5, 108450aadb33SDmitri Tikhonov .frt_n_cb_vals = 1, 108550aadb33SDmitri Tikhonov .frt_err = 1, 108650aadb33SDmitri Tikhonov .frt_in_off = 9, 108750aadb33SDmitri Tikhonov .frt_cb_vals = { 108850aadb33SDmitri Tikhonov { 108950aadb33SDmitri Tikhonov .type = CV_ERROR, 109050aadb33SDmitri Tikhonov .stream_off = 9, 109150aadb33SDmitri Tikhonov .u.error.code = FR_ERR_ZERO_STREAM_ID, 109250aadb33SDmitri Tikhonov .u.error.stream_id = 0x00, 109350aadb33SDmitri Tikhonov } 109450aadb33SDmitri Tikhonov }, 109550aadb33SDmitri Tikhonov }, 109650aadb33SDmitri Tikhonov 109750aadb33SDmitri Tikhonov { 109850aadb33SDmitri Tikhonov .frt_bufsz = 0, 109950aadb33SDmitri Tikhonov }, 110050aadb33SDmitri Tikhonov}; 110150aadb33SDmitri Tikhonov 110250aadb33SDmitri Tikhonov 110372585dc9SDmitri Tikhonovstatic struct lsquic_stream * 110472585dc9SDmitri Tikhonovmy_get_stream_by_id (struct lsquic_conn *conn, lsquic_stream_id_t stream_id) 110572585dc9SDmitri Tikhonov{ 110672585dc9SDmitri Tikhonov return (void *) my_get_stream_by_id; 110772585dc9SDmitri Tikhonov} 110872585dc9SDmitri Tikhonov 110972585dc9SDmitri Tikhonov 111050aadb33SDmitri Tikhonovstatic void 111150aadb33SDmitri Tikhonovtest_one_frt (const struct frame_reader_test *frt) 111250aadb33SDmitri Tikhonov{ 111350aadb33SDmitri Tikhonov struct lsquic_frame_reader *fr; 111450aadb33SDmitri Tikhonov unsigned short exp_off; 1115bea64822SDmitri Tikhonov struct lshpack_dec hdec; 111650aadb33SDmitri Tikhonov struct lsquic_mm mm; 11173b55e6aeSDmitri Tikhonov struct lsquic_conn lconn; 11183b55e6aeSDmitri Tikhonov struct lsquic_conn_public conn_pub; 11193b55e6aeSDmitri Tikhonov struct lsquic_stream stream; 112050aadb33SDmitri Tikhonov int s; 112108c45823SDmitri Tikhonov struct conn_iface my_conn_if; 112250aadb33SDmitri Tikhonov 112319f667fbSDmitri Tikhonov#if LSQUIC_CONN_STATS 112419f667fbSDmitri Tikhonov struct conn_stats conn_stats; 112519f667fbSDmitri Tikhonov memset(&conn_stats, 0, sizeof(conn_stats)); 112619f667fbSDmitri Tikhonov#endif 112719f667fbSDmitri Tikhonov 11283b55e6aeSDmitri Tikhonov memset(&stream, 0, sizeof(stream)); 11293b55e6aeSDmitri Tikhonov memset(&lconn, 0, sizeof(lconn)); 11303b55e6aeSDmitri Tikhonov memset(&conn_pub, 0, sizeof(conn_pub)); 113108c45823SDmitri Tikhonov memset(&my_conn_if, 0, sizeof(my_conn_if)); 113272585dc9SDmitri Tikhonov my_conn_if.ci_get_stream_by_id = my_get_stream_by_id; 113308c45823SDmitri Tikhonov lconn.cn_if = &my_conn_if; 11343b55e6aeSDmitri Tikhonov stream.conn_pub = &conn_pub; 11353b55e6aeSDmitri Tikhonov conn_pub.lconn = &lconn; 11363b55e6aeSDmitri Tikhonov 113772585dc9SDmitri Tikhonov top: 113850aadb33SDmitri Tikhonov lsquic_mm_init(&mm); 1139fb3e20e0SDmitri Tikhonov lshpack_dec_init(&hdec); 114050aadb33SDmitri Tikhonov memset(&input, 0, sizeof(input)); 114150aadb33SDmitri Tikhonov memcpy(input.in_buf, frt->frt_buf, frt->frt_bufsz); 114250aadb33SDmitri Tikhonov input.in_sz = frt->frt_bufsz; 114350aadb33SDmitri Tikhonov 114450aadb33SDmitri Tikhonov do 114550aadb33SDmitri Tikhonov { 114650aadb33SDmitri Tikhonov reset_cb_ctx(&g_cb_ctx); 114750aadb33SDmitri Tikhonov input.in_off = 0; 114850aadb33SDmitri Tikhonov ++input.in_max_sz; 114950aadb33SDmitri Tikhonov 115050aadb33SDmitri Tikhonov fr = lsquic_frame_reader_new(frt->frt_fr_flags, frt->frt_max_headers_sz, 11513b55e6aeSDmitri Tikhonov &mm, &stream, read_from_stream, &hdec, &frame_callbacks, &g_cb_ctx, 115219f667fbSDmitri Tikhonov#if LSQUIC_CONN_STATS 115319f667fbSDmitri Tikhonov &conn_stats, 115419f667fbSDmitri Tikhonov#endif 11553b55e6aeSDmitri Tikhonov lsquic_http1x_if, NULL); 115650aadb33SDmitri Tikhonov do 115750aadb33SDmitri Tikhonov { 115850aadb33SDmitri Tikhonov s = lsquic_frame_reader_read(fr); 115950aadb33SDmitri Tikhonov if (s != 0) 116050aadb33SDmitri Tikhonov break; 116150aadb33SDmitri Tikhonov } 116250aadb33SDmitri Tikhonov while (input.in_off < input.in_sz); 116350aadb33SDmitri Tikhonov 116450aadb33SDmitri Tikhonov assert(frt->frt_err || 0 == s); 116550aadb33SDmitri Tikhonov 116672585dc9SDmitri Tikhonov if (my_conn_if.ci_get_stream_by_id) 116772585dc9SDmitri Tikhonov { 116872585dc9SDmitri Tikhonov assert(g_cb_ctx.n_cb_vals == frt->frt_n_cb_vals); 116950aadb33SDmitri Tikhonov 117072585dc9SDmitri Tikhonov unsigned i; 117172585dc9SDmitri Tikhonov for (i = 0; i < g_cb_ctx.n_cb_vals; ++i) 117272585dc9SDmitri Tikhonov compare_cb_vals(&g_cb_ctx.cb_vals[i], &frt->frt_cb_vals[i]); 117372585dc9SDmitri Tikhonov } 117450aadb33SDmitri Tikhonov 117550aadb33SDmitri Tikhonov exp_off = frt->frt_in_off; 117650aadb33SDmitri Tikhonov if (!exp_off) 117750aadb33SDmitri Tikhonov exp_off = frt->frt_bufsz; 117850aadb33SDmitri Tikhonov assert(input.in_off == exp_off); 117950aadb33SDmitri Tikhonov 118050aadb33SDmitri Tikhonov lsquic_frame_reader_destroy(fr); 118150aadb33SDmitri Tikhonov } 118250aadb33SDmitri Tikhonov while (input.in_max_sz < input.in_max_req_sz); 1183bea64822SDmitri Tikhonov lshpack_dec_cleanup(&hdec); 118472585dc9SDmitri Tikhonov 118572585dc9SDmitri Tikhonov if (!(frt->frt_fr_flags & FRF_SERVER) && my_conn_if.ci_get_stream_by_id) 118672585dc9SDmitri Tikhonov { 118772585dc9SDmitri Tikhonov /* Do it again, but this time test header block skip logic */ 118872585dc9SDmitri Tikhonov my_conn_if.ci_get_stream_by_id = NULL; 118972585dc9SDmitri Tikhonov goto top; 119072585dc9SDmitri Tikhonov } 119172585dc9SDmitri Tikhonov 119250aadb33SDmitri Tikhonov lsquic_mm_cleanup(&mm); 119350aadb33SDmitri Tikhonov} 119450aadb33SDmitri Tikhonov 119550aadb33SDmitri Tikhonov 119650aadb33SDmitri Tikhonovint 119750aadb33SDmitri Tikhonovmain (int argc, char **argv) 119850aadb33SDmitri Tikhonov{ 119950aadb33SDmitri Tikhonov int opt; 120050aadb33SDmitri Tikhonov 120150aadb33SDmitri Tikhonov while (-1 != (opt = getopt(argc, argv, "l:"))) 120250aadb33SDmitri Tikhonov { 120350aadb33SDmitri Tikhonov switch (opt) 120450aadb33SDmitri Tikhonov { 120550aadb33SDmitri Tikhonov case 'l': 120650aadb33SDmitri Tikhonov lsquic_log_to_fstream(stderr, LLTS_NONE); 120750aadb33SDmitri Tikhonov lsquic_logger_lopt(optarg); 120850aadb33SDmitri Tikhonov break; 120950aadb33SDmitri Tikhonov default: 121050aadb33SDmitri Tikhonov exit(1); 121150aadb33SDmitri Tikhonov } 121250aadb33SDmitri Tikhonov } 121350aadb33SDmitri Tikhonov 121450aadb33SDmitri Tikhonov const struct frame_reader_test *frt; 121550aadb33SDmitri Tikhonov for (frt = tests; frt->frt_bufsz > 0; ++frt) 121650aadb33SDmitri Tikhonov test_one_frt(frt); 121750aadb33SDmitri Tikhonov return 0; 121850aadb33SDmitri Tikhonov} 1219