diff --git a/go.mod b/go.mod index b99ecd25..5253061d 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.2 github.com/jackc/pgx/v5 v5.2.0 github.com/jlaffaye/ftp v0.0.0-20201112195030-9aae4d151126 - github.com/klauspost/compress v1.15.14 + github.com/klauspost/compress v1.15.15 github.com/lestrrat-go/jwx/v2 v2.0.8 github.com/lithammer/shortuuid/v3 v3.0.7 github.com/mattn/go-sqlite3 v1.14.16 diff --git a/go.sum b/go.sum index ca811659..4e596fce 100644 --- a/go.sum +++ b/go.sum @@ -1397,8 +1397,8 @@ github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.14 h1:i7WCKDToww0wA+9qrUZ1xOjp218vfFo3nTU6UHp+gOc= -github.com/klauspost/compress v1.15.14/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= +github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= diff --git a/internal/common/eventmanager.go b/internal/common/eventmanager.go index 912f4fb7..49bdbca8 100644 --- a/internal/common/eventmanager.go +++ b/internal/common/eventmanager.go @@ -1029,11 +1029,22 @@ func checkEventGroupConditionPatters(groups []sdk.GroupMapping, patterns []datap } func getHTTPRuleActionEndpoint(c dataprovider.EventActionHTTPConfig, replacer *strings.Replacer) (string, error) { - if len(c.QueryParameters) > 0 { - u, err := url.Parse(c.Endpoint) - if err != nil { - return "", fmt.Errorf("invalid endpoint: %w", err) + u, err := url.Parse(c.Endpoint) + if err != nil { + return "", fmt.Errorf("invalid endpoint: %w", err) + } + if strings.Contains(u.Path, "{{") { + pathComponents := strings.Split(u.Path, "/") + for idx := range pathComponents { + part := replaceWithReplacer(pathComponents[idx], replacer) + if part != pathComponents[idx] { + pathComponents[idx] = url.PathEscape(part) + } } + u.Path = "" + u = u.JoinPath(pathComponents...) + } + if len(c.QueryParameters) > 0 { q := u.Query() for _, keyVal := range c.QueryParameters { @@ -1041,9 +1052,8 @@ func getHTTPRuleActionEndpoint(c dataprovider.EventActionHTTPConfig, replacer *s } u.RawQuery = q.Encode() - return u.String(), nil } - return c.Endpoint, nil + return u.String(), nil } func writeHTTPPart(m *multipart.Writer, part dataprovider.HTTPPart, h textproto.MIMEHeader, diff --git a/internal/common/eventmanager_test.go b/internal/common/eventmanager_test.go index 7c4cf436..a1cf8077 100644 --- a/internal/common/eventmanager_test.go +++ b/internal/common/eventmanager_test.go @@ -21,6 +21,7 @@ import ( "io" "mime/multipart" "net/http" + "net/url" "os" "path" "path/filepath" @@ -703,6 +704,7 @@ func TestEventRuleActions(t *testing.T) { if assert.Error(t, err) { assert.Contains(t, err.Error(), "unable to decrypt HTTP password") } + action.Options.HTTPConfig.Endpoint = fmt.Sprintf("http://%v", httpAddr) action.Options.HTTPConfig.Password = kms.NewEmptySecret() action.Options.HTTPConfig.Body = "" action.Options.HTTPConfig.Parts = []dataprovider.HTTPPart{ @@ -1890,3 +1892,33 @@ func getErrorString(err error) string { } return err.Error() } + +func TestHTTPEndpointWithPlaceholders(t *testing.T) { + c := dataprovider.EventActionHTTPConfig{ + Endpoint: "http://127.0.0.1:8080/base/url/{{Name}}/{{VirtualPath}}/upload", + QueryParameters: []dataprovider.KeyValue{ + { + Key: "u", + Value: "{{Name}}", + }, + { + Key: "p", + Value: "{{VirtualPath}}", + }, + }, + } + name := "uname" + vPath := "/a dir/@ file.txt" + replacer := strings.NewReplacer("{{Name}}", name, "{{VirtualPath}}", vPath) + u, err := getHTTPRuleActionEndpoint(c, replacer) + assert.NoError(t, err) + expected := "http://127.0.0.1:8080/base/url/" + url.PathEscape(name) + "/" + url.PathEscape(vPath) + + "/upload?" + "p=" + url.QueryEscape(vPath) + "&u=" + url.QueryEscape(name) + assert.Equal(t, expected, u) + + c.Endpoint = "http://127.0.0.1/upload" + u, err = getHTTPRuleActionEndpoint(c, replacer) + assert.NoError(t, err) + expected = c.Endpoint + "?p=" + url.QueryEscape(vPath) + "&u=" + url.QueryEscape(name) + assert.Equal(t, expected, u) +} diff --git a/templates/webadmin/eventaction.html b/templates/webadmin/eventaction.html index be8c1ae1..1c57beaa 100644 --- a/templates/webadmin/eventaction.html +++ b/templates/webadmin/eventaction.html @@ -91,7 +91,7 @@ along with this program. If not, see . - Endpoint URL, i.e https://host:port/path + Endpoint URL, i.e https://host:port/path. Placeholders are supported within the URL path