Two example about middleware in go
Reference: http://www.alexedwards.net/blog/making-and-using-middleware

A basic middleware chain example

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
package main
import (
"log"
"net/http"
)
func middlewareOne(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println("Executing middlewareOne")
next.ServeHTTP(w, r)
log.Println("Executing middlewareOne again")
})
}
func middlewareTwo(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println("Executing middlewareTwo")
if r.URL.Path != "/" {
return
}
next.ServeHTTP(w, r)
log.Println("Executing middlewareTwo again")
})
}
func final(w http.ResponseWriter, r *http.Request) {
log.Println("Executing finalHandler")
w.Write([]byte("OK"))
}
func main() {
finalHandler := http.HandlerFunc(final)
http.Handle("/", middlewareOne(middlewareTwo(finalHandler)))
http.ListenAndServe(":3000", nil)
}

example of chaining 3rd party middleware

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
package main
import (
"bytes"
"github.com/goji/httpauth"
"github.com/gorilla/handlers"
"net/http"
"os"
)
func enforceXMLHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.ContentLength == 0 {
http.Error(w, http.StatusText(400), 400)
return
}
buf := new(bytes.Buffer)
buf.ReadFrom(r.Body)
if http.DetectContentType(buf.Bytes()) != "text/xml; charset=utf-8" {
http.Error(w, http.StatusText(415), 415)
return
}
next.ServeHTTP(w, r)
})
}
func myLoggingHandler(h http.Handler) http.Handler {
logFile, err := os.OpenFile("server.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
panic(err)
}
return handlers.LoggingHandler(logFile, h)
}
func main() {
indexHandler := http.HandlerFunc(index)
authHandler := httpauth.SimpleBasicAuth("username", "password")
http.Handle("/", myLoggingHandler(authHandler(enforceXMLHandler(indexHandler))))
http.ListenAndServe(":3000", nil)
}
func index(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("OK"))
}