@@ -2306,44 +2306,123 @@ func RedirectHandler(url string, code int) Handler {
2306
2306
return & redirectHandler {url , code }
2307
2307
}
2308
2308
2309
- // TODO(jba): rewrite the following doc for enhanced patterns (proposal
2310
- // https://go.dev/issue/61410).
2311
-
2312
2309
// ServeMux is an HTTP request multiplexer.
2313
2310
// It matches the URL of each incoming request against a list of registered
2314
2311
// patterns and calls the handler for the pattern that
2315
2312
// most closely matches the URL.
2316
2313
//
2317
- // Patterns name fixed, rooted paths, like "/favicon.ico",
2318
- // or rooted subtrees, like "/images/" (note the trailing slash).
2319
- // Longer patterns take precedence over shorter ones, so that
2320
- // if there are handlers registered for both "/images/"
2321
- // and "/images/thumbnails/", the latter handler will be
2322
- // called for paths beginning with "/images/thumbnails/" and the
2323
- // former will receive requests for any other paths in the
2324
- // "/images/" subtree.
2325
- //
2326
- // Note that since a pattern ending in a slash names a rooted subtree,
2327
- // the pattern "/" matches all paths not matched by other registered
2328
- // patterns, not just the URL with Path == "/".
2329
- //
2330
- // If a subtree has been registered and a request is received naming the
2331
- // subtree root without its trailing slash, ServeMux redirects that
2332
- // request to the subtree root (adding the trailing slash). This behavior can
2333
- // be overridden with a separate registration for the path without
2334
- // the trailing slash. For example, registering "/images/" causes ServeMux
2314
+ // # Patterns
2315
+ //
2316
+ // Patterns can match the method, host and path of a request.
2317
+ // Some examples:
2318
+ //
2319
+ // - "/index.html" matches the path "/index.html" for any host and method.
2320
+ // - "GET /static/" matches a GET request whose path begins with "/static/".
2321
+ // - "example.com/" matches any request to the host "example.com".
2322
+ // - "example.com/{$}" matches requests with host "example.com" and path "/".
2323
+ // - "/b/{bucket}/o/{objectname...}" matches paths whose first segment is "b"
2324
+ // and whose third segment is "o". The name "bucket" denotes the second
2325
+ // segment and "objectname" denotes the remainder of the path.
2326
+ //
2327
+ // In general, a pattern looks like
2328
+ //
2329
+ // [METHOD ][HOST]/[PATH]
2330
+ //
2331
+ // All three parts are optional; "/" is a valid pattern.
2332
+ // If METHOD is present, it must be followed by a single space.
2333
+ //
2334
+ // Literal (that is, non-wildcard) parts of a pattern match
2335
+ // the corresponding parts of a request case-sensitively.
2336
+ //
2337
+ // A pattern with no method matches every method. A pattern
2338
+ // with the method GET matches both GET and HEAD requests.
2339
+ // Otherwise, the method must match exactly.
2340
+ //
2341
+ // A pattern with no host matches every host.
2342
+ // A pattern with a host matches URLs on that host only.
2343
+ //
2344
+ // A path can include wildcard segments of the form {NAME} or {NAME...}.
2345
+ // For example, "/b/{bucket}/o/{objectname...}".
2346
+ // The wildcard name must be a valid Go identifier.
2347
+ // Wildcards must be full path segments: they must be preceded by a slash and followed by
2348
+ // either a slash or the end of the string.
2349
+ // For example, "/b_{bucket}" is not a valid pattern.
2350
+ //
2351
+ // Normally a wildcard matches only a single path segment,
2352
+ // ending at the next literal slash (not %2F) in the request URL.
2353
+ // But if the "..." is present, then the wildcard matches the remainder of the URL path, including slashes.
2354
+ // (Therefore it is invalid for a "..." wildcard to appear anywhere but at the end of a pattern.)
2355
+ // The match for a wildcard can be obtained by calling [Request.PathValue] with the wildcard's name.
2356
+ // A trailing slash in a path acts as an anonymous "..." wildcard.
2357
+ //
2358
+ // The special wildcard {$} matches only the end of the URL.
2359
+ // For example, the pattern "/{$}" matches only the path "/",
2360
+ // whereas the pattern "/" matches every path.
2361
+ //
2362
+ // For matching, both pattern paths and incoming request paths are unescaped segment by segment.
2363
+ // So, for example, the path "/a%2Fb/100%25" is treated as having two segments, "a/b" and "100%".
2364
+ // The pattern "/a%2fb/" matches it, but the pattern "/a/b/" does not.
2365
+ //
2366
+ // # Precedence
2367
+ //
2368
+ // If two or more patterns match a request, then the most specific pattern takes precedence.
2369
+ // A pattern P1 is more specific than P2 if P1 matches a strict subset of P2’s requests;
2370
+ // that is, if P2 matches all the requests of P1 and more.
2371
+ // If neither is more specific, then the patterns conflict.
2372
+ // There is one exception to this rule, for backwards compatibility:
2373
+ // if two patterns would otherwise conflict and one has a host while the other does not,
2374
+ // then the pattern with the host takes precedence.
2375
+ // If a pattern passed [ServeMux.Handle] or [ServeMux.HandleFunc] conflicts with
2376
+ // another pattern that is already registered, those functions panic.
2377
+ //
2378
+ // As an example of the general rule, "/images/thumbnails/" is more specific than "/images/",
2379
+ // so both can be registered.
2380
+ // The former matches paths beginning with "/images/thumbnails/"
2381
+ // and the latter will match any other path in the "/images/" subtree.
2382
+ //
2383
+ // As another example, consider the patterns "GET /" and "/index.html":
2384
+ // both match a GET request for "/index.html", but the former pattern
2385
+ // matches all other GET and HEAD requests, while the latter matches any
2386
+ // request for "/index.html" that uses a different method.
2387
+ // The patterns conflict.
2388
+ //
2389
+ // # Trailing-slash redirection
2390
+ //
2391
+ // Consider a ServeMux with a handler for a subtree, registered using a trailing slash or "..." wildcard.
2392
+ // If the ServeMux receives a request for the subtree root without a trailing slash,
2393
+ // it redirects the request by adding the trailing slash.
2394
+ // This behavior can be overridden with a separate registration for the path without
2395
+ // the trailing slash or "..." wildcard. For example, registering "/images/" causes ServeMux
2335
2396
// to redirect a request for "/images" to "/images/", unless "/images" has
2336
2397
// been registered separately.
2337
2398
//
2338
- // Patterns may optionally begin with a host name, restricting matches to
2339
- // URLs on that host only. Host-specific patterns take precedence over
2340
- // general patterns, so that a handler might register for the two patterns
2341
- // "/codesearch" and "codesearch.google.com/" without also taking over
2342
- // requests for "http://www.google.com/".
2399
+ // # Request sanitizing
2343
2400
//
2344
2401
// ServeMux also takes care of sanitizing the URL request path and the Host
2345
2402
// header, stripping the port number and redirecting any request containing . or
2346
- // .. elements or repeated slashes to an equivalent, cleaner URL.
2403
+ // .. segments or repeated slashes to an equivalent, cleaner URL.
2404
+ //
2405
+ // # Compatibility
2406
+ //
2407
+ // The pattern syntax and matching behavior of ServeMux changed significantly
2408
+ // in Go 1.22. To restore the old behavior, set the GODEBUG environment variable
2409
+ // to "httpmuxgo121=1". This setting is read once, at program startup; changes
2410
+ // during execution will be ignored.
2411
+ //
2412
+ // The backwards-incompatible changes include:
2413
+ // - Wildcards are just ordinary literal path segments in 1.21.
2414
+ // For example, the pattern "/{x}" will match only that path in 1.21,
2415
+ // but will match any one-segment path in 1.22.
2416
+ // - In 1.21, no pattern was rejected, unless it was empty or conflicted with an existing pattern.
2417
+ // In 1.22, syntactically invalid patterns will cause [ServeMux.Handle] and [ServeMux.HandleFunc] to panic.
2418
+ // For example, in 1.21, the patterns "/{" and "/a{x}" match themselves,
2419
+ // but in 1.22 they are invalid and will cause a panic when registered.
2420
+ // - In 1.22, each segment of a pattern is unescaped; this was not done in 1.21.
2421
+ // For example, in 1.22 the pattern "/%61" matches the path "/a" ("%61" being the URL escape sequence for "a"),
2422
+ // but in 1.21 it would match only the path "/%2561" (where "%25" is the escape for the percent sign).
2423
+ // - When matching patterns to paths, in 1.22 each segment of the path is unescaped; in 1.21, the entire path is unescaped.
2424
+ // This change mostly affects how paths with %2F escapes adjacent to slashes are treated.
2425
+ // See https://go.dev/issue/21955 for details.
2347
2426
type ServeMux struct {
2348
2427
mu sync.RWMutex
2349
2428
tree routingNode
@@ -2570,7 +2649,7 @@ func (mux *ServeMux) matchingMethods(host, path string) []string {
2570
2649
return methods
2571
2650
}
2572
2651
2573
- // TODO: replace with maps.Keys when it is defined.
2652
+ // TODO(jba) : replace with maps.Keys when it is defined.
2574
2653
func mapKeys [K comparable , V any ](m map [K ]V ) []K {
2575
2654
var ks []K
2576
2655
for k := range m {
@@ -2598,11 +2677,12 @@ func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
2598
2677
h .ServeHTTP (w , r )
2599
2678
}
2600
2679
2601
- // The four functions below all call register so that callerLocation
2680
+ // The four functions below all call ServeMux. register so that callerLocation
2602
2681
// always refers to user code.
2603
2682
2604
2683
// Handle registers the handler for the given pattern.
2605
- // If a handler already exists for pattern, Handle panics.
2684
+ // If the given pattern conflicts, with one that is already registered, Handle
2685
+ // panics.
2606
2686
func (mux * ServeMux ) Handle (pattern string , handler Handler ) {
2607
2687
if use121 {
2608
2688
mux .mux121 .handle (pattern , handler )
@@ -2611,6 +2691,8 @@ func (mux *ServeMux) Handle(pattern string, handler Handler) {
2611
2691
}
2612
2692
2613
2693
// HandleFunc registers the handler function for the given pattern.
2694
+ // If the given pattern conflicts, with one that is already registered, HandleFunc
2695
+ // panics.
2614
2696
func (mux * ServeMux ) HandleFunc (pattern string , handler func (ResponseWriter , * Request )) {
2615
2697
if use121 {
2616
2698
mux .mux121 .handleFunc (pattern , handler )
0 commit comments