http: authority-form target parsing/serializing 98/41398/2
authorMatus Fabian <[email protected]>
Thu, 8 Aug 2024 10:50:32 +0000 (12:50 +0200)
committerFlorin Coras <[email protected]>
Fri, 9 Aug 2024 20:08:59 +0000 (20:08 +0000)
Type: improvement
Change-Id: Ifb90818a3526d3d4030a66b1ef7eebedfe97978f
Signed-off-by: Matus Fabian <[email protected]>
extras/hs-test/http_test.go
src/plugins/http/CMakeLists.txt
src/plugins/http/http.h
src/plugins/http/http_test.c [new file with mode: 0644]

index c45f7c2..8f8946f 100644 (file)
@@ -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
index d9cd84a..c51a7dc 100644 (file)
@@ -16,4 +16,5 @@ add_vpp_plugin(http
   http.c
   http_buffer.c
   http_timer.c
+  http_test.c
 )
index 63d0586..1914790 100644 (file)
@@ -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 (file)
index 0000000..1f2f21d
--- /dev/null
@@ -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,
+};