This repository has been archived by the owner on Apr 11, 2019. It is now read-only.
/
example_test.go
73 lines (62 loc) · 2.25 KB
/
example_test.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
package httpctx_test
import (
"context"
"net/http"
"github.com/spkg/httpctx"
)
func Example() {
public := httpctx.Use(ensureHttps)
authenticate := public.Use(authenticate, ensureAdmin)
http.Handle("/admin", authenticate.HandleFunc(admin))
http.Handle("/", public.HandleFunc(index))
http.ListenAndServe(":8080", nil)
}
func index(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
w.Write([]byte("index page"))
return nil
}
func admin(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
w.Write([]byte("admin page, userid=" + useridFrom(ctx)))
return nil
}
// ensureHttps is an example of middleware that ensures that the request scheme is https.
func ensureHttps(h httpctx.Handler) httpctx.Handler {
return httpctx.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
if r.URL.Scheme != "https" {
u := *r.URL
u.Scheme = "https"
http.Redirect(w, r, u.String(), http.StatusMovedPermanently)
return nil
}
return h.ServeHTTPContext(ctx, w, r)
})
}
// authenticate is an example of middleware that authenticates using basic authentication
func authenticate(h httpctx.Handler) httpctx.Handler {
return httpctx.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
credentials := r.Header.Get("WWW-Authenticate")
ctx, err := checkCredentials(ctx, credentials)
if err != nil {
return err
}
return h.ServeHTTPContext(ctx, w, r)
})
}
func ensureAdmin(h httpctx.Handler) httpctx.Handler {
return httpctx.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
// ... get the userid from the context and ensure that the user has admin privilege ...
return h.ServeHTTPContext(ctx, w, r)
})
}
// checkCredentials is a placeholder for a function that checks
// credentials, and if successful returns a context with the
// identity of the user attached as a value.
func checkCredentials(ctx context.Context, credentials string) (context.Context, error) {
// ... just an example ...
// Note that you would not normally use a string as the key to context.WithValue
return context.WithValue(ctx, "userid", "username"), nil
}
func useridFrom(ctx context.Context) string {
userid, _ := ctx.Value("userid").(string)
return userid
}