diff options
Diffstat (limited to 'src/plugins/http/test/http_test.c')
-rw-r--r-- | src/plugins/http/test/http_test.c | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/src/plugins/http/test/http_test.c b/src/plugins/http/test/http_test.c index 691efdf6138..f44d3cbd31b 100644 --- a/src/plugins/http/test/http_test.c +++ b/src/plugins/http/test/http_test.c @@ -7,6 +7,7 @@ #include <http/http.h> #include <http/http_header_names.h> #include <http/http2/hpack.h> +#include <http/http2/frame.h> #define HTTP_TEST_I(_cond, _comment, _args...) \ ({ \ @@ -1020,6 +1021,285 @@ http_test_hpack (vlib_main_t *vm) return 0; } +static int +http_test_h2_frame (vlib_main_t *vm) +{ + static void (*_http2_frame_header_read) (u8 * src, + http2_frame_header_t * fh); + + _http2_frame_header_read = + vlib_get_plugin_symbol ("http_plugin.so", "http2_frame_header_read"); + + vlib_cli_output (vm, "http2_frame_read_settings"); + + static http2_error_t (*_http2_frame_read_settings) ( + http2_conn_settings_t * settings, u8 * payload, u32 payload_len); + + _http2_frame_read_settings = + vlib_get_plugin_symbol ("http_plugin.so", "http2_frame_read_settings"); + + http2_error_t rv; + http2_frame_header_t fh = { 0 }; + http2_conn_settings_t conn_settings = http2_default_conn_settings; + + u8 settings[] = { 0x0, 0x0, 0x12, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x3, 0x0, 0x0, 0x0, 0x64, 0x0, 0x4, 0x40, + 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0 }; + _http2_frame_header_read (settings, &fh); + HTTP_TEST ((fh.flags == 0 && fh.type == HTTP2_FRAME_TYPE_SETTINGS && + fh.stream_id == 0 && fh.length == 18), + "frame identified as SETTINGS"); + + rv = _http2_frame_read_settings ( + &conn_settings, settings + HTTP2_FRAME_HEADER_SIZE, fh.length); + HTTP_TEST ((rv == HTTP2_ERROR_NO_ERROR && + conn_settings.max_concurrent_streams == 100 && + conn_settings.initial_window_size == 1073741824 && + conn_settings.enable_push == 0), + "SETTINGS frame payload parsed") + + u8 settings_ack[] = { 0x0, 0x0, 0x0, 0x4, 0x1, 0x0, 0x0, 0x0, 0x0 }; + _http2_frame_header_read (settings_ack, &fh); + HTTP_TEST ((fh.flags == HTTP2_FRAME_FLAG_ACK && + fh.type == HTTP2_FRAME_TYPE_SETTINGS && fh.stream_id == 0 && + fh.length == 0), + "frame identified as SETTINGS ACK"); + + vlib_cli_output (vm, "http2_frame_write_settings_ack"); + + static void (*_http2_frame_write_settings_ack) (u8 * *dst); + + _http2_frame_write_settings_ack = vlib_get_plugin_symbol ( + "http_plugin.so", "http2_frame_write_settings_ack"); + + u8 *buf = 0; + + _http2_frame_write_settings_ack (&buf); + HTTP_TEST ((vec_len (buf) == sizeof (settings_ack)) && + !memcmp (buf, settings_ack, sizeof (settings_ack)), + "SETTINGS ACK frame written"); + vec_free (buf); + + vlib_cli_output (vm, "http2_frame_write_settings"); + + static void (*_http2_frame_write_settings) ( + http2_settings_entry_t * settings, u8 * *dst); + + _http2_frame_write_settings = + vlib_get_plugin_symbol ("http_plugin.so", "http2_frame_write_settings"); + + http2_settings_entry_t *settings_list = 0; + vec_validate (settings_list, 2); + settings_list[0].identifier = HTTP2_SETTINGS_MAX_CONCURRENT_STREAMS; + settings_list[0].value = 100; + settings_list[1].identifier = HTTP2_SETTINGS_INITIAL_WINDOW_SIZE; + settings_list[1].value = 1073741824; + settings_list[2].identifier = HTTP2_SETTINGS_ENABLE_PUSH; + settings_list[2].value = 0; + + _http2_frame_write_settings (settings_list, &buf); + HTTP_TEST ((vec_len (buf) == sizeof (settings) && + !memcmp (buf, settings, sizeof (settings))), + "SETTINGS frame written"); + vec_free (settings_list); + vec_free (buf); + + vlib_cli_output (vm, "http2_frame_read_window_update"); + + static http2_error_t (*_http2_frame_read_window_update) ( + u32 * increment, u8 * payload, u32 payload_len); + + _http2_frame_read_window_update = vlib_get_plugin_symbol ( + "http_plugin.so", "http2_frame_read_window_update"); + + u32 win_increment; + u8 win_update[] = { 0x0, 0x0, 0x4, 0x8, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3f, 0xff, 0x0, 0x1 }; + _http2_frame_header_read (win_update, &fh); + HTTP_TEST ((fh.flags == 0 && fh.type == HTTP2_FRAME_TYPE_WINDOW_UPDATE && + fh.stream_id == 0 && fh.length == 4), + "frame identified as WINDOW_UPDATE"); + + rv = _http2_frame_read_window_update ( + &win_increment, win_update + HTTP2_FRAME_HEADER_SIZE, fh.length); + HTTP_TEST ((rv == HTTP2_ERROR_NO_ERROR && win_increment == 1073676289), + "WINDOW_UPDATE frame payload parsed") + + vlib_cli_output (vm, "http2_frame_write_window_update"); + + static void (*_http2_frame_write_window_update) (u32 increment, + u32 stream_id, u8 * *dst); + + _http2_frame_write_window_update = vlib_get_plugin_symbol ( + "http_plugin.so", "http2_frame_write_window_update"); + + _http2_frame_write_window_update (1073676289, 0, &buf); + HTTP_TEST ((vec_len (buf) == sizeof (win_update) && + !memcmp (buf, win_update, sizeof (win_update))), + "WINDOW_UPDATE frame written"); + vec_free (buf); + + vlib_cli_output (vm, "http2_frame_read_rst_stream"); + + static http2_error_t (*_http2_frame_read_rst_stream) ( + u32 * error_code, u8 * payload, u32 payload_len); + + _http2_frame_read_rst_stream = + vlib_get_plugin_symbol ("http_plugin.so", "http2_frame_read_rst_stream"); + + u32 error_code; + u8 rst_stream[] = { 0x0, 0x0, 0x4, 0x3, 0x0, 0x0, 0x0, + 0x0, 0x5, 0x0, 0x0, 0x0, 0x01 }; + _http2_frame_header_read (rst_stream, &fh); + HTTP_TEST ((fh.flags == 0 && fh.type == HTTP2_FRAME_TYPE_RST_STREAM && + fh.stream_id == 5 && fh.length == 4), + "frame identified as RST_STREAM"); + + rv = _http2_frame_read_rst_stream ( + &error_code, rst_stream + HTTP2_FRAME_HEADER_SIZE, fh.length); + HTTP_TEST ( + (rv == HTTP2_ERROR_NO_ERROR && error_code == HTTP2_ERROR_PROTOCOL_ERROR), + "RST_STREAM frame payload parsed") + + vlib_cli_output (vm, "http2_frame_write_rst_stream"); + + static void (*_http2_frame_write_rst_stream) (u32 increment, u32 stream_id, + u8 * *dst); + + _http2_frame_write_rst_stream = + vlib_get_plugin_symbol ("http_plugin.so", "http2_frame_write_rst_stream"); + + _http2_frame_write_rst_stream (HTTP2_ERROR_PROTOCOL_ERROR, 5, &buf); + HTTP_TEST ((vec_len (buf) == sizeof (rst_stream) && + !memcmp (buf, rst_stream, sizeof (rst_stream))), + "RST_STREAM frame written"); + vec_free (buf); + + vlib_cli_output (vm, "http2_frame_read_goaway"); + + static http2_error_t (*_http2_frame_read_goaway) ( + u32 * error_code, u32 * last_stream_id, u8 * payload, u32 payload_len); + + _http2_frame_read_goaway = + vlib_get_plugin_symbol ("http_plugin.so", "http2_frame_read_goaway"); + + u32 last_stream_id; + u8 goaway[] = { 0x0, 0x0, 0x8, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x2 }; + + _http2_frame_header_read (goaway, &fh); + HTTP_TEST ((fh.flags == 0 && fh.type == HTTP2_FRAME_TYPE_GOAWAY && + fh.stream_id == 0 && fh.length == 8), + "frame identified as GOAWAY"); + + rv = _http2_frame_read_goaway (&error_code, &last_stream_id, + goaway + HTTP2_FRAME_HEADER_SIZE, fh.length); + HTTP_TEST ((rv == HTTP2_ERROR_NO_ERROR && + error_code == HTTP2_ERROR_INTERNAL_ERROR && last_stream_id == 5), + "GOAWAY frame payload parsed") + + vlib_cli_output (vm, "http2_frame_write_goaway"); + + static void (*_http2_frame_write_goaway) (http2_error_t error_code, + u32 last_stream_id, u8 * *dst); + + _http2_frame_write_goaway = + vlib_get_plugin_symbol ("http_plugin.so", "http2_frame_write_goaway"); + + _http2_frame_write_goaway (HTTP2_ERROR_INTERNAL_ERROR, 5, &buf); + HTTP_TEST ((vec_len (buf) == sizeof (goaway) && + !memcmp (buf, goaway, sizeof (goaway))), + "GOAWAY frame written"); + vec_free (buf); + + vlib_cli_output (vm, "http2_frame_read_headers"); + + static http2_error_t (*_http2_frame_read_headers) ( + u8 * *headers, u32 * headers_len, u8 * payload, u32 payload_len, u8 flags); + + _http2_frame_read_headers = + vlib_get_plugin_symbol ("http_plugin.so", "http2_frame_read_headers"); + + u8 *h; + u32 h_len; + u8 headers[] = { 0x0, 0x0, 0x28, 0x1, 0x5, 0x0, 0x0, 0x0, 0x3, 0x3f, + 0xe1, 0x1f, 0x82, 0x4, 0x88, 0x62, 0x7b, 0x69, 0x1d, 0x48, + 0x5d, 0x3e, 0x53, 0x86, 0x41, 0x88, 0xaa, 0x69, 0xd2, 0x9a, + 0xc4, 0xb9, 0xec, 0x9b, 0x7a, 0x88, 0x25, 0xb6, 0x50, 0xc3, + 0xab, 0xb8, 0x15, 0xc1, 0x53, 0x3, 0x2a, 0x2f, 0x2a }; + + _http2_frame_header_read (headers, &fh); + HTTP_TEST ((fh.flags == + (HTTP2_FRAME_FLAG_END_HEADERS | HTTP2_FRAME_FLAG_END_STREAM) && + fh.type == HTTP2_FRAME_TYPE_HEADERS && fh.stream_id == 3 && + fh.length == 40), + "frame identified as HEADERS"); + + rv = _http2_frame_read_headers ( + &h, &h_len, headers + HTTP2_FRAME_HEADER_SIZE, fh.length, fh.flags); + HTTP_TEST ((rv == HTTP2_ERROR_NO_ERROR && h_len == 40 && + *h == headers[HTTP2_FRAME_HEADER_SIZE]), + "HEADERS frame payload parsed") + + vlib_cli_output (vm, "http2_frame_write_headers_header"); + + static void (*_http2_frame_write_headers_header) ( + u32 headers_len, u32 stream_id, u8 flags, u8 * dst); + + _http2_frame_write_headers_header = vlib_get_plugin_symbol ( + "http_plugin.so", "http2_frame_write_headers_header"); + + u8 *p = http2_frame_header_alloc (&buf); + _http2_frame_write_headers_header ( + 40, 3, HTTP2_FRAME_FLAG_END_HEADERS | HTTP2_FRAME_FLAG_END_STREAM, p); + HTTP_TEST ((vec_len (buf) == HTTP2_FRAME_HEADER_SIZE && + !memcmp (buf, headers, HTTP2_FRAME_HEADER_SIZE)), + "HEADERS frame header written"); + vec_free (buf); + + vlib_cli_output (vm, "http2_frame_read_data"); + + static http2_error_t (*_http2_frame_read_data) ( + u8 * *data, u32 * data_len, u8 * payload, u32 payload_len, u8 flags); + + _http2_frame_read_data = + vlib_get_plugin_symbol ("http_plugin.so", "http2_frame_read_data"); + + u8 *d; + u32 d_len; + u8 data[] = { 0x0, 0x0, 0x9, 0x0, 0x1, 0x0, 0x0, 0x0, 0x3, + 0x6e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64 }; + + _http2_frame_header_read (data, &fh); + HTTP_TEST ((fh.flags == HTTP2_FRAME_FLAG_END_STREAM && + fh.type == HTTP2_FRAME_TYPE_DATA && fh.stream_id == 3 && + fh.length == 9), + "frame identified as DATA"); + + rv = _http2_frame_read_data (&d, &d_len, data + HTTP2_FRAME_HEADER_SIZE, + fh.length, fh.flags); + HTTP_TEST ((rv == HTTP2_ERROR_NO_ERROR && d_len == 9 && + *d == data[HTTP2_FRAME_HEADER_SIZE]), + "DATA frame payload parsed") + + vlib_cli_output (vm, "http2_frame_write_data_header"); + + static void (*_http2_frame_write_data_header) ( + u32 headers_len, u32 stream_id, u8 flags, u8 * dst); + + _http2_frame_write_data_header = + vlib_get_plugin_symbol ("http_plugin.so", "http2_frame_write_data_header"); + + p = http2_frame_header_alloc (&buf); + _http2_frame_write_data_header (9, 3, HTTP2_FRAME_FLAG_END_STREAM, p); + HTTP_TEST ((vec_len (buf) == HTTP2_FRAME_HEADER_SIZE && + !memcmp (buf, data, HTTP2_FRAME_HEADER_SIZE)), + "DATA frame header written"); + vec_free (buf); + + return 0; +} + static clib_error_t * test_http_command_fn (vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd) @@ -1039,6 +1319,8 @@ test_http_command_fn (vlib_main_t *vm, unformat_input_t *input, res = http_test_http_header_table (vm); else if (unformat (input, "hpack")) res = http_test_hpack (vm); + else if (unformat (input, "h2-frame")) + res = http_test_h2_frame (vm); else if (unformat (input, "all")) { if ((res = http_test_parse_authority (vm))) @@ -1053,6 +1335,8 @@ test_http_command_fn (vlib_main_t *vm, unformat_input_t *input, goto done; if ((res = http_test_hpack (vm))) goto done; + if ((res = http_test_h2_frame (vm))) + goto done; } else break; |