func (l Logger) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { for _, rule := range l.Rules { if httpserver.Path(r.URL.Path).Matches(rule.PathScope) { // Record the response responseRecorder := httpserver.NewResponseRecorder(w) // Attach the Replacer we'll use so that other middlewares can // set their own placeholders if they want to. rep := httpserver.NewReplacer(r, responseRecorder, CommonLogEmptyValue) responseRecorder.Replacer = rep // Bon voyage, request! status, err := l.Next.ServeHTTP(responseRecorder, r) if status >= 400 { // There was an error up the chain, but no response has been written yet. // The error must be handled here so the log entry will record the response size. if l.ErrorFunc != nil { l.ErrorFunc(responseRecorder, r, status) } else { // Default failover error handler responseRecorder.WriteHeader(status) fmt.Fprintf(responseRecorder, "%d %s", status, http.StatusText(status)) } status = 0 } // Write log entry rule.Log.Println(rep.Replace(rule.Format)) return status, err } } return l.Next.ServeHTTP(w, r) }
func TestReverseProxy(t *testing.T) { log.SetOutput(ioutil.Discard) defer log.SetOutput(os.Stderr) var requestReceived bool backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { requestReceived = true w.Write([]byte("Hello, client")) })) defer backend.Close() // set up proxy p := &Proxy{ Next: httpserver.EmptyNext, // prevents panic in some cases when test fails Upstreams: []Upstream{newFakeUpstream(backend.URL, false)}, } // create request and response recorder r, err := http.NewRequest("GET", "/", nil) if err != nil { t.Fatalf("Failed to create request: %v", err) } w := httptest.NewRecorder() p.ServeHTTP(w, r) if !requestReceived { t.Error("Expected backend to receive request, but it didn't") } // Make sure {upstream} placeholder is set rr := httpserver.NewResponseRecorder(httptest.NewRecorder()) rr.Replacer = httpserver.NewReplacer(r, rr, "-") p.ServeHTTP(rr, r) if got, want := rr.Replacer.Replace("{upstream}"), backend.URL; got != want { t.Errorf("Expected custom placeholder {upstream} to be set (%s), but it wasn't; got: %s", want, got) } }