Skip to content

Commit

Permalink
move HTTP middleware
Browse files Browse the repository at this point in the history
Modify logging, based on github.com/gorilla/handlers.
  • Loading branch information
dmke committed Mar 14, 2022
1 parent e405ab8 commit a257971
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 8 deletions.
20 changes: 20 additions & 0 deletions service/middleware/clean_multipart.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package middleware

import (
"log"
"net/http"
)

func CleanMultipart(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r)

if r.MultipartForm == nil {
return
}
if err := r.MultipartForm.RemoveAll(); err != nil {
id, _ := GetRequestID(r)
log.Printf("%s: failed to cleanup multipart/form-data residues: %v", id, err)
}
})
}
82 changes: 82 additions & 0 deletions service/middleware/logging.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package middleware

import (
"bytes"
"net"
"net/http"
"os"
"strconv"
)

type responseLogger struct {
status, n int
http.ResponseWriter
}

func (l *responseLogger) Write(b []byte) (n int, err error) {
n, err = l.ResponseWriter.Write(b)
l.n += n
return
}

func (l *responseLogger) WriteHeader(status int) {
l.ResponseWriter.WriteHeader(status)
l.status = status
}

// Logging performs request logging. This method takes heavy inspiration
// from (github.com/gorilla/handlers).CombinedLoggingHandler.
func Logging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
rl := &responseLogger{ResponseWriter: w}
url := *r.URL

next.ServeHTTP(rl, r)

username := "-"
if url.User != nil {
if name := url.User.Username(); name != "" {
username = name
}
}

host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
host = r.RemoteAddr
}

uri := r.RequestURI

// Requests using the CONNECT method over HTTP/2.0 must use
// the authority field (aka r.Host) to identify the target.
// Refer: https://httpwg.github.io/specs/rfc7540.html#CONNECT
if r.ProtoMajor == 2 && r.Method == "CONNECT" {
uri = r.Host
}
if uri == "" {
uri = url.RequestURI()
}

id, haveID := GetRequestID(r)

var buf bytes.Buffer
buf.Grow(len(id) + len(r.Method) + len(host) + len(username) + len(uri) + 50) // reduce allocs
if haveID {
buf.WriteString(id)
buf.WriteString(": ")
}
buf.WriteString(host)
buf.WriteString(" - ")
buf.WriteString(username)
buf.WriteString(" - ")
buf.WriteString(r.Method)
buf.WriteByte(' ')
buf.WriteString(uri)
buf.WriteString(" - ")
buf.WriteString(strconv.Itoa(rl.status))
buf.WriteByte(' ')
buf.WriteString(strconv.Itoa(rl.n))
buf.WriteByte('\n')
_, _ = buf.WriteTo(os.Stderr)
})
}
9 changes: 7 additions & 2 deletions requestid/requestid.go → service/middleware/requestid.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package requestid
package middleware

import (
"context"
Expand All @@ -13,7 +13,7 @@ type contextKey string

const ContextKey = contextKey("request-id")

func Middleware(next http.Handler) http.Handler {
func RequestID(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
id := uuid.Must(uuid.NewRandom()).String()
r = r.WithContext(context.WithValue(r.Context(), ContextKey, id))
Expand All @@ -22,3 +22,8 @@ func Middleware(next http.Handler) http.Handler {
next.ServeHTTP(w, r)
})
}

func GetRequestID(r *http.Request) (string, bool) {
id, ok := r.Context().Value(ContextKey).(string)
return id, ok
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package requestid
package middleware

import (
"net/http"
Expand Down Expand Up @@ -26,7 +26,7 @@ func TestMiddleware(t *testing.T) {
}

w := httptest.NewRecorder()
Middleware(http.HandlerFunc(captureContextID)).ServeHTTP(w,
RequestID(http.HandlerFunc(captureContextID)).ServeHTTP(w,
httptest.NewRequest(http.MethodGet, "/", nil))
assert.Equal(t, http.StatusOK, w.Code)

Expand Down
9 changes: 5 additions & 4 deletions service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ import (
"fmt"
"log"
"net/http"
"os"
"time"

"github.com/digineo/texd/exec"
"github.com/digineo/texd/requestid"
"github.com/digineo/texd/service/middleware"
"github.com/digineo/texd/tex"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
Expand Down Expand Up @@ -62,12 +61,14 @@ func Start(opts Options) func(context.Context) error {
r.HandleFunc("/metrics", svc.HandleMetrics).Methods(http.MethodGet)

// r.Use(handlers.RecoveryHandler())
r.Use(requestid.Middleware)
r.Use(middleware.RequestID)
r.Use(handlers.CompressHandler)
r.Use(middleware.Logging)
r.Use(middleware.CleanMultipart)

srv := http.Server{
Addr: opts.Addr,
Handler: handlers.CombinedLoggingHandler(os.Stdout, r),
Handler: r,
}

go func() {
Expand Down

0 comments on commit a257971

Please sign in to comment.