Skip to content

Commit 7b583fd

Browse files
callthingsoffjba
authored andcommitted
net/http: allow multiple spaces between method and path in mux patterns
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]>
1 parent 5225da7 commit 7b583fd

File tree

4 files changed

+25
-3
lines changed

4 files changed

+25
-3
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The patterns used by [`net/http.ServeMux`](//net/http#ServeMux) allow
2+
multiple spaces matching regexp '[ \t]+'.

‎src/net/http/pattern.go‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ type segment struct {
7676
// a literal or a wildcard of the form "{name}", "{name...}", or "{$}".
7777
//
7878
// METHOD, HOST and PATH are all optional; that is, the string can be "/".
79-
// If METHOD is present, it must be followed by a single space.
79+
// If METHOD is present, it must be followed by at least one space or tab.
8080
// Wildcard names must be valid Go identifiers.
8181
// The "{$}" and "{name...}" wildcard must occur at the end of PATH.
8282
// PATH may end with a '/'.
@@ -92,7 +92,10 @@ func parsePattern(s string) (_ *pattern, err error) {
9292
}
9393
}()
9494

95-
method, rest, found := strings.Cut(s, " ")
95+
method, rest, found := s, "", false
96+
if i := strings.IndexAny(s, " \t"); i >= 0 {
97+
method, rest, found = s[:i], strings.TrimLeft(s[i+1:], " \t"), true
98+
}
9699
if !found {
97100
rest = method
98101
method = ""

‎src/net/http/pattern_test.go‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,23 @@ func TestParsePattern(t *testing.T) {
9898
"/%61%62/%7b/%",
9999
pattern{segments: []segment{lit("ab"), lit("{"), lit("%")}},
100100
},
101+
// Allow multiple spaces matching regexp '[ \t]+' between method and path.
102+
{
103+
"GET\t /",
104+
pattern{method: "GET", segments: []segment{multi("")}},
105+
},
106+
{
107+
"POST \t example.com/foo/{w}",
108+
pattern{
109+
method: "POST",
110+
host: "example.com",
111+
segments: []segment{lit("foo"), wild("w")},
112+
},
113+
},
114+
{
115+
"DELETE \texample.com/a/{foo12}/{$}",
116+
pattern{method: "DELETE", host: "example.com", segments: []segment{lit("a"), wild("foo12"), lit("/")}},
117+
},
101118
} {
102119
got := mustParsePattern(t, test.in)
103120
if !got.equal(&test.want) {

‎src/net/http/server.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2335,7 +2335,7 @@ func RedirectHandler(url string, code int) Handler {
23352335
// [METHOD ][HOST]/[PATH]
23362336
//
23372337
// All three parts are optional; "/" is a valid pattern.
2338-
// If METHOD is present, it must be followed by a single space.
2338+
// If METHOD is present, it must be followed by at least one space or tab.
23392339
//
23402340
// Literal (that is, non-wildcard) parts of a pattern match
23412341
// the corresponding parts of a request case-sensitively.

0 commit comments

Comments
 (0)