Add initial support for HTTP request intercepting

This commit is contained in:
David Stotijn
2022-03-08 13:27:31 +01:00
parent bdd667381a
commit 71e550f0cd
11 changed files with 1184 additions and 28 deletions

View File

@ -8,10 +8,8 @@ import (
"fmt"
"io"
"io/ioutil"
"math/rand"
"net/http"
"net/url"
"time"
"github.com/oklog/ulid"
@ -23,16 +21,16 @@ import (
type contextKey int
const LogBypassedKey contextKey = 0
const (
LogBypassedKey contextKey = iota
ReqLogIDKey
)
var (
ErrRequestNotFound = errors.New("reqlog: request not found")
ErrProjectIDMustBeSet = errors.New("reqlog: project ID must be set")
)
//nolint:gosec
var ulidEntropy = rand.New(rand.NewSource(time.Now().UnixNano()))
type RequestLog struct {
ID ulid.ULID
ProjectID ulid.ULID
@ -170,8 +168,14 @@ func (svc *service) RequestModifier(next proxy.RequestModifyFunc) proxy.RequestM
return
}
reqID, ok := proxy.RequestIDFromContext(req.Context())
if !ok {
svc.logger.Errorw("Bypassed logging: request doesn't have an ID.")
return
}
reqLog := RequestLog{
ID: ulid.MustNew(ulid.Timestamp(time.Now()), ulidEntropy),
ID: reqID,
ProjectID: svc.activeProjectID,
Method: clone.Method,
URL: clone.URL,
@ -191,7 +195,7 @@ func (svc *service) RequestModifier(next proxy.RequestModifyFunc) proxy.RequestM
"reqLogID", reqLog.ID.String(),
"url", reqLog.URL.String())
ctx := context.WithValue(req.Context(), proxy.ReqLogIDKey, reqLog.ID)
ctx := context.WithValue(req.Context(), ReqLogIDKey, reqLog.ID)
*req = *req.WithContext(ctx)
}
}
@ -206,7 +210,7 @@ func (svc *service) ResponseModifier(next proxy.ResponseModifyFunc) proxy.Respon
return nil
}
reqLogID, ok := res.Request.Context().Value(proxy.ReqLogIDKey).(ulid.ULID)
reqLogID, ok := res.Request.Context().Value(ReqLogIDKey).(ulid.ULID)
if !ok {
return errors.New("reqlog: request is missing ID")
}

View File

@ -41,6 +41,8 @@ func TestRequestModifier(t *testing.T) {
}
reqModFn := svc.RequestModifier(next)
req := httptest.NewRequest("GET", "https://example.com/", strings.NewReader("bar"))
reqID := ulid.MustNew(ulid.Timestamp(time.Now()), ulidEntropy)
req = req.WithContext(proxy.WithRequestID(req.Context(), reqID))
reqModFn(req)
@ -88,7 +90,7 @@ func TestResponseModifier(t *testing.T) {
req := httptest.NewRequest("GET", "https://example.com/", strings.NewReader("bar"))
reqLogID := ulid.MustNew(ulid.Timestamp(time.Now()), ulidEntropy)
req = req.WithContext(context.WithValue(req.Context(), proxy.ReqLogIDKey, reqLogID))
req = req.WithContext(context.WithValue(req.Context(), reqlog.ReqLogIDKey, reqLogID))
res := &http.Response{
Request: req,