外部 Go ミドルウェアからの HTTP ヘッダーの制御
Go の HTTP ミドルウェアは、HTTP リクエストとレスポンスをインターセプトして変更する便利な方法を提供します。ただし、外部ミドルウェアからヘッダーを制御することは、重複を導入せずに既存のヘッダーをオーバーライドする必要があるため、困難な場合があります。
「Server」ヘッダーを設定する次のサーバー ミドルウェアを考えてみましょう:
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) }) }
このミドルウェアは応答チェーンに追加されると、「Server」ヘッダーを正常に設定します。ただし、チェーン内の他のハンドラーも "Server" ヘッダーを設定すると、ヘッダーが重複して応答が返されます。
この問題が発生するのは、ServeHTTP が要求の終了後に ResponseWriter への書き込みを明示的に禁止しているためです。 1 つのアプローチは、ヘッダーの書き込みをインターセプトし、最初の書き込みの前に「Server」ヘッダーを挿入するカスタム ResponseWriter を作成することです。
type serverWriter struct { w http.ResponseWriter name string wroteHeader bool } func (s serverWriter) WriteHeader(code int) { if s.wroteHeader == false { s.w.Header().Set("Server", s.name) s.wroteHeader = true } s.w.WriteHeader(code) } func (s serverWriter) Write(b []byte) (int, error) { return s.w.Write(b) } func (s serverWriter) Header() http.Header { return s.w.Header() } // 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) { sw := serverWriter{ w: w, name: serverName, wroteHeader: false, } h.ServeHTTP(sw, r) }) }
カスタム ResponseWriter を使用することで、「Server」ヘッダーが確実に追加されるようにすることができます。他のハンドラーの動作に関係なく、一度だけ。このアプローチでは追加の間接層が導入されますが、必要な機能は維持されます。
以上がGo ミドルウェアはどのようにして HTTP ヘッダーを重複なく確実に制御できるのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。