Documentation
¶
Overview ¶
Package parseurl parses the URL of an incoming HTTP request into its components, a stdlib-only Go port of the npm package "parseurl" (https://www.npmjs.com/package/parseurl). In the Node/Express world parseurl is the tiny utility that turns a request's raw target string (req.url) into a structured URL object with fields such as path, query and pathname, and it underpins routing, static file serving and any middleware that needs to reason about the request path independently of the query string.
The reason parseurl exists at all in Node is performance and correctness of caching. Parsing a URL is not free, and a single request typically has its URL inspected by many layers of middleware, so the original library memoizes the parsed result on the request object and reparses only when the underlying req.url string has changed. It also distinguishes the current URL (which Express may rewrite as it strips mounted route prefixes) from the original, unmodified request target, exposing the latter through parseurl.original.
This Go port maps those two concepts onto net/http and net/url. Parse returns the request's effective URL as a *url.URL, and OriginalURL returns the original request target; both read from req.RequestURI, the raw target line as received, and fall back to the request's already-parsed req.URL field when RequestURI is empty or unparseable. A nil request yields a nil result rather than panicking, mirroring parseurl's tolerance of a missing url. ParseString is a thin convenience wrapper over url.Parse for parsing an arbitrary URL string directly.
Because Go's http.Request already carries a parsed URL and an immutable RequestURI, this port does not need parseurl's memoization machinery: parsing RequestURI with net/url is cheap and the raw target does not mutate underneath you the way req.url can in Express, so each call simply parses afresh and no per-request cache is stored. Parse first tries url.ParseRequestURI, which is the correct strict parser for an HTTP request target, and only falls back to the more lenient url.Parse (and finally to req.URL) if that fails, so well-formed absolute paths and absolute-form targets are both handled.
The resulting *url.URL exposes the same information the Node object does, just under Go's field names: Path holds the decoded path, EscapedPath preserves the original percent-encoding, and RawQuery (or the parsed Query map) holds the query string. Parity with Node is therefore behavioral rather than literal — you get the request's path and query parsed the way net/url parses them, with the original request target available separately — which is exactly what the downstream routing and static-serving ports in this module consume.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func OriginalURL ¶
OriginalURL parses the request's original URL. Like Parse, it uses req.RequestURI as the source of the original, unmodified request target.
func Parse ¶
Parse parses the request's effective URL, using req.RequestURI and falling back to req.URL when RequestURI is empty or cannot be parsed. It returns nil when req is nil.
Example ¶
ExampleParse builds an HTTP request with a path and query string and parses its effective URL into structured components. Parse reads the request's raw target and returns a *url.URL, from which the decoded path and the raw query string can be read directly. The query can also be decoded into individual parameters via the returned URL's Query method. This mirrors how Node's parseurl turns req.url into a structured object for routing and middleware.
package main
import (
"fmt"
"net/http/httptest"
"github.com/malcolmston/express/parseurl"
)
func main() {
req := httptest.NewRequest("GET", "/foo/bar?baz=1&qux=2", nil)
u := parseurl.Parse(req)
fmt.Println("path:", u.Path)
fmt.Println("query:", u.RawQuery)
fmt.Println("baz:", u.Query().Get("baz"))
}
Output: path: /foo/bar query: baz=1&qux=2 baz: 1
Example (Encoded) ¶
ExampleParse_encoded shows that percent-encoded path segments are handled correctly. The request target contains a space encoded as %20 in both the path and a query value. Parse returns a URL whose Path field holds the decoded value while EscapedPath preserves the original encoding. This lets callers compare against decoded paths yet still reconstruct the exact on-the-wire form when needed.
package main
import (
"fmt"
"net/http/httptest"
"github.com/malcolmston/express/parseurl"
)
func main() {
req := httptest.NewRequest("GET", "/foo%20bar?a=b%20c", nil)
u := parseurl.Parse(req)
fmt.Println("decoded path:", u.Path)
fmt.Println("escaped path:", u.EscapedPath())
}
Output: decoded path: /foo bar escaped path: /foo%20bar
func ParseString ¶
ParseString parses a raw URL string into a *url.URL.
Example ¶
ExampleParseString parses an arbitrary absolute URL string directly, without needing an *http.Request. It is a thin convenience wrapper over the standard library's url.Parse. The returned URL exposes the host, path and query as separate fields. This is handy when you already hold a URL string rather than a request, for example when parsing a configured upstream target.
package main
import (
"fmt"
"github.com/malcolmston/express/parseurl"
)
func main() {
u, err := parseurl.ParseString("http://example.com/a/b?c=d")
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println("host:", u.Host)
fmt.Println("path:", u.Path)
fmt.Println("query:", u.RawQuery)
}
Output: host: example.com path: /a/b query: c=d
Types ¶
This section is empty.