dbs67
2/28/2017 - 6:19 PM

Go middleware samples for my blog post. http://justinas.org/writing-http-middleware-in-go/

Go middleware samples for my blog post. http://justinas.org/writing-http-middleware-in-go/

package main

import (
	"net/http"
)

type SingleHost struct {
	handler     http.Handler
	allowedHost string
}

func NewSingleHost(handler http.Handler, allowedHost string) *SingleHost {
	return &SingleHost{handler: handler, allowedHost: allowedHost}
}

func (s *SingleHost) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	host := r.Host
	if host == s.allowedHost {
		s.handler.ServeHTTP(w, r)
	} else {
		w.WriteHeader(403)
	}
}

func myHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Success!"))
}

func main() {
	single := NewSingleHost(http.HandlerFunc(myHandler), "example.com")

	println("Listening on port 8080")
	http.ListenAndServe(":8080", single)
}
package main

import (
	"net/http"
)

func SingleHost(handler http.Handler, allowedHost string) http.Handler {
	ourFunc := func(w http.ResponseWriter, r *http.Request) {
		host := r.Host
		if host == allowedHost {
			handler.ServeHTTP(w, r)
		} else {
			w.WriteHeader(403)
		}
	}
	return http.HandlerFunc(ourFunc)
}


func myHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Success!"))
}

func main() {
	single := SingleHost(http.HandlerFunc(myHandler), "example.com")

	println("Listening on port 8080")
	http.ListenAndServe(":8080", single)
}
package main

import (
	"net/http"
)

type AppendMiddleware struct {
	handler http.Handler
}

func (a *AppendMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	a.handler.ServeHTTP(w, r)
	w.Write([]byte("<!-- Middleware says hello! -->"))
}

func myHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Success!"))
}

func main() {
	mid := &AppendMiddleware{http.HandlerFunc(myHandler)}

	println("Listening on port 8080")
	http.ListenAndServe(":8080", mid)
}
package main

import (
	"net/http"
	"net/http/httptest"
)

type ModifierMiddleware struct {
	handler http.Handler
}

func (m *ModifierMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	rec := httptest.NewRecorder()
	// passing a ResponseRecorder instead of the original RW
	m.handler.ServeHTTP(rec, r)
	// after this finishes, we have the response recorded
	// and can modify it before copying it to the original RW

	// we copy the original headers first
	for k, v := range rec.Header() {
		w.Header()[k] = v
	}
	// and set an additional one
	w.Header().Set("X-We-Modified-This", "Yup")
	// only then the status code, as this call writes the headers as well 
	w.WriteHeader(418)
        // The body hasn't been written (to the real RW) yet,
        // so we can prepend some data.
        data := []byte("Middleware says hello again. ")

        // But the Content-Length might have been set already,
        // we should modify it by adding the length
        // of our own data.
        // Ignoring the error is fine here:
        // if Content-Length is empty or otherwise invalid,
        // Atoi() will return zero,
        // which is just what we'd want in that case.
        clen, _ := strconv.Atoi(r.Header.Get("Content-Length"))
        clen += len(data)
        w.Header.Set("Content-Length", strconv.Itoa(clen))

        // finally, write out our data
        w.Write(data)
	// then write out the original body
	w.Write(rec.Body.Bytes())
}

func myHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Success!"))
}

func main() {
	mid := &ModifierMiddleware{http.HandlerFunc(myHandler)}

	println("Listening on port 8080")
	http.ListenAndServe(":8080", mid)
}