Skip to content

Commit dc47ac7

Browse files
committed
add HTTP methods support
1 parent 322f2f4 commit dc47ac7

File tree

2 files changed

+146
-7
lines changed

2 files changed

+146
-7
lines changed

mux.go

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,35 @@ import (
99
)
1010

1111
// Version is this package's version number.
12-
const Version = "0.0.1"
12+
const Version = "0.0.2"
1313

14-
// Handler responds to an HTTP request.
14+
// Handler responds to a HTTP request.
1515
type Handler interface {
1616
ServeHTTP(http.ResponseWriter, *http.Request, map[string]string)
1717
}
1818

19+
// The HandlerFunc type is an adapter to allow the use of an ordinary function
20+
// as a Handler.
21+
type HandlerFunc func(http.ResponseWriter, *http.Request, map[string]string)
22+
23+
func (f HandlerFunc) ServeHTTP(res http.ResponseWriter, req *http.Request, params map[string]string) {
24+
f(res, req, params)
25+
}
26+
1927
// Mux is the HTTP request multiplexer.
2028
type Mux struct {
2129
root map[string]*routing.Node
2230
}
2331

2432
// New returns a new mux.
2533
func New() *Mux {
26-
return &Mux{}
34+
return &Mux{root: map[string]*routing.Node{}}
2735
}
2836

2937
// Handle registers the handler for the given method and url.
3038
func (m *Mux) Handle(method string, url string, handler Handler) *Mux {
39+
method = strings.ToUpper(method)
40+
3141
if _, ok := m.root[method]; !ok {
3242
m.root[method] = routing.New()
3343
}
@@ -37,6 +47,36 @@ func (m *Mux) Handle(method string, url string, handler Handler) *Mux {
3747
return m
3848
}
3949

50+
// Get registers a handler for the GET http method.
51+
func (m *Mux) Get(url string, handler Handler) *Mux {
52+
return m.Handle(http.MethodGet, url, handler)
53+
}
54+
55+
// Post registers a handler for the POST http method.
56+
func (m *Mux) Post(url string, handler Handler) *Mux {
57+
return m.Handle(http.MethodPost, url, handler)
58+
}
59+
60+
// Put registers a handler for the PUT http method.
61+
func (m *Mux) Put(url string, handler Handler) *Mux {
62+
return m.Handle(http.MethodPut, url, handler)
63+
}
64+
65+
// Delete registers a handler for the DELETE http method.
66+
func (m *Mux) Delete(url string, handler Handler) *Mux {
67+
return m.Handle(http.MethodDelete, url, handler)
68+
}
69+
70+
// Head registers a handler for the HEAD http method.
71+
func (m *Mux) Head(url string, handler Handler) *Mux {
72+
return m.Handle(http.MethodHead, url, handler)
73+
}
74+
75+
// Patch registers a handler for the PATCH http method.
76+
func (m *Mux) Patch(url string, handler Handler) *Mux {
77+
return m.Handle(http.MethodPatch, url, handler)
78+
}
79+
4080
func (m Mux) ServeHTTP(res http.ResponseWriter, req *http.Request) {
4181
uri := req.RequestURI
4282
method := req.Method
@@ -56,10 +96,6 @@ func (m Mux) ServeHTTP(res http.ResponseWriter, req *http.Request) {
5696
return
5797
}
5898

59-
if method == http.MethodHead {
60-
method = http.MethodGet
61-
}
62-
6399
node, ok := m.root[method]
64100

65101
if !ok {

mux_test.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,104 @@
11
package mux
2+
3+
import (
4+
"io/ioutil"
5+
"net/http"
6+
"net/http/httptest"
7+
"strings"
8+
"testing"
9+
10+
"github.com/stretchr/testify/suite"
11+
)
12+
13+
type MuxSuite struct {
14+
suite.Suite
15+
16+
server *httptest.Server
17+
}
18+
19+
func (s *MuxSuite) SetupSuite() {
20+
mux := New()
21+
22+
mux.Get("/get/:id", HandlerFunc(func(res http.ResponseWriter, req *http.Request, params map[string]string) {
23+
res.WriteHeader(http.StatusOK)
24+
25+
res.Write([]byte(params["id"]))
26+
}))
27+
28+
mux.Post("/post/:id", HandlerFunc(func(res http.ResponseWriter, req *http.Request, params map[string]string) {
29+
res.WriteHeader(http.StatusOK)
30+
31+
res.Write([]byte(params["id"]))
32+
}))
33+
34+
mux.Put("/put/:id", HandlerFunc(func(res http.ResponseWriter, req *http.Request, params map[string]string) {
35+
res.WriteHeader(http.StatusOK)
36+
37+
res.Write([]byte(params["id"]))
38+
}))
39+
40+
mux.Delete("/delete/:id", HandlerFunc(func(res http.ResponseWriter, req *http.Request, params map[string]string) {
41+
res.WriteHeader(http.StatusOK)
42+
43+
res.Write([]byte(params["id"]))
44+
}))
45+
46+
mux.Head("/head/:id", HandlerFunc(func(res http.ResponseWriter, req *http.Request, params map[string]string) {
47+
res.WriteHeader(http.StatusOK)
48+
49+
res.Write([]byte(params["id"]))
50+
}))
51+
52+
mux.Patch("/patch/:id", HandlerFunc(func(res http.ResponseWriter, req *http.Request, params map[string]string) {
53+
res.WriteHeader(http.StatusOK)
54+
55+
res.Write([]byte(params["id"]))
56+
}))
57+
58+
s.server = httptest.NewServer(mux)
59+
}
60+
61+
func (s *MuxSuite) TestMethods() {
62+
methods := []string{
63+
http.MethodGet,
64+
http.MethodPost,
65+
http.MethodPut,
66+
http.MethodDelete,
67+
http.MethodHead,
68+
http.MethodPatch,
69+
}
70+
71+
for _, method := range methods {
72+
req, err := http.NewRequest(method, s.server.URL+"/"+strings.ToLower(method)+"/123", nil)
73+
74+
s.Nil(err)
75+
76+
res, err := sendRequest(req)
77+
78+
s.Nil(err)
79+
s.Equal(http.StatusOK, res.StatusCode)
80+
81+
if method != http.MethodHead {
82+
s.Equal([]byte("123"), getResRawBody(res))
83+
}
84+
}
85+
}
86+
87+
func TestMux(t *testing.T) {
88+
suite.Run(t, new(MuxSuite))
89+
}
90+
91+
func sendRequest(req *http.Request) (*http.Response, error) {
92+
cli := &http.Client{}
93+
return cli.Do(req)
94+
}
95+
96+
func getResRawBody(res *http.Response) []byte {
97+
bytes, err := ioutil.ReadAll(res.Body)
98+
99+
if err != nil {
100+
panic(err)
101+
}
102+
103+
return bytes
104+
}

0 commit comments

Comments
 (0)