Documentation
¶
Overview ¶
Package wiretarget spells the path the router matched the way a request line carries it, for middleware that hands the request on to something that reads request lines: a proxy upstream, a net/http handler.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func HasForgedEscape ¶
HasForgedEscape reports whether target's path holds an escape of an unreserved character (RFC 3986 Section 2.3: a letter, a digit, "-", ".", "_" or "~"). The router decodes every such escape when it normalizes a path, so one still in c.Path() was forged by a stray "%" lining up with the escape after it: "/%%32e" reaches the router as "/%2e". A reader that decodes the path once more then sees a character the router never matched, "%2e%2e" becoming a ".." segment or "%70rivate" becoming "private". Under UnescapePath the routed path is escaped again segment by segment, which never escapes an unreserved character, so nothing is reported there.
func ParsesAsPath ¶
ParsesAsPath reports whether fasthttp reads target as a path when it is set as the request line of a request whose Host header is host. It is false for a target without a leading slash, which a request line reads as an absolute URL or an authority, for one that begins with "//" and holds "://", and for one that begins with "//" on a request without a Host header: fasthttp then reads the target as "[scheme:]//authority/path" and takes the request's host, and a Basic credential, from the authority, over the ones the application set. The router never sees such a target as an authority, and it need not have arrived as one: ".." resolution builds "//u:pw@evil.example/a://b" out of "//u:pw@evil.example/a:/x/..//b", and under UnescapePath a decoded "%3A%2F%2F" spells the "://".
func Routed ¶
Routed returns the request target to hand on for c: the path the router matched, spelled as a request line has to carry it, then the query.
Under the default configuration c.Path() is nearly that spelling already: escapes of unreserved characters decoded, every other escape kept, dot segments resolved and empty segments kept. What it may still hold raw is written as an escape, the valid spelling of the same name: a stray "%" that begins no escape as "%25", and every byte RFC 3986 does not allow raw in a path, such as a space, "\", "|", "{", "}", '"', "^", "<", ">", a control byte or a byte of UTF-8, as its escape, as fasthttp's normalizing writer did before. Under UnescapePath c.Path() is fully decoded, so it is escaped again segment by segment, and a "/" that came from "%2F" stays the separator the router took it for.
The raw request line is deliberately not the source. fasthttp's own normalization of it decodes "%2F" into a separator, merges "//" and then resolves "..", so "/public/..%2Fadmin" and "//admin" reached a proxy upstream or a net/http handler as "/admin" although no middleware mounted on "/admin" had run for them. The routed path keeps them the distinct names the router matched.
The query is the one the client sent, even after a handler read it through c.Query(): fasthttp would serialize parsed arguments again, "%20" as "+" and ";" as "%3B", and a signed URL would no longer verify. Only when a handler changed the arguments through QueryArgs() are they forwarded as fasthttp serializes them, since that is the change it made.
The target may be the request line itself, a view of it rather than a copy, when that already spells the routed path, so read it before the request line is set to something else.
The target always begins with a slash. A path override that dropped it, a rewrite of "/go/*" to "$1" say, would otherwise hand on "http://u:pw@evil.example/x", which a request line reads as an absolute URL and so as a host and a credential; rooted, it is the path "/http://u:pw@evil.example/x".
func SegmentsAsRouted ¶
SegmentsAsRouted reports whether a reader that decodes target's path and cleans it still sees the segments the router matched. It is false when the path holds an empty segment, an escaped slash or a forged escape (see HasForgedEscape): net/http's URL.Path reads "%2F" as a separator and a forged "%2e%2e" as "..", and its handlers clean "//" and ".." away, so "/public/..%2Fadmin", "//admin" and "/public/%2e%2e/admin" would be served as "/admin" by a handler no middleware mounted on "/admin" guarded. A proxied upstream that decodes "%2F" or merges "//" before it matches routes reads a target the same way, so the proxy handlers refuse one for which this is false, as the net/http handler adapters do.
It is false as well for a backslash, raw or escaped as "%5C", which WHATWG URL parsers and IIS read as a separator, and for a "." or ".." segment that carries path parameters, such as "..;x", which servlet containers such as Tomcat and Jetty resolve as a dot segment once they strip the parameters: "/public/..;/admin" is "/admin" there.
func SegmentsAsRoutedSlashesAside ¶
SegmentsAsRoutedSlashesAside is SegmentsAsRouted without its objection to an escaped slash and an empty segment, for a caller that was told the reader keeps those as sent. A backslash, a forged escape and a dot segment carrying parameters are still refused.
func SurvivesNormalization ¶
SurvivesNormalization reports whether fasthttp's path normalization would leave target's path naming what it names. Normalization merges every empty segment, decodes every escape and writes the path again with only some bytes escaped, so "//" and an escape that does not come back (see escapeSurvives) leave a normalizing client as a path the router never matched: "/public/..%2Fadmin" as "/admin" and "/..%3B/" as "/..;/". Any other escape, such as the "%C3%A9" Routed writes for "é", comes out as it went in, up to the case of its hex digits. The client also escapes a raw "!", "'", "(", ")" or "*", which changes the spelling but cannot add a separator.
Types ¶
This section is empty.