Skip to content

Commit

Permalink
first pass at adding a with formatting option, WIP - not working
Browse files Browse the repository at this point in the history
  • Loading branch information
nathan-lubchenco committed Oct 12, 2023
1 parent e74e40a commit db7af1a
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 2 deletions.
96 changes: 94 additions & 2 deletions httpevents/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package httpevents

import (
"bufio"
"fmt"
"net"
"net/http"
"sync"
Expand Down Expand Up @@ -68,11 +69,83 @@ func NewHandlerWith(logger *events.Logger, handler http.Handler) http.Handler {
})
}

type LoggerFunc func(headers http.Header) http.Header

func copyHeaders(headers http.Header) http.Header {
fmt.Println("Copying headers")
fmt.Println("Existing Header")
for k, v := range headers {
fmt.Println(k)
fmt.Println(v)
}
headersCopy := make(http.Header)

for k, v := range headers {
headersCopy[k] = v
}

fmt.Println("New Headers")
for k, v := range headersCopy {
fmt.Println(k)
fmt.Println(v)
}

return headersCopy
}
func NewHandlerWithFormatting(formatter LoggerFunc, logger *events.Logger, handler http.Handler) http.Handler {
return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
var laddr string

if value, ok := req.Context().Value(http.LocalAddrContextKey).(net.Addr); ok {
laddr = value.String()
}

w := responseWriterPool.Get().(*responseWriter)
// We capture all the values we need from req in case the object
// gets modified by the handler.
w.ResponseWriter = res
w.logger = logger
w.SanitizeHeaders = formatter
w.request.reset(req, laddr)

// If the handler panics we want to make sure we report the issue in the
// access log, while also ensuring that a response is going to be sent
// down to the client.
// We don't silence the panic here tho and instead we forward it back to
// the parent handler which may need to be aware that a panic occurred.
defer func() {
err := recover()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
}

w.ResponseWriter = nil
w.logger = nil
w.wroteHeader = false
w.request.release()
responseWriterPool.Put(w)

if err != nil {
panic(err)
}
}()

// The request is forwarded to the handler, if it never calls the
// writer's WriteHeader method we force the call with "200 OK" status
// to match the default behavior of the net/http package (and also make
// sure an access log will be written).
handler.ServeHTTP(w, req)
w.WriteHeader(http.StatusOK)
})

}

type responseWriter struct {
http.ResponseWriter
logger *events.Logger
request
wroteHeader bool
wroteHeader bool
SanitizeHeaders LoggerFunc
}

func (w *responseWriter) WriteHeader(status int) {
Expand Down Expand Up @@ -103,7 +176,26 @@ func (w *responseWriter) log(depth int, status int) {
w.logger = nil
w.request.status = status
w.request.statusText = http.StatusText(status)
w.request.log(logger, w.ResponseWriter.Header(), depth+1)

if w.SanitizeHeaders != nil {
fmt.Println("Sanitizing headers")
for k, v := range w.ResponseWriter.Header() {
fmt.Println(k)
fmt.Println(v)
}
headers := w.SanitizeHeaders(copyHeaders(w.ResponseWriter.Header()))
fmt.Println("Headers")
println(w.ResponseWriter.Header())

println(w.ResponseWriter.Header().Get("User-Agent"))
fmt.Println("Changed Headers")
println(headers)
println(headers.Get("User-Agent"))
w.request.log(logger, headers, depth+1)
} else {
fmt.Println("MISSING FUNC")
w.request.log(logger, w.ResponseWriter.Header(), depth+1)
}
}
}

Expand Down
49 changes: 49 additions & 0 deletions httpevents/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package httpevents

import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"testing"
Expand Down Expand Up @@ -79,6 +80,54 @@ func TestHandler(t *testing.T) {
})
}

func filterHeaders(headers http.Header) http.Header {
fmt.Println("before")
fmt.Println(headers)
headers.Del("User-Agent")
fmt.Println("after")
fmt.Println(headers)
return headers
}
func TestNewHandlerWithFormatting(t *testing.T) {
eventsHandler := &eventstest.Handler{}

req := httptest.NewRequest("GET", "/hello?answer=42", nil)
req.Header.Set("User-Agent", "httpevents")
req.Header.Set("Authorization", "this will be deleted")
req.URL.Fragment = "universe" // for some reason NewRequest doesn't parses this
req.Host = "www.github.com"
req.RemoteAddr = "127.0.0.1:56789"
req = req.WithContext(context.WithValue(req.Context(), http.LocalAddrContextKey, mockAddr{
s: "127.0.0.1:80",
n: "tcp",
}))

res := httptest.NewRecorder()
log := events.NewLogger(eventsHandler)

h := NewHandlerWithFormatting(filterHeaders, log, http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusAccepted)
}))
h.ServeHTTP(res, req)

eventsHandler.AssertEvents(t, events.Event{
Message: `127.0.0.1:80->127.0.0.1:56789 - www.github.com - GET /hello?answer=42#universe - 202 Accepted - "httpevents"`,
Args: events.Args{
{Name: "local_address", Value: "127.0.0.1:80"},
{Name: "remote_address", Value: "127.0.0.1:56789"},
{Name: "host", Value: "www.github.com"},
{Name: "method", Value: "GET"},
//{Name: "path", Value: "/hello"},
{Name: "query", Value: "answer=42"},
{Name: "fragment", Value: "universe"},
{Name: "status", Value: 202},
{Name: "request", Value: &headerList{{name: "User-Agent", value: "httpevents"}}},
{Name: "response", Value: &headerList{}},
},
Debug: true,
})
}

func TestHandlerPanic(t *testing.T) {
eventsHandler := &eventstest.Handler{}

Expand Down

0 comments on commit db7af1a

Please sign in to comment.