Added tests and fixed code get it passing

This commit is contained in:
Matthew Beatty 2025-04-25 15:23:22 -04:00
parent dcfb286874
commit ec264026c9
2 changed files with 81 additions and 11 deletions

55
data.go
View file

@ -337,11 +337,13 @@ func (r Request) String() string {
// http://localhost/http://example.com/image.jpg
func NewRequest(r *http.Request, baseURL *url.URL) (*Request, error) {
var err error
var additionalQuery string
req := &Request{Original: r}
path := r.URL.EscapedPath()[1:] // strip leading slash
path, err = decodeUrl(path)
path := r.URL.EscapedPath()[1:] // the image url is stored in the path, so get image url from path but strip leading slash so it's not like /https://example.com
path, err, additionalQuery = decodeURL(path) // Conditionally decode url path param if it is url encoded this enables us to process image urls with query params built in
req.URL, err = parseURL(path)
if err != nil || !req.URL.IsAbs() {
// first segment should be options
parts := strings.SplitN(path, "/", 2)
@ -371,7 +373,7 @@ func NewRequest(r *http.Request, baseURL *url.URL) (*Request, error) {
}
// query string is always part of the remote URL
req.URL.RawQuery = r.URL.RawQuery
req.URL.RawQuery = combineQueries(r.URL.RawQuery, additionalQuery)
return req, nil
}
@ -386,11 +388,42 @@ func parseURL(s string) (*url.URL, error) {
var reIsEncodedUrl = regexp.MustCompile(`^https?%`)
func decodeUrl(s string) (string, error) {
var isUrlEncoded = reIsEncodedUrl.MatchString(s)
if isUrlEncoded {
return url.QueryUnescape(s)
} else {
return s, nil
}
}
func decodeURL(s string) (string, error, string) {
var startsWithHttp = strings.HasPrefix(s, "http")
var prefix = ""
var u = s
if !startsWithHttp && strings.Contains(s, "http") {
var parts = strings.SplitN(s, "http", 2)
u = "http" + parts[1]
prefix = parts[0]
}
var isUrlEncoded = reIsEncodedUrl.MatchString(u)
print(u, ": ", isUrlEncoded, "\n")
if isUrlEncoded {
u, err := url.QueryUnescape(u)
if err != nil {
return u, err, ""
}
var parsed, err2 = url.Parse(u)
if err2 != nil {
return u, err2, ""
}
return prefix + u, err2, parsed.RawQuery
} else {
return prefix + u, nil, ""
}
}
func combineQueries(a string, b string) string {
if a == "" {
return b
} else if b == "" {
return a
} else {
return a + "&" + b
}
}

View file

@ -156,6 +156,43 @@ func TestNewRequest(t *testing.T) {
"http://localhost/http://example.com/%2C",
"http://example.com/%2C", emptyOptions, false,
},
// URI Encoded cases
{
"http://localhost/1x2/http%3A%2F%2Fexample.com%2Ffoo",
"http://example.com/foo", Options{Width: 1, Height: 2}, false,
},
{
"http://localhost/1x2/http%3A%2F%2Fexample.com%2Fhttp%2Fstuff",
"http://example.com/http/stuff", Options{Width: 1, Height: 2}, false,
},
{
"http://localhost/http%3A%2F%2Fexample.com%2Ffoo",
"http://example.com/foo", emptyOptions, false,
},
{
"http://localhost/http%3A%2F%2Fexample.com%2Ffoo",
"http://example.com/foo", emptyOptions, false,
},
{
"http://localhost/http%3A%2Fexample.com%2Ffoo",
"http://example.com/foo", emptyOptions, false,
},
{
"http://localhost/http%3A%2F%2F%2Fexample.com%2Ffoo",
"http://example.com/foo", emptyOptions, false,
},
{
"http://localhost//http%3A%2F%2Fexample.com%2Ffoo",
"http://example.com/foo", emptyOptions, false,
},
{
"http://localhost/http%3A%2F%2Fexample.com%2Ffoo%3Ftest%3D1%26test%3D2",
"http://example.com/foo?test=1&test=2", emptyOptions, false,
},
{
"http://localhost/1x2/http%3A%2F%2Fexample.com%2Ffoo%3Ftest%3D1%26test%3D2",
"http://example.com/foo?test=1&test=2", Options{Width: 1, Height: 2}, false,
},
}
for _, tt := range tests {