-
Notifications
You must be signed in to change notification settings - Fork 4
/
r2.go
94 lines (76 loc) · 2.13 KB
/
r2.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
Package r2 implements a minimalist HTTP request routing helper for Go.
*/
package r2
import (
"context"
"net/http"
"time"
)
// Context returns a non-nil [context.Context] that is never canceled and has no
// deadline. It is typically used in the [http.Server.BaseContext] to avoid the
// [Router.Handler] from calling the [http.Request.WithContext], which can
// significantly improve routing performance.
func Context() context.Context {
return &dataContext{d: &data{}}
}
// PathParam returns a path parameter value of the req for the name. It returns
// empty string if not found.
func PathParam(req *http.Request, name string) string {
d, ok := req.Context().Value(dataContextKey).(*data)
if !ok {
return ""
}
for i, ppn := range d.pathParamNames {
if ppn == name {
return d.pathParamValues[i]
}
}
return ""
}
// PathParamNames returns path parameter names of the req. It returns nil if not
// found.
func PathParamNames(req *http.Request) []string {
d, ok := req.Context().Value(dataContextKey).(*data)
if !ok {
return nil
}
return d.pathParamNames
}
// PathParamValues returns path parameter values of the req. It returns nil if
// not found.
func PathParamValues(req *http.Request) []string {
d, ok := req.Context().Value(dataContextKey).(*data)
if !ok {
return nil
}
return d.pathParamValues[:len(d.pathParamNames)]
}
// dataContext is a [context.Context] that wraps a [data].
type dataContext struct {
d *data
}
// Deadline implements the [context.Context].
func (*dataContext) Deadline() (deadline time.Time, ok bool) { return }
// Done implements the [context.Context].
func (*dataContext) Done() <-chan struct{} { return nil }
// Err implements the [context.Context].
func (*dataContext) Err() error { return nil }
// Value implements the [context.Context].
func (dc *dataContext) Value(key interface{}) interface{} {
if key == dataContextKey {
return dc.d
}
return nil
}
// contextKey is a key for a context value.
type contextKey uint8
// The context keys.
const (
dataContextKey contextKey = iota
)
// data is a request-scoped data set.
type data struct {
pathParamNames []string
pathParamValues []string
}