diff options
author | Aliaksandr Valialkin <valyala@gmail.com> | 2016-06-07 13:29:51 +0300 |
---|---|---|
committer | Aliaksandr Valialkin <valyala@gmail.com> | 2016-06-07 13:30:03 +0300 |
commit | 033bb40f06c5c88ffa4f12c26b4eb3d8a15403b0 (patch) | |
tree | 8fc77756b5892a2ddbbfd85c5bf86d8f1ef33bf5 /uri.go | |
parent | Limit the number of concurrently running request handlers inside TimeoutHandler (diff) | |
download | fasthttp-033bb40f06c5c88ffa4f12c26b4eb3d8a15403b0.tar.gz fasthttp-033bb40f06c5c88ffa4f12c26b4eb3d8a15403b0.tar.bz2 fasthttp-033bb40f06c5c88ffa4f12c26b4eb3d8a15403b0.zip |
Properly handle hashes and single dots in URI.Update (see https://github.com/kataras/iris/issues/173)
Diffstat (limited to 'uri.go')
-rw-r--r-- | uri.go | 57 |
1 files changed, 31 insertions, 26 deletions
@@ -286,9 +286,20 @@ func normalizePath(dst, src []byte) []byte { } dst = dst[:bSize] - // remove /foo/../ parts + // remove /./ parts b = dst for { + n := bytes.Index(b, strSlashDotSlash) + if n < 0 { + break + } + nn := n + len(strSlashDotSlash) - 1 + copy(b[n:], b[nn:]) + b = b[:len(b)-nn+n] + } + + // remove /foo/../ parts + for { n := bytes.Index(b, strSlashDotDotSlash) if n < 0 { break @@ -302,17 +313,6 @@ func normalizePath(dst, src []byte) []byte { b = b[:len(b)-n+nn] } - // remove /./ parts - for { - n := bytes.Index(b, strSlashDotSlash) - if n < 0 { - break - } - nn := n + len(strSlashDotSlash) - 1 - copy(b[n:], b[nn:]) - b = b[:len(b)-nn+n] - } - // remove trailing /foo/.. n := bytes.LastIndex(b, strSlashDotDot) if n >= 0 && n+len(strSlashDotDot) == len(b) { @@ -371,8 +371,7 @@ func (u *URI) LastPathSegment() []byte { // * Relative path, i.e. xx?yy=abc . In this case the original RequestURI // is updated according to the new relative path. func (u *URI) Update(newURI string) { - u.fullURI = append(u.fullURI[:0], newURI...) - u.UpdateBytes(u.fullURI) + u.UpdateBytes(s2b(newURI)) } // UpdateBytes updates uri. @@ -409,22 +408,28 @@ func (u *URI) updateBytes(newURI, buf []byte) []byte { } // relative path - if newURI[0] == '?' { + switch newURI[0] { + case '?': // query string only update u.SetQueryStringBytes(newURI[1:]) + return append(buf[:0], u.FullURI()...) + case '#': + // update only hash + u.SetHashBytes(newURI[1:]) + return append(buf[:0], u.FullURI()...) + default: + // update the last path part after the slash + path := u.Path() + n = bytes.LastIndexByte(path, '/') + if n < 0 { + panic("BUG: path must contain at least one slash") + } + buf = u.appendSchemeHost(buf[:0]) + buf = appendQuotedPath(buf, path[:n+1]) + buf = append(buf, newURI...) + u.Parse(nil, buf) return buf } - - path := u.Path() - n = bytes.LastIndexByte(path, '/') - if n < 0 { - panic("BUG: path must contain at least one slash") - } - buf = u.appendSchemeHost(buf[:0]) - buf = appendQuotedPath(buf, path[:n+1]) - buf = append(buf, newURI...) - u.Parse(nil, buf) - return buf } // FullURI returns full uri in the form {Scheme}://{Host}{RequestURI}#{Hash}. |