Skip to content

Commit

Permalink
add a helper function to extract the HTTP path from a template
Browse files Browse the repository at this point in the history
  • Loading branch information
marten-seemann committed Aug 14, 2024
1 parent 3be033a commit b6dadec
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
15 changes: 15 additions & 0 deletions request.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net/http"
"net/url"
"strconv"
"strings"

"github.com/dunglas/httpsfv"
"github.com/yosida95/uritemplate/v3"
Expand Down Expand Up @@ -89,3 +90,17 @@ func ParseRequest(r *http.Request, template *uritemplate.Template) (*Request, er
}
return &Request{Target: fmt.Sprintf("%s:%d", targetHost, targetPort)}, nil
}

// PathFromTemplate extracts the HTTP path from a URI template,
// such that it can be used in a http.ServeMux.
func PathFromTemplate(t *uritemplate.Template) (string, error) {
u, err := url.Parse(t.Raw())
if err != nil {
return "", err

Check warning on line 99 in request.go

View check run for this annotation

Codecov / codecov/patch

request.go#L99

Added line #L99 was not covered by tests
}
path := strings.ReplaceAll(strings.ReplaceAll(u.Path, "/{target_host}", ""), "/{target_port}", "")
if path != u.Path && len(path) > 0 && path[len(path)-1] != '/' {
path = path + "/"
}
return path, nil
}
29 changes: 29 additions & 0 deletions request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,32 @@ func TestRequestParsing(t *testing.T) {
require.Equal(t, http.StatusBadRequest, err.(*RequestParseError).HTTPStatus)
})
}

func TestPathFromTemplate(t *testing.T) {
for _, tc := range []struct {
name, template, expected string
}{
{
"variables as URL parameters",
"https://localhost:1234/masque?h={target_host}&p={target_port}",
"/masque",
},
{
"variables in URL paths",
"https://localhost:1234/masque/{target_host}/{target_port}",
"/masque/", // needs to have a trailing /
},
{
"variables in URL paths, no trailing /",
"https://localhost:1234/masque/{target_host}/{target_port}/",
"/masque/",
},
} {
t.Run(tc.name, func(t *testing.T) {
temp := uritemplate.MustNew(tc.template)
path, err := PathFromTemplate(temp)
require.NoError(t, err)
require.Equal(t, tc.expected, path)
})
}
}

0 comments on commit b6dadec

Please sign in to comment.