diff --git a/system/service/sink.go b/system/service/sink.go index a01ebfb7f..0c0971c94 100644 --- a/system/service/sink.go +++ b/system/service/sink.go @@ -5,6 +5,7 @@ import ( "encoding/base64" "encoding/json" "fmt" + "github.com/davecgh/go-spew/spew" "io" "net/http" "net/url" @@ -130,11 +131,11 @@ func (svc sink) GetPath() string { // pathCleanup removes base URL prefix and adds leading slash func (svc sink) pathCleanup(p string) string { if len(p) > 0 { - if strings.HasPrefix(p, SinkBaseURL) { - p = p[len(SinkBaseURL):] + if pos := strings.Index(p, SinkBaseURL); pos > -1 { + p = p[pos+len(SinkBaseURL):] } - return "/" + strings.TrimLeft(p, "/") + return "/" + strings.Trim(p, "/") } return "" @@ -187,16 +188,20 @@ func (svc sink) handleRequest(r *http.Request) (*SinkRequestUrlParams, error) { signatureFoundInPath bool param string + + // this value is modified if signature is found in a path + reqPath = r.URL.Path ) // try to find a signature if _, has := qs[SinkSignUrlParamName]; has { // first, in a query string param = r.URL.Query().Get(SinkSignUrlParamName) - } else if i := strings.Index(r.URL.Path, SinkSignUrlParamName); i > -1 { + } else if i := strings.Index(reqPath, SinkSignUrlParamName); i > -1 { // fallback to path, expecting signature to be at the end // offset string index by start of signature param name, length of param name, and = char - param = r.URL.Path[i+len(SinkSignUrlParamName)+1:] + param = reqPath[i+len(SinkSignUrlParamName)+1:] + reqPath = reqPath[:i] // this is more for consistency and cleaner tests signatureFoundInPath = true @@ -248,7 +253,8 @@ func (svc sink) handleRequest(r *http.Request) (*SinkRequestUrlParams, error) { } if srup.Path != "" { - if srup.Path != svc.pathCleanup(r.URL.Path) { + if srup.Path != svc.pathCleanup(reqPath) { + spew.Dump(srup.Path, reqPath, svc.pathCleanup(reqPath)) return nil, SinkErrInvalidPath(sap) } } diff --git a/system/service/sink_test.go b/system/service/sink_test.go index ad083b49d..e9cc9cd17 100644 --- a/system/service/sink_test.go +++ b/system/service/sink_test.go @@ -98,9 +98,12 @@ func Test_sink_handleRequest(t *testing.T) { signParamsExp = SinkRequestUrlParams{Expires: &time.Time{}} signedUrlExp, _, _ = svc.SignURL(signParamsExp) - signParamsInPath = SinkRequestUrlParams{SignatureInPath: true} + signParamsInPath = SinkRequestUrlParams{SignatureInPath: true, Path: "/foo"} signedUrlInPath, _, _ = svc.SignURL(signParamsInPath) + signParamsInPathNoPath = SinkRequestUrlParams{SignatureInPath: true} + signedUrlInPathNoPath, _, _ = svc.SignURL(signParamsInPathNoPath) + signParamsFixedPath = SinkRequestUrlParams{Path: "/foo/bar"} signedUrlFixedPath, _, _ = svc.SignURL(signParamsFixedPath) ) @@ -178,7 +181,12 @@ func Test_sink_handleRequest(t *testing.T) { wantErr: SinkErrContentLengthExceedsMaxAllowedSize(), }, { - name: "signature in a path", + name: "signature in a path (no path constraint)", + withURL: signedUrlInPathNoPath.String(), + wantParams: &signParamsInPathNoPath, + }, + { + name: "signature in a path (with path constraint)", withURL: signedUrlInPath.String(), wantParams: &signParamsInPath, },