diff options
-rw-r--r-- | extras/hs-test/http_test.go | 22 | ||||
-rw-r--r-- | src/plugins/http/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/plugins/http/http.h | 52 | ||||
-rw-r--r-- | src/plugins/http/http_test.c | 34 |
4 files changed, 108 insertions, 1 deletions
diff --git a/extras/hs-test/http_test.go b/extras/hs-test/http_test.go index c45f7c2d57c..8f8946fa32e 100644 --- a/extras/hs-test/http_test.go +++ b/extras/hs-test/http_test.go @@ -29,7 +29,7 @@ func init() { HttpStaticMacTimeTest, HttpStaticBuildInUrlGetVersionVerboseTest, HttpVersionNotSupportedTest, HttpInvalidContentLengthTest, HttpInvalidTargetSyntaxTest, HttpStaticPathTraversalTest, HttpUriDecodeTest, HttpHeadersTest, HttpStaticFileHandlerTest, HttpClientTest, HttpClientErrRespTest, HttpClientPostFormTest, - HttpClientPostFileTest, HttpClientPostFilePtrTest) + HttpClientPostFileTest, HttpClientPostFilePtrTest, AuthorityFormTargetTest) RegisterNoTopoSoloTests(HttpStaticPromTest, HttpTpsTest, HttpTpsInterruptModeTest, PromConcurrentConnectionsTest, PromMemLeakTest, HttpClientPostMemLeakTest) } @@ -305,6 +305,26 @@ func HttpClientPostFilePtrTest(s *NoTopoSuite) { httpClientPostFile(s, true, 131072) } +func cliTestAuthority(s *NoTopoSuite, authority string) { + o := s.GetContainerByName("vpp").VppInstance.Vppctl("test http authority-form " + authority) + s.AssertNotContains(o, "error") + s.AssertContains(o, authority) +} + +func cliTestAuthorityError(s *NoTopoSuite, authority string) { + o := s.GetContainerByName("vpp").VppInstance.Vppctl("test http authority-form " + authority) + s.AssertContains(o, "error") +} + +func AuthorityFormTargetTest(s *NoTopoSuite) { + cliTestAuthority(s, "10.10.2.45:20") + cliTestAuthority(s, "[dead:beef::1234]:443") + cliTestAuthorityError(s, "example.com:80") + cliTestAuthorityError(s, "10.10.2.45") + cliTestAuthorityError(s, "1000.10.2.45:20") + cliTestAuthorityError(s, "[xyz0::1234]:443") +} + func HttpStaticPromTest(s *NoTopoSuite) { query := "stats.prom" vpp := s.GetContainerByName("vpp").VppInstance diff --git a/src/plugins/http/CMakeLists.txt b/src/plugins/http/CMakeLists.txt index d9cd84a3955..c51a7dce36d 100644 --- a/src/plugins/http/CMakeLists.txt +++ b/src/plugins/http/CMakeLists.txt @@ -16,4 +16,5 @@ add_vpp_plugin(http http.c http_buffer.c http_timer.c + http_test.c ) diff --git a/src/plugins/http/http.h b/src/plugins/http/http.h index 63d05860099..19147904bfd 100644 --- a/src/plugins/http/http.h +++ b/src/plugins/http/http.h @@ -921,6 +921,58 @@ http_serialize_headers (http_header_t *headers) return headers_buf; } +typedef struct +{ + ip46_address_t ip; + u16 port; + u8 is_ip4; +} http_uri_t; + +always_inline int +http_parse_authority_form_target (u8 *target, http_uri_t *authority) +{ + unformat_input_t input; + u32 port; + int rv = 0; + + unformat_init_vector (&input, vec_dup (target)); + if (unformat (&input, "[%U]:%d", unformat_ip6_address, &authority->ip.ip6, + &port)) + { + authority->port = clib_host_to_net_u16 (port); + authority->is_ip4 = 0; + } + else if (unformat (&input, "%U:%d", unformat_ip4_address, &authority->ip.ip4, + &port)) + { + authority->port = clib_host_to_net_u16 (port); + authority->is_ip4 = 1; + } + /* TODO reg-name resolution */ + else + { + clib_warning ("unsupported format '%v'", target); + rv = -1; + } + unformat_free (&input); + return rv; +} + +always_inline u8 * +http_serialize_authority_form_target (http_uri_t *authority) +{ + u8 *s; + + if (authority->is_ip4) + s = format (0, "%U:%d", format_ip4_address, &authority->ip.ip4, + clib_net_to_host_u16 (authority->port)); + else + s = format (0, "[%U]:%d", format_ip6_address, &authority->ip.ip6, + clib_net_to_host_u16 (authority->port)); + + return s; +} + #endif /* SRC_PLUGINS_HTTP_HTTP_H_ */ /* diff --git a/src/plugins/http/http_test.c b/src/plugins/http/http_test.c new file mode 100644 index 00000000000..1f2f21dd19a --- /dev/null +++ b/src/plugins/http/http_test.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright(c) 2024 Cisco Systems, Inc. + */ + +#include <http/http.h> + +static clib_error_t * +test_http_authority_command_fn (vlib_main_t *vm, unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + u8 *target = 0; + http_uri_t authority; + int rv; + + if (!unformat (input, "%v", &target)) + return clib_error_return (0, "error: no input provided"); + + rv = http_parse_authority_form_target (target, &authority); + vec_free (target); + if (rv) + return clib_error_return (0, "error: parsing failed"); + + target = http_serialize_authority_form_target (&authority); + vlib_cli_output (vm, "%v", target); + vec_free (target); + + return 0; +} + +VLIB_CLI_COMMAND (test_http_authority_command) = { + .path = "test http authority-form", + .short_help = "test dns authority-form", + .function = test_http_authority_command_fn, +}; |