This repository has been archived by the owner on Apr 3, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mux.go
85 lines (72 loc) · 2.2 KB
/
mux.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
package goji
import (
"context"
"net/http"
"goji.io/internal"
)
/*
Mux is a HTTP multiplexer / router similar to net/http.ServeMux.
Muxes multiplex traffic between many http.Handlers by selecting the first
applicable Pattern. They then call a common middleware stack, finally passing
control to the selected http.Handler. See the documentation on the Handle
function for more information about how routing is performed, the documentation
on the Pattern type for more information about request matching, and the
documentation for the Use method for more about middleware.
Muxes cannot be configured concurrently from multiple goroutines, nor can they
be configured concurrently with requests.
*/
type Mux struct {
handler http.Handler
middleware []func(http.Handler) http.Handler
router router
root bool
}
/*
NewMux returns a new Mux with no configured middleware or routes.
*/
func NewMux() *Mux {
m := SubMux()
m.root = true
return m
}
/*
SubMux returns a new Mux with no configured middleware or routes, and which
inherits routing information from the passed context. This is especially useful
when using one Mux as a http.Handler registered to another "parent" Mux.
For example, a common pattern is to organize applications in a way that mirrors
the structure of its URLs: a photo-sharing site might have URLs that start with
"/users/" and URLs that start with "/albums/", and might be organized using
three Muxes:
root := NewMux()
users := SubMux()
root.Handle(pat.New("/users/*"), users)
albums := SubMux()
root.Handle(pat.New("/albums/*"), albums)
// e.g., GET /users/carl
users.Handle(pat.Get("/:name"), renderProfile)
// e.g., POST /albums/
albums.Handle(pat.Post("/"), newAlbum)
*/
func SubMux() *Mux {
m := &Mux{}
m.buildChain()
return m
}
// Match implements Pattern.
func (m *Mux) Match(r *http.Request) *http.Request {
if m.router.match(r) {
return r
}
return nil
}
// ServeHTTP implements net/http.Handler.
func (m *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if m.root {
ctx := r.Context()
ctx = context.WithValue(ctx, internal.Path, r.URL.EscapedPath())
r = r.WithContext(ctx)
}
r = m.router.route(r)
m.handler.ServeHTTP(w, r)
}
var _ http.Handler = &Mux{}