http: authority-form target parsing/serializing

Type: improvement
Change-Id: Ifb90818a3526d3d4030a66b1ef7eebedfe97978f
Signed-off-by: Matus Fabian <matfabia@cisco.com>
This commit is contained in:
Matus Fabian
2024-08-08 12:50:32 +02:00
committed by Florin Coras
parent 0ce93ae744
commit d58177c50b
4 changed files with 108 additions and 1 deletions

View 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

View File

@@ -16,4 +16,5 @@ add_vpp_plugin(http
http.c
http_buffer.c
http_timer.c
http_test.c
)

View 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_ */
/*

View File

@@ -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,
};