Nehmen wir an, ich habe eine Middleware in Go, wo ich alle vorhandenen Server
Header mit meinem eigenen Wert überschreiben will.Kontrolle HTTP-Header von äußeren Go Middleware
// Server attaches a Server header to the response.
func Server(h http.Handler, serverName string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Server", serverName)
h.ServeHTTP(w, r)
})
}
Dann füge ich es auf eine Antwort Kette wie diese
http.Handle("/", authHandler)
http.ListenAndServe(":8000", Server(http.DefaultServeMux, "myapp"))
Leider, wenn die authHandler oder durch DefaultServeMux behandelt etwas nennt w.Header().Add("Server", "foo")
(wie, sagen wir, httputil.ReverseProxy.ServeHTTP), I mit zwei Server am Ende Header in der Antwort.
$ http localhost:5962/v1/hello_world
HTTP/1.1 200 OK
Content-Length: 11
Content-Type: text/plain
Date: Tue, 12 Jul 2016 04:54:04 GMT
Server: inner-middleware
Server: myapp
Was ich wirklich möchte etwas wie folgt aus:
// Server attaches a Server header to the response.
func Server(h http.Handler, serverName string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(w, r)
w.Header().Set("Server", serverName)
})
}
Dies ist jedoch disallowed by the semantics of ServeHTTP:
ServeHTTP sollte Antwort-Header und Daten an die ResponseWriter und dann wieder schreiben. Rückgabe von Signalen, dass die Anfrage beendet ist; Es ist nicht zulässig, den AntwortWriter zu verwenden oder von der Request.Body nach oder gleichzeitig mit dem Abschluss des ServeHTTP-Aufrufs zu lesen.
Ich habe einige ziemlich hässlich Hacks um dies zu sehen, zum Beispiel den Code in httputil.ReverseProxy.ServeHTTP, die Kopien von Kopf- und umschreibt den Antwortcode oder mit httptest.ResponseRecorder, die den ganzen Körper in ein Byte-Puffer liest.
Ich könnte auch die traditionelle Middleware-Reihenfolge umkehren und meine Server-Middleware zuletzt, irgendwie, oder machen es die innerste Middleware.
Gibt es eine einfache Methode, die ich vermisse?
Dies ist ein perfektes Beispiel für Overengineering. Wirklich alles, was Sie tun müssen, ist die Stelle zu ändern, an der der Header geschrieben wird, und sie vor dem Aufruf von WriteHeader() zu schreiben. – dlsniper
Ich bin wirklich verwirrt von Ihrem Kommentar. Es ist unmöglich, eine interne Middleware von einer äußeren Middleware zu überschreiben. In diesem Fall rufe ich httputil.ReverseProxy.ServeHTTP zum Proxy an, den ich nicht kontrolliere. ReverseProxy.ServeHTTP ruft WriteHeader auf, was auch immer der Proxy zurückgibt; Ich kann das nicht kontrollieren. –
@Dlsniper müssen Sie die Frage mein Freund erneut lesen – Kugel