diff options
| author | Jonathan Amsterdam <jba@google.com> | 2023-09-13 16:58:24 -0400 |
|---|---|---|
| committer | Jonathan Amsterdam <jba@google.com> | 2023-09-14 00:00:28 +0000 |
| commit | 495830acd6976c8a2b39dd4aa4fdc105ad72de52 (patch) | |
| tree | a44f8bcbd8d75e67e2cd3ce5c607a6cbacde1616 /src/net/http/request.go | |
| parent | fccd0b9b70255099691deca5dc1d577efcfc889b (diff) | |
| download | go-495830acd6976c8a2b39dd4aa4fdc105ad72de52.tar.xz | |
net/http: implement path value methods on Request
Add Request.PathValue and Request.SetPathValue,
and the fields on Request required to support them.
Populate those fields in ServeMux.ServeHTTP.
Updates #61410.
Change-Id: Ic88cb865b0d865a30d3b35ece8e0382c58ef67d1
Reviewed-on: https://go-review.googlesource.com/c/go/+/528355
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/net/http/request.go')
| -rw-r--r-- | src/net/http/request.go | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/net/http/request.go b/src/net/http/request.go index 12039c9ae2..b66e6853f6 100644 --- a/src/net/http/request.go +++ b/src/net/http/request.go @@ -329,6 +329,11 @@ type Request struct { // It is unexported to prevent people from using Context wrong // and mutating the contexts held by callers of the same request. ctx context.Context + + // The following fields are for requests matched by ServeMux. + pat *pattern // the pattern that matched + matches []string // values for the matching wildcards in pat + otherValues map[string]string // for calls to SetPathValue that don't match a wildcard } // Context returns the request's context. To change the context, use @@ -1415,6 +1420,48 @@ func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, e return nil, nil, ErrMissingFile } +// PathValue returns the value for the named path wildcard in the ServeMux pattern +// that matched the request. +// It returns the empty string if the request was not matched against a pattern +// or there is no such wildcard in the pattern. +func (r *Request) PathValue(name string) string { + if i := r.patIndex(name); i >= 0 { + return r.matches[i] + } + return r.otherValues[name] +} + +func (r *Request) SetPathValue(name, value string) { + if i := r.patIndex(name); i >= 0 { + r.matches[i] = value + } else { + if r.otherValues == nil { + r.otherValues = map[string]string{} + } + r.otherValues[name] = value + } +} + +// patIndex returns the index of name in the list of named wildcards of the +// request's pattern, or -1 if there is no such name. +func (r *Request) patIndex(name string) int { + // The linear search seems expensive compared to a map, but just creating the map + // takes a lot of time, and most patterns will just have a couple of wildcards. + if r.pat == nil { + return -1 + } + i := 0 + for _, seg := range r.pat.segments { + if seg.wild && seg.s != "" { + if name == seg.s { + return i + } + i++ + } + } + return -1 +} + func (r *Request) expectsContinue() bool { return hasToken(r.Header.get("Expect"), "100-continue") } |
