Skip to content

Instantly share code, notes, and snippets.

@masiuchi
Last active April 16, 2016 10:57
Show Gist options
  • Save masiuchi/c57b901aa24a05a56f4fbd31c2b84295 to your computer and use it in GitHub Desktop.
Save masiuchi/c57b901aa24a05a56f4fbd31c2b84295 to your computer and use it in GitHub Desktop.
Go sample code of net/http middleware.
package main
// http://www.alexedwards.net/blog/making-and-using-middleware
import (
"errors"
"fmt"
"html"
"log"
"net/http"
"regexp"
)
type WrapperWriter struct {
http.ResponseWriter
Body string
}
func NewWrapperWriter(w http.ResponseWriter) *WrapperWriter {
wrapper := new(WrapperWriter)
wrapper.ResponseWriter = w
return wrapper
}
func (ww *WrapperWriter) Write(p []byte) (n int, err error) {
ww.Body += string(p)
return len(p), nil
}
func (ww *WrapperWriter) Flush() (n int, err error) {
if ww.Body == "" {
return 0, errors.New("no body")
}
return ww.ResponseWriter.Write([]byte(ww.Body))
}
func middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/redirect" {
http.Redirect(w, r, "/redirected", 302)
return
}
if r.URL.Path != "/redirected" {
r.URL.Path += "/rewritten"
}
wrapper := NewWrapperWriter(w)
defer wrapper.Flush()
next.ServeHTTP(wrapper, r)
fmt.Fprintf(wrapper, "\ninserted by middleware")
wrapper.Body = regexp.MustCompile(`Hello,`).ReplaceAllString(wrapper.Body, "こんにちは、")
})
}
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
}
func main() {
topHandler := http.HandlerFunc(handler)
http.Handle("/", middleware(topHandler))
log.Fatal(http.ListenAndServe(":5000", nil))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment