From ee8450036eb75d30d45d58a7c8aeff41b881d7cc Mon Sep 17 00:00:00 2001 From: Daniel Firsht Date: Tue, 17 Sep 2019 23:56:18 -0700 Subject: [PATCH] Added option to disable path normalization (#649) --- uri.go | 18 +++++++++++++++++- uri_test.go | 10 ++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/uri.go b/uri.go index e9cd4b1..913c86b 100644 --- a/uri.go +++ b/uri.go @@ -48,6 +48,15 @@ type URI struct { queryArgs Args parsedQueryArgs bool + // Path values are sent as-is without normalization + // + // Disabled path normalization may be useful for proxying incoming requests + // to servers that are expecting paths to be forwarded as-is. + // + // By default path values are normalized, i.e. + // extra slashes are removed, special characters are encoded. + DisablePathNormalizing bool + fullURI []byte requestURI []byte @@ -71,6 +80,7 @@ func (u *URI) CopyTo(dst *URI) { u.queryArgs.CopyTo(&dst.queryArgs) dst.parsedQueryArgs = u.parsedQueryArgs + dst.DisablePathNormalizing = u.DisablePathNormalizing // fullURI and requestURI shouldn't be copied, since they are created // from scratch on each FullURI() and RequestURI() call. @@ -215,6 +225,7 @@ func (u *URI) Reset() { u.host = u.host[:0] u.queryArgs.Reset() u.parsedQueryArgs = false + u.DisablePathNormalizing = false // There is no need in u.fullURI = u.fullURI[:0], since full uri // is calculated on each call to FullURI(). @@ -387,7 +398,12 @@ func normalizePath(dst, src []byte) []byte { // RequestURI returns RequestURI - i.e. URI without Scheme and Host. func (u *URI) RequestURI() []byte { - dst := appendQuotedPath(u.requestURI[:0], u.Path()) + var dst []byte + if u.DisablePathNormalizing { + dst = append(u.requestURI[:0], u.PathOriginal()...) + } else { + dst = appendQuotedPath(u.requestURI[:0], u.Path()) + } if u.queryArgs.Len() > 0 { dst = append(dst, '?') dst = u.queryArgs.AppendBytes(dst) diff --git a/uri_test.go b/uri_test.go index 7ed05f9..84f9380 100644 --- a/uri_test.go +++ b/uri_test.go @@ -184,6 +184,16 @@ func testURIPathNormalize(t *testing.T, u *URI, requestURI, expectedPath string) } } +func TestURINoNormalization(t *testing.T) { + var u URI + irregularPath := "/aaa%2Fbbb%2F%2E.%2Fxxx" + u.Parse(nil, []byte(irregularPath)) + u.DisablePathNormalizing = true + if string(u.RequestURI()) != irregularPath { + t.Fatalf("Unexpected path %q. Expected %q.", u.Path(), irregularPath) + } +} + func TestURICopyTo(t *testing.T) { var u URI var copyU URI