diff --git a/data.go b/data.go index d3295fe..13bc37d 100644 --- a/data.go +++ b/data.go @@ -222,10 +222,6 @@ func (r Request) String() string { return u.String() } -// reCleanedURL matches an absolute HTTP URL that has been munged by path.Clean -// or a webserver that collapses multiple slashes. -var reCleanedURL = regexp.MustCompile(`^(https?):/([^/])`) - // NewRequest parses an http.Request into an imageproxy Request. Options and // the remote image URL are specified in the request path, formatted as: // /{options}/{remote_url}. Options may be omitted, so a request path may @@ -244,8 +240,7 @@ func NewRequest(r *http.Request, baseURL *url.URL) (*Request, error) { req := &Request{Original: r} path := r.URL.Path[1:] // strip leading slash - path = reCleanedURL.ReplaceAllString(path, "$1://$2") - req.URL, err = url.Parse(path) + req.URL, err = parseURL(path) if err != nil || !req.URL.IsAbs() { // first segment should be options parts := strings.SplitN(path, "/", 2) @@ -254,7 +249,7 @@ func NewRequest(r *http.Request, baseURL *url.URL) (*Request, error) { } var err error - req.URL, err = url.Parse(parts[1]) + req.URL, err = parseURL(parts[1]) if err != nil { return nil, URLError{fmt.Sprintf("unable to parse remote URL: %v", err), r.URL} } @@ -278,3 +273,12 @@ func NewRequest(r *http.Request, baseURL *url.URL) (*Request, error) { req.URL.RawQuery = r.URL.RawQuery return req, nil } + +var reCleanedURL = regexp.MustCompile(`^(https?):/+([^/])`) + +// parseURL parses s as a URL, handling URLs that have been munged by +// path.Clean or a webserver that collapses multiple slashes. +func parseURL(s string) (*url.URL, error) { + s = reCleanedURL.ReplaceAllString(s, "$1://$2") + return url.Parse(s) +} diff --git a/data_test.go b/data_test.go index fc18d9b..2f19ef2 100644 --- a/data_test.go +++ b/data_test.go @@ -147,6 +147,10 @@ func TestNewRequest(t *testing.T) { "http://localhost/http:/example.com/foo", "http://example.com/foo", emptyOptions, false, }, + { + "http://localhost/http:///example.com/foo", + "http://example.com/foo", emptyOptions, false, + }, } for _, tt := range tests {