diff --git a/api/next/41773.txt b/api/next/41773.txt new file mode 100644 index 0000000000000..116596e73ea9d --- /dev/null +++ b/api/next/41773.txt @@ -0,0 +1 @@ +pkg net/http, type Server struct, DisableGeneralOptionsHandler bool #41773 diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go index f956e66c44d44..d28bfba759258 100644 --- a/src/net/http/serve_test.go +++ b/src/net/http/serve_test.go @@ -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 diff --git a/src/net/http/server.go b/src/net/http/server.go index eedc4e9db9471..47b6070e1a7c0 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go @@ -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{} }