net/http: add Server.DisableOptionsHandler for custom handling of OPTIONS *

Fixes #41773

Change-Id: I432ad5410d5e3bb0aff3a6e0eea6906ab1b214e2
GitHub-Last-Rev: 57d1ee249d
GitHub-Pull-Request: golang/go#49014
Reviewed-on: https://go-review.googlesource.com/c/go/+/356410
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: hopehook <hopehook@qq.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Alexander Yastrebov 2022-08-14 09:56:34 +00:00 committed by Damien Neil
parent f7e6986d6b
commit 05ff045dfe
3 changed files with 37 additions and 1 deletions

1
api/next/41773.txt Normal file
View file

@ -0,0 +1 @@
pkg net/http, type Server struct, DisableGeneralOptionsHandler bool #41773

View file

@ -3492,6 +3492,37 @@ func TestOptions(t *testing.T) {
}
}
func TestOptionsHandler(t *testing.T) {
rc := make(chan *Request, 1)
ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
rc <- r
}))
ts.Config.DisableGeneralOptionsHandler = true
ts.Start()
defer ts.Close()
conn, err := net.Dial("tcp", ts.Listener.Addr().String())
if err != nil {
t.Fatal(err)
}
defer conn.Close()
_, err = conn.Write([]byte("OPTIONS * HTTP/1.1\r\nHost: foo.com\r\n\r\n"))
if err != nil {
t.Fatal(err)
}
select {
case got := <-rc:
if got.Method != "OPTIONS" || got.RequestURI != "*" {
t.Errorf("Expected OPTIONS * request, got %v", got)
}
case <-time.After(5 * time.Second):
t.Error("timeout")
}
}
// Tests regarding the ordering of Write, WriteHeader, Header, and
// Flush calls. In Go 1.0, rw.WriteHeader immediately flushed the
// (*response).header to the wire. In Go 1.1, the actual wire flush is

View file

@ -2584,6 +2584,10 @@ type Server struct {
Handler Handler // handler to invoke, http.DefaultServeMux if nil
// DisableGeneralOptionsHandler, if true, passes "OPTIONS *" requests to the Handler,
// otherwise responds with 200 OK and Content-Length: 0.
DisableGeneralOptionsHandler bool
// TLSConfig optionally provides a TLS configuration for use
// by ServeTLS and ListenAndServeTLS. Note that this value is
// cloned by ServeTLS and ListenAndServeTLS, so it's not
@ -2916,7 +2920,7 @@ func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
if handler == nil {
handler = DefaultServeMux
}
if req.RequestURI == "*" && req.Method == "OPTIONS" {
if !sh.srv.DisableGeneralOptionsHandler && req.RequestURI == "*" && req.Method == "OPTIONS" {
handler = globalOptionsHandler{}
}