aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/http/test/http_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/http/test/http_test.c')
-rw-r--r--src/plugins/http/test/http_test.c202
1 files changed, 202 insertions, 0 deletions
diff --git a/src/plugins/http/test/http_test.c b/src/plugins/http/test/http_test.c
index bfaa285eb35..04db580cb59 100644
--- a/src/plugins/http/test/http_test.c
+++ b/src/plugins/http/test/http_test.c
@@ -6,6 +6,7 @@
#include <vpp/app/version.h>
#include <http/http.h>
#include <http/http_header_names.h>
+#include <http/http2/hpack.h>
#define HTTP_TEST_I(_cond, _comment, _args...) \
({ \
@@ -533,6 +534,203 @@ http_test_http_header_table (vlib_main_t *vm)
return 0;
}
+static int
+http_test_hpack (vlib_main_t *vm)
+{
+ vlib_cli_output (vm, "hpack_decode_int");
+
+ static uword (*_hpack_decode_int) (u8 * *pos, u8 * end, u8 prefix_len);
+ _hpack_decode_int =
+ vlib_get_plugin_symbol ("http_plugin.so", "hpack_decode_int");
+
+ u8 *pos, *end, *input = 0;
+ uword value;
+#define TEST(i, pl, e) \
+ vec_validate (input, sizeof (i) - 2); \
+ memcpy (input, i, sizeof (i) - 1); \
+ pos = input; \
+ end = vec_end (input); \
+ value = _hpack_decode_int (&pos, end, (u8) pl); \
+ HTTP_TEST ((value == (uword) e && pos == end), \
+ "%U with prefix length %u is %llu", format_hex_bytes, input, \
+ vec_len (input), (u8) pl, value); \
+ vec_free (input);
+
+ TEST ("\x00", 8, 0);
+ TEST ("\x2A", 8, 42);
+ TEST ("\x72", 4, 2);
+ TEST ("\x7F\x00", 7, 127);
+ TEST ("\x7F\x01", 7, 128);
+ TEST ("\x9F\x9A\x0A", 5, 1337);
+ TEST ("\xFF\x80\x01", 7, 255);
+ /* max value to decode is CLIB_WORD_MAX, CLIB_UWORD_MAX is error */
+ TEST ("\x7F\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F", 7, CLIB_WORD_MAX);
+
+#undef TEST
+
+#define N_TEST(i, pl) \
+ vec_validate (input, sizeof (i) - 2); \
+ memcpy (input, i, sizeof (i) - 1); \
+ pos = input; \
+ end = vec_end (input); \
+ value = _hpack_decode_int (&pos, end, (u8) pl); \
+ HTTP_TEST ((value == HPACK_INVALID_INT), \
+ "%U with prefix length %u should be invalid", format_hex_bytes, \
+ input, vec_len (input), (u8) pl); \
+ vec_free (input);
+
+ /* incomplete */
+ N_TEST ("\x7F", 7);
+ N_TEST ("\x0F\xFF\xFF", 4);
+ /* overflow */
+ N_TEST ("\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", 4);
+ N_TEST ("\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", 4);
+
+#undef N_TEST
+
+ vlib_cli_output (vm, "hpack_encode_int");
+
+ static u8 *(*_hpack_encode_int) (u8 * dst, uword value, u8 prefix_len);
+ _hpack_encode_int =
+ vlib_get_plugin_symbol ("http_plugin.so", "hpack_encode_int");
+
+ u8 *buf = 0;
+ u8 *p;
+
+#define TEST(v, pl, e) \
+ vec_validate_init_empty (buf, 15, 0); \
+ p = _hpack_encode_int (buf, v, (u8) pl); \
+ HTTP_TEST (((p - buf) == (sizeof (e) - 1) && !memcmp (buf, e, p - buf)), \
+ "%llu with prefix length %u is encoded as %U", v, (u8) pl, \
+ format_hex_bytes, buf, p - buf); \
+ vec_free (buf);
+
+ TEST (0, 8, "\x00");
+ TEST (2, 4, "\x02");
+ TEST (42, 8, "\x2A");
+ TEST (127, 7, "\x7F\x00");
+ TEST (128, 7, "\x7F\x01");
+ TEST (255, 7, "\x7F\x80\x01");
+ TEST (1337, 5, "\x1F\x9A\x0A");
+ TEST (CLIB_WORD_MAX, 7, "\x7F\x80\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F");
+#undef TEST
+
+ vlib_cli_output (vm, "hpack_decode_string");
+
+ static int (*_hpack_decode_string) (u8 * *src, u8 * end, u8 * *buf,
+ uword * buf_len);
+ _hpack_decode_string =
+ vlib_get_plugin_symbol ("http_plugin.so", "hpack_decode_string");
+
+ u8 *bp;
+ uword blen, len;
+ int rv;
+
+#define TEST(i, e) \
+ vec_validate (input, sizeof (i) - 2); \
+ memcpy (input, i, sizeof (i) - 1); \
+ pos = input; \
+ vec_validate_init_empty (buf, 63, 0); \
+ bp = buf; \
+ blen = vec_len (buf); \
+ rv = _hpack_decode_string (&pos, vec_end (input), &bp, &blen); \
+ len = vec_len (buf) - blen; \
+ HTTP_TEST ((len == strlen (e) && !memcmp (buf, e, len) && \
+ pos == vec_end (input) && bp == buf + len && rv == 0), \
+ "%U is decoded as %U", format_hex_bytes, input, vec_len (input), \
+ format_http_bytes, buf, len); \
+ vec_free (input); \
+ vec_free (buf);
+
+ /* raw coding */
+ TEST ("\x07private", "private");
+ /* Huffman coding */
+ TEST ("\x85\xAE\xC3\x77\x1A\x4B", "private");
+ TEST ("\x86\xA8\xEB\x10\x64\x9C\xBF", "no-cache");
+ TEST ("\x8C\xF1\xE3\xC2\xE5\xF2\x3A\x6B\xA0\xAB\x90\xF4\xFF",
+ "www.example.com");
+ TEST ("\x96\xD0\x7A\xBE\x94\x10\x54\xD4\x44\xA8\x20\x05\x95\x04\x0B\x81\x66"
+ "\xE0\x82\xA6\x2D\x1B\xFF",
+ "Mon, 21 Oct 2013 20:13:21 GMT")
+ TEST ("\xAD\x94\xE7\x82\x1D\xD7\xF2\xE6\xC7\xB3\x35\xDF\xDF\xCD\x5B\x39\x60"
+ "\xD5\xAF\x27\x08\x7F\x36\x72\xC1\xAB\x27\x0F\xB5\x29\x1F\x95\x87\x31"
+ "\x60\x65\xC0\x03\xED\x4E\xE5\xB1\x06\x3D\x50\x07",
+ "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1");
+ TEST ("\x8A\x9C\xB4\x50\x75\x3C\x1E\xCA\x24\xFE\x3F", "hello world!")
+ TEST ("\x8A\xFF\xFE\x03\x18\xC6\x31\x8C\x63\x18\xC7", "\\aaaaaaaaaaaa");
+ TEST ("\x8C\x1F\xFF\xF0\x18\xC6\x31\x80\x03\x18\xC6\x31\x8F",
+ "a\\aaaaa00aaaaaaa");
+ TEST ("\x87\x1F\xFF\xF0\xFF\xFE\x11\xFF", "a\\\\b");
+ TEST ("\x84\x1F\xF9\xFE\xA3", "a?'b");
+ TEST ("\x84\x1F\xFA\xFF\x23", "a'?b");
+ TEST ("\x8D\x1F\xFF\xFF\xFF\x0C\x63\x18\xC0\x01\x8C\x63\x18\xC7",
+ "\x61\xF9\x61\x61\x61\x61\x61\x30\x30\x61\x61\x61\x61\x61\x61\x61")
+#undef TEST
+
+#define N_TEST(i) \
+ vec_validate (input, sizeof (i) - 2); \
+ memcpy (input, i, sizeof (i) - 1); \
+ pos = input; \
+ vec_validate_init_empty (buf, 15, 0); \
+ bp = buf; \
+ blen = vec_len (buf); \
+ rv = _hpack_decode_string (&pos, vec_end (input), &bp, &blen); \
+ HTTP_TEST ((rv != 0), "%U should be invalid", format_hex_bytes, input, \
+ vec_len (input)); \
+ vec_free (input); \
+ vec_free (buf);
+
+ /* incomplete */
+ N_TEST ("\x07priv");
+ /* invalid length */
+ N_TEST ("\x7Fprivate");
+ /* invalid EOF */
+ N_TEST ("\x81\x8C");
+ /* not enough space for decoding */
+ N_TEST (
+ "\x96\xD0\x7A\xBE\x94\x10\x54\xD4\x44\xA8\x20\x05\x95\x04\x0B\x81\x66"
+ "\xE0\x82\xA6\x2D\x1B\xFF");
+#undef N_TEST
+
+ vlib_cli_output (vm, "hpack_encode_string");
+
+ static u8 *(*_hpack_encode_string) (u8 * dst, const u8 *value,
+ uword value_len);
+ _hpack_encode_string =
+ vlib_get_plugin_symbol ("http_plugin.so", "hpack_encode_string");
+
+#define TEST(i, e) \
+ vec_validate (input, sizeof (i) - 2); \
+ memcpy (input, i, sizeof (i) - 1); \
+ pos = input; \
+ vec_validate_init_empty (buf, 63, 0); \
+ p = _hpack_encode_string (buf, input, vec_len (input)); \
+ HTTP_TEST (((p - buf) == (sizeof (e) - 1) && !memcmp (buf, e, p - buf)), \
+ "%v is encoded as %U", input, format_hex_bytes, buf, p - buf); \
+ vec_free (input); \
+ vec_free (buf);
+
+ /* Huffman coding */
+ TEST ("private", "\x85\xAE\xC3\x77\x1A\x4B");
+ TEST ("no-cache", "\x86\xA8\xEB\x10\x64\x9C\xBF");
+ TEST ("www.example.com",
+ "\x8C\xF1\xE3\xC2\xE5\xF2\x3A\x6B\xA0\xAB\x90\xF4\xFF");
+ TEST ("Mon, 21 Oct 2013 20:13:21 GMT",
+ "\x96\xD0\x7A\xBE\x94\x10\x54\xD4\x44\xA8\x20\x05\x95\x04\x0B\x81\x66"
+ "\xE0\x82\xA6\x2D\x1B\xFF")
+ TEST ("foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1",
+ "\xAD\x94\xE7\x82\x1D\xD7\xF2\xE6\xC7\xB3\x35\xDF\xDF\xCD\x5B\x39\x60"
+ "\xD5\xAF\x27\x08\x7F\x36\x72\xC1\xAB\x27\x0F\xB5\x29\x1F\x95\x87\x31"
+ "\x60\x65\xC0\x03\xED\x4E\xE5\xB1\x06\x3D\x50\x07");
+ TEST ("hello world!", "\x8A\x9C\xB4\x50\x75\x3C\x1E\xCA\x24\xFE\x3F")
+ TEST ("\\aaaaaaaaaaaa", "\x8A\xFF\xFE\x03\x18\xC6\x31\x8C\x63\x18\xC7");
+ /* raw coding */
+ TEST ("[XZ]", "\x4[XZ]");
+#undef TEST
+
+ return 0;
+}
+
static clib_error_t *
test_http_command_fn (vlib_main_t *vm, unformat_input_t *input,
vlib_cli_command_t *cmd)
@@ -550,6 +748,8 @@ test_http_command_fn (vlib_main_t *vm, unformat_input_t *input,
res = http_test_http_token_is_case (vm);
else if (unformat (input, "header-table"))
res = http_test_http_header_table (vm);
+ else if (unformat (input, "hpack"))
+ res = http_test_hpack (vm);
else if (unformat (input, "all"))
{
if ((res = http_test_parse_authority (vm)))
@@ -562,6 +762,8 @@ test_http_command_fn (vlib_main_t *vm, unformat_input_t *input,
goto done;
if ((res = http_test_http_header_table (vm)))
goto done;
+ if ((res = http_test_hpack (vm)))
+ goto done;
}
else
break;