From d89c79a7c49b9fb0f852b06594f9cb32955808e1 Mon Sep 17 00:00:00 2001 From: Ben Hearsum Date: Sun, 14 Jul 2024 23:32:07 -0400 Subject: [PATCH] feat: use uuids for request ids to guarantee uniqueness --- middleware.go | 18 ++++++++++++------ middleware_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 middleware_test.go diff --git a/middleware.go b/middleware.go index 00217fd4e..5d8e8096c 100644 --- a/middleware.go +++ b/middleware.go @@ -1,9 +1,10 @@ package main import ( - "math/rand" "net/http" "time" + + "github.com/google/uuid" ) // Middleware wraps an http.Handler with additional functionality @@ -27,13 +28,18 @@ func setResponseHeaders() Middleware { func setRequestID() Middleware { return func(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - rid := make([]rune, 16) - letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") - for i := range rid { - rid[i] = letters[rand.Intn(len(letters))] + // NewV7 is used instead of New because the latter will panic + // if can't generate a UUID. It's preferably for us to have + // worse request ids than panic. + uuid, err := uuid.NewV7() + var rid string + if err != nil { + rid = "-" + } else { + rid = uuid.String() } - h.ServeHTTP(w, addToContext(r, contextKeyRequestID, string(rid))) + h.ServeHTTP(w, addToContext(r, contextKeyRequestID, rid)) }) } } diff --git a/middleware_test.go b/middleware_test.go new file mode 100644 index 000000000..3f90c5e95 --- /dev/null +++ b/middleware_test.go @@ -0,0 +1,30 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package main + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/google/uuid" +) + +func TestRequestIDWellFormed(t *testing.T) { + // This method of testing middleware is cribbed from + // https://stackoverflow.com/questions/51201056/testing-golang-middleware-that-modifies-the-request + nextHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + val := r.Context().Value(contextKeyRequestID).(string) + if uuid.Validate(val) != nil { + t.Errorf("requestID is not a valid uuid! %v", val) + } + }) + + handlerToTest := setRequestID()(nextHandler) + + req := httptest.NewRequest("GET", "http://foo.bar/", nil) + + handlerToTest.ServeHTTP(httptest.NewRecorder(), req) +}