-
-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathparams_writer.go
129 lines (110 loc) · 3.8 KB
/
params_writer.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package muxie
import (
"net/http"
)
// GetParam returns the path parameter value based on its key, i.e
// "/hello/:name", the parameter key is the "name".
// For example if a route with pattern of "/hello/:name" is inserted to the `Trie` or handlded by the `Mux`
// and the path "/hello/kataras" is requested through the `Mux#ServeHTTP -> Trie#Search`
// then the `GetParam("name")` will return the value of "kataras".
// If not associated value with that key is found then it will return an empty string.
//
// The function will do its job only if the given "w" http.ResponseWriter interface is an `ResponseWriter`.
func GetParam(w http.ResponseWriter, key string) string {
if store, ok := w.(ResponseWriter); ok {
return store.Get(key)
}
return ""
}
// GetParams returns all the available parameters based on the "w" http.ResponseWriter which should be a ResponseWriter.
//
// The function will do its job only if the given "w" http.ResponseWriter interface is an `ResponseWriter`.
func GetParams(w http.ResponseWriter) []ParamEntry {
if store, ok := w.(ResponseWriter); ok {
return store.GetAll()
}
return nil
}
// SetParam sets manually a parameter to the "w" http.ResponseWriter which should be a ResponseWriter.
// This is not commonly used by the end-developers,
// unless sharing values(string messages only) between handlers is absolutely necessary.
func SetParam(w http.ResponseWriter, key, value string) bool {
if store, ok := w.(ResponseWriter); ok {
store.Set(key, value)
return true
}
return false
}
// ParamEntry holds the Key and the Value of a named path parameter.
type ParamEntry struct {
Key string
Value string
}
// ResponseWriter is the muxie's specific ResponseWriter to hold the path parameters.
// Usage: use this to cast a handler's `http.ResponseWriter` and pass it as an embedded parameter to custom response writer
// that will be passed to the next handler in the chain.
type ResponseWriter interface {
http.ResponseWriter
ParamsSetter
Get(string) string
GetAll() []ParamEntry
}
type paramsWriter struct {
http.ResponseWriter
params []ParamEntry
}
var _ ResponseWriter = (*paramsWriter)(nil)
// Set implements the `ParamsSetter` which `Trie#Search` needs to store the parameters, if any.
// These are decoupled because end-developers may want to use the trie to design a new Mux of their own
// or to store different kind of data inside it.
func (pw *paramsWriter) Set(key, value string) {
if ln := len(pw.params); cap(pw.params) > ln {
pw.params = pw.params[:ln+1]
p := &pw.params[ln]
p.Key = key
p.Value = value
return
}
pw.params = append(pw.params, ParamEntry{
Key: key,
Value: value,
})
}
// Get returns the value of the associated parameter based on its key/name.
func (pw *paramsWriter) Get(key string) string {
n := len(pw.params)
for i := 0; i < n; i++ {
if kv := pw.params[i]; kv.Key == key {
return kv.Value
}
}
return ""
}
// GetAll returns all the path parameters keys-values.
func (pw *paramsWriter) GetAll() []ParamEntry {
return pw.params
}
func (pw *paramsWriter) reset(w http.ResponseWriter) {
pw.ResponseWriter = w
pw.params = pw.params[0:0]
}
// Flusher indicates if `Flush` is supported by the client.
//
// The default HTTP/1.x and HTTP/2 ResponseWriter implementations
// support Flusher, but ResponseWriter wrappers may not. Handlers
// should always test for this ability at runtime.
//
// Note that even for ResponseWriters that support Flush,
// if the client is connected through an HTTP proxy,
// the buffered data may not reach the client until the response
// completes.
func (pw *paramsWriter) Flusher() (http.Flusher, bool) {
flusher, canFlush := pw.ResponseWriter.(http.Flusher)
return flusher, canFlush
}
// Flush sends any buffered data to the client.
func (pw *paramsWriter) Flush() {
if flusher, ok := pw.Flusher(); ok {
flusher.Flush()
}
}