0

Hopefully, this is an easy way to earn some rep. This seems very simple, so I must be doing something wrong and just cant see it.

I have a simple middleware which a transaction id and adds it to the request and response headers.

    func HandleTransactionID(fn http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, req *http.Request) {
        tid := uuid.NewV4()
        req.Header.Set(TransIDHeader, TransIDPrefix + tid.String())
        w.Header().Set(TransIDHeader, TransIDPrefix + tid.String())
        fn(w, req)
    }
}

In my unit tests, I've confirmed the response header is successfully set, but it doesn't appear the the request header is being set. I would assume that it is possible to modify the request headers, so ?

const (
    WriteTestHeader = "WriterTransHeader"
    RequestTestHeader = "ReqTransHeader"
)


func recorderFunc(w http.ResponseWriter, req *http.Request){
    w.Header().Set(WriteTestHeader, w.Header().Get(TransIDHeader))
    w.Header().Set(RequestTestHeader, req.Header.Get(TransIDHeader))
}

func TestHandleTransactionID(t *testing.T) {
    recorder := httptest.NewRecorder()
    req := httptest.NewRequest("GET", "/foo", nil)
    middleware.HandleTransactionID(recorderFunc)(recorder, req)

    if req.Header.Get(RequestTestHeader) == "" {
        t.Error("request header is nil")
    }
    if recorder.Header().Get(WriteTestHeader) == "" {
        t.Error("response header is nil")
    }
    if req.Header.Get(RequestTestHeader) != recorder.Header().Get(WriteTestHeader) {
        t.Errorf("header value mismatch: %s != %s",
            req.Header.Get(RequestTestHeader),
            recorder.Header().Get(WriteTestHeader))
    }
}
4
  • Can you try logging the headers directly in recorderFunc ? log.Println(req.Header.Get(TransIDHeader), w.Header().Get(TransIDHeader)) Commented Oct 12, 2016 at 17:36
  • I thought I did that earlier, and it printed the empty string, but I can try again. Commented Oct 14, 2016 at 20:02
  • Can you confirm that TransIDPrefix + tid.String() is not an empty string because, I was able to print the values when I used hardcoded strings. Commented Oct 15, 2016 at 10:48
  • It was when I did a println(), but I'll verify. I've been pulled off on other projects for the time being. Should be back to it this week. Commented Oct 17, 2016 at 16:26

1 Answer 1

1

In your test, req.Header.Get(RequestTestHeader) will always remain an empty string because you are not setting the Key as 'RequestTestHeader' in the request header but in the ResponseWriter w.Header().Set(RequestTestHeader, req.Header.Get(TransIDHeader))

On an unrelated note, It would be considered idomatic Go, to have your middleware function signature using the http.Handler interface, func HandleTransactionID(fn http.Handler) http.Handler.

Sign up to request clarification or add additional context in comments.

1 Comment

Good catch. I messed that up trying to fix this test due to an unrelated problem. Writing while sleepy is a bad idea. :-/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.