-
Notifications
You must be signed in to change notification settings - Fork 13
/
rye_example.go
160 lines (126 loc) · 4.69 KB
/
rye_example.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package main
import (
"context"
"errors"
"fmt"
"net/http"
"github.com/InVisionApp/rye"
"github.com/cactus/go-statsd-client/statsd"
"github.com/gorilla/mux"
log "github.com/sirupsen/logrus"
)
func main() {
statsdClient, err := statsd.NewBufferedClient("localhost:12345", "my_service", 1.0, 0)
if err != nil {
log.Fatalf("Unable to instantiate statsd client: %v", err.Error())
}
config := rye.Config{
Statter: statsdClient,
StatRate: 1.0,
}
middlewareHandler := rye.NewMWHandler(config)
middlewareHandler.Use(beforeAllHandler)
routes := mux.NewRouter().StrictSlash(true)
routes.Handle("/", middlewareHandler.Handle([]rye.Handler{
middlewareFirstHandler,
homeHandler,
})).Methods("GET")
// If you perform a `curl -i http://localhost:8181/cors -H "Origin: *.foo.com"`
// you will see that the CORS middleware is adding required headers
routes.Handle("/cors", middlewareHandler.Handle([]rye.Handler{
rye.MiddlewareCORS(),
homeHandler,
})).Methods("GET", "OPTIONS")
// If you perform an `curl -i http://localhost:8181/jwt \
// -H "Authorization: Basic dXNlcjE6cGFzczEK"
// you will see that we are allowed through to the handler, if the header is changed, you will get a 401
routes.Handle("/basic-auth", middlewareHandler.Handle([]rye.Handler{
rye.NewMiddlewareAuth(rye.NewBasicAuthFunc(map[string]string{
"user1": "pass1",
"user2": "pass2",
})),
getJwtFromContextHandler,
})).Methods("GET")
// If you perform an `curl -i http://localhost:8181/jwt \
// -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ"
// you will see that we are allowed through to the handler, if the sample token is changed, we will get a 401
routes.Handle("/jwt", middlewareHandler.Handle([]rye.Handler{
rye.NewMiddlewareAuth(rye.NewJWTAuthFunc("secret")),
getJwtFromContextHandler,
})).Methods("GET")
routes.Handle("/error", middlewareHandler.Handle([]rye.Handler{
middlewareFirstHandler,
errorHandler,
homeHandler,
})).Methods("GET")
// In order to pass in a context variable, this set of
// handlers works with "ctx" on the query string
routes.Handle("/context", middlewareHandler.Handle(
[]rye.Handler{
stashContextHandler,
logContextHandler,
})).Methods("GET")
log.Infof("API server listening on %v", "localhost:8181")
srv := &http.Server{
Addr: "localhost:8181",
Handler: routes,
}
srv.ListenAndServe()
}
func beforeAllHandler(rw http.ResponseWriter, r *http.Request) *rye.Response {
log.Infof("This handler is called before every endpoint: %+v", r)
return nil
}
func homeHandler(rw http.ResponseWriter, r *http.Request) *rye.Response {
log.Infof("Home handler has fired!")
fmt.Fprint(rw, "This is the home handler")
return nil
}
func middlewareFirstHandler(rw http.ResponseWriter, r *http.Request) *rye.Response {
log.Infof("Middleware handler has fired!")
return nil
}
func errorHandler(rw http.ResponseWriter, r *http.Request) *rye.Response {
log.Infof("Error handler has fired!")
message := "This is the error handler"
return &rye.Response{
StatusCode: http.StatusInternalServerError,
Err: errors.New(message),
}
}
func stashContextHandler(rw http.ResponseWriter, r *http.Request) *rye.Response {
log.Infof("Stash Context handler has fired!")
// Retrieve the request's context
ctx := r.Context()
// A query string value to add to the context
toContext := r.URL.Query().Get("ctx")
if toContext != "" {
log.Infof("Adding `query-string-ctx` to request.Context(). Val: %v", toContext)
} else {
log.Infof("Adding default `query-string-ctx` value to context")
toContext = "No value added. Add querystring param `ctx` with a value to get it mirrored through context."
}
// Create a NEW context
ctx = context.WithValue(ctx, "query-string-ctx", toContext)
// Return that in the Rye response
// Rye will add it to the Request to
// pass to the next middleware
return &rye.Response{Context: ctx}
}
func logContextHandler(rw http.ResponseWriter, r *http.Request) *rye.Response {
log.Infof("Log Context handler has fired!")
// Retrieving a context value is EASY in subsequent middlewares
fromContext := r.Context().Value("query-string-ctx")
// Reflect that on the http response
fmt.Fprintf(rw, "Here's the `ctx` query string value you passed. Pulled from context: %v", fromContext)
return nil
}
// This handler pulls the JWT from the Context and echoes it through the request
func getJwtFromContextHandler(rw http.ResponseWriter, r *http.Request) *rye.Response {
log.Infof("Log Context handler has fired!")
jwt := r.Context().Value(rye.CONTEXT_JWT)
if jwt != nil {
fmt.Fprintf(rw, "JWT found in Context: %v", jwt)
}
return nil
}