Skip to content

Commit

Permalink
net/http: allow multiple spaces between method and path in mux patterns
Browse files Browse the repository at this point in the history
Fixes #64910

Change-Id: I14fd1e35c95b14591e3ad7b889dc1ab19a008730
GitHub-Last-Rev: b8d436c
GitHub-Pull-Request: #65868
Reviewed-on: https://go-review.googlesource.com/c/go/+/565916
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Damien Neil <[email protected]>
Reviewed-by: Jonathan Amsterdam <[email protected]>
  • Loading branch information
callthingsoff authored and jba committed Feb 26, 2024
1 parent 5225da7 commit 7b583fd
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 3 deletions.
2 changes: 2 additions & 0 deletions doc/next/6-stdlib/99-minor/net/http/64910.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The patterns used by [`net/http.ServeMux`](//net/http#ServeMux) allow
multiple spaces matching regexp '[ \t]+'.
7 changes: 5 additions & 2 deletions src/net/http/pattern.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ type segment struct {
// a literal or a wildcard of the form "{name}", "{name...}", or "{$}".
//
// METHOD, HOST and PATH are all optional; that is, the string can be "/".
// If METHOD is present, it must be followed by a single space.
// If METHOD is present, it must be followed by at least one space or tab.
// Wildcard names must be valid Go identifiers.
// The "{$}" and "{name...}" wildcard must occur at the end of PATH.
// PATH may end with a '/'.
Expand All @@ -92,7 +92,10 @@ func parsePattern(s string) (_ *pattern, err error) {
}
}()

method, rest, found := strings.Cut(s, " ")
method, rest, found := s, "", false
if i := strings.IndexAny(s, " \t"); i >= 0 {
method, rest, found = s[:i], strings.TrimLeft(s[i+1:], " \t"), true
}
if !found {
rest = method
method = ""
Expand Down
17 changes: 17 additions & 0 deletions src/net/http/pattern_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,23 @@ func TestParsePattern(t *testing.T) {
"/%61%62/%7b/%",
pattern{segments: []segment{lit("ab"), lit("{"), lit("%")}},
},
// Allow multiple spaces matching regexp '[ \t]+' between method and path.
{
"GET\t /",
pattern{method: "GET", segments: []segment{multi("")}},
},
{
"POST \t example.com/foo/{w}",
pattern{
method: "POST",
host: "example.com",
segments: []segment{lit("foo"), wild("w")},
},
},
{
"DELETE \texample.com/a/{foo12}/{$}",
pattern{method: "DELETE", host: "example.com", segments: []segment{lit("a"), wild("foo12"), lit("/")}},
},
} {
got := mustParsePattern(t, test.in)
if !got.equal(&test.want) {
Expand Down
2 changes: 1 addition & 1 deletion src/net/http/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2335,7 +2335,7 @@ func RedirectHandler(url string, code int) Handler {
// [METHOD ][HOST]/[PATH]
//
// All three parts are optional; "/" is a valid pattern.
// If METHOD is present, it must be followed by a single space.
// If METHOD is present, it must be followed by at least one space or tab.
//
// Literal (that is, non-wildcard) parts of a pattern match
// the corresponding parts of a request case-sensitively.
Expand Down

0 comments on commit 7b583fd

Please sign in to comment.