From a25062f6dfb679e111d8ba2abecdf1838f256e95 Mon Sep 17 00:00:00 2001 From: "luca.morgese@tno.nl" Date: Mon, 8 Apr 2024 17:40:36 +0200 Subject: [PATCH] implement intended url plus path composition for http command and agent --- test/unittest/utils/http/http_test.go | 26 ++++++++++++++++++++++++ utils/http/http.go | 29 +++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/test/unittest/utils/http/http_test.go b/test/unittest/utils/http/http_test.go index 59002843..2de434d7 100644 --- a/test/unittest/utils/http/http_test.go +++ b/test/unittest/utils/http/http_test.go @@ -470,6 +470,32 @@ func TestHttpPathParser(t *testing.T) { assert.Equal(t, parsedUrl, "https://godcapability.tno.nl") } +func TestHttpPathUrlComposition(t *testing.T) { + target := cacao.AgentTarget{ + Address: map[cacao.NetAddressType][]string{ + "url": {"https://godcapability.tno.nl/isp"}, + }, + } + + command := cacao.Command{ + Type: "http-api", + Command: "POST /isp/cst HTTP/1.1", + Headers: map[string][]string{"accept": {"application/json"}}, + } + httpOptions := http.HttpOptions{ + Target: &target, + Command: &command, + } + + parsedUrl, err := httpOptions.ExtractUrl() + if err != nil { + t.Error("failed test because: ", err) + } + // Duplication of path values if present is INTENDED behaviour and + // a warning will be issued + assert.Equal(t, parsedUrl, "https://godcapability.tno.nl/isp/isp/cst") +} + func TestHttpPathBreakingParser(t *testing.T) { target := cacao.AgentTarget{ Address: map[cacao.NetAddressType][]string{ diff --git a/utils/http/http.go b/utils/http/http.go index 233f4c11..6d9c0337 100644 --- a/utils/http/http.go +++ b/utils/http/http.go @@ -204,17 +204,17 @@ func (httpOptions *HttpOptions) ExtractUrl() (string, error) { } } - // If for an http-api command the agent-target address is a URL, it must be handled differently than dname and ip addresses + // If for an http-api command the agent-target address is a URL, + // we should warn for misuse of the field when appendind command-specified path if len(target.Address["url"]) > 0 { if target.Address["url"][0] != "" { urlObject, err := parsePathBasedUrl(target.Address["url"][0]) if err != nil { return "", err } - if (urlObject.Path != "" && urlObject.Path != "/") && urlObject.Path != path { - log.Warn("agent-target url has path that does not match http-api command path") + if (urlObject.Path != "" && urlObject.Path != "/") && urlObject.Path == path { + log.Warn("possible http api invocation path duplication: agent-target url has same path of http-api command path") } - return urlObject.String(), nil } } return buildSchemeAndHostname(path, target) @@ -229,6 +229,20 @@ func buildSchemeAndHostname(path string, target *cacao.AgentTarget) (string, err return "", err } + // If only URL is used to compose the URL target, then + // scheme and port are not considered + if len(target.Address["url"]) > 0 && + len(target.Address["dname"]) == 0 && + len(target.Address["ipv4"]) == 0 && + len(target.Address["ipv6"]) == 0 { + + url := strings.TrimSuffix(hostname, "/") + if len(path) > 1 && !strings.HasPrefix(path, "/") { + path = "/" + path + } + return strings.TrimSuffix(url+path, "/"), nil + } + parsedUrl := &url.URL{ Scheme: scheme, Host: fmt.Sprintf("%s:%s", hostname, target.Port), @@ -268,6 +282,13 @@ func extractHostname(target *cacao.AgentTarget) (string, error) { } address = target.Address["ipv4"][0] + } else if len(target.Address["url"]) > 0 { + _, err := parsePathBasedUrl(target.Address["url"][0]) + if err != nil { + return "", err + } + address = target.Address["url"][0] + } else { return "", errors.New("unsupported target address type") }