Skip to content

Commit 8db0c20

Browse files
net/http: add Server.DisableGeneralOptionsHandler for custom handling of OPTIONS *
Fixes #41773
1 parent b6c1606 commit 8db0c20

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

src/net/http/serve_test.go

+38
Original file line numberDiff line numberDiff line change
@@ -3491,6 +3491,44 @@ func TestOptions(t *testing.T) {
34913491
}
34923492
}
34933493

3494+
func TestOptionsHandler(t *testing.T) {
3495+
rc := make(chan *Request, 1)
3496+
3497+
ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
3498+
rc <- r
3499+
}))
3500+
ts.Config.DisableGeneralOptionsHandler = true
3501+
ts.Start()
3502+
defer ts.Close()
3503+
3504+
conn, err := net.Dial("tcp", ts.Listener.Addr().String())
3505+
if err != nil {
3506+
t.Fatal(err)
3507+
}
3508+
defer conn.Close()
3509+
3510+
_, err = conn.Write([]byte("OPTIONS * HTTP/1.1\r\nHost: foo.com\r\n\r\n"))
3511+
if err != nil {
3512+
t.Fatal(err)
3513+
}
3514+
res, err := ReadResponse(bufio.NewReader(conn), &Request{Method: "OPTIONS"})
3515+
if err != nil {
3516+
t.Fatal(err)
3517+
}
3518+
if res.StatusCode != 200 {
3519+
t.Errorf("Got non-200 response to OPTIONS *: %#v", res)
3520+
}
3521+
3522+
select {
3523+
case got := <-rc:
3524+
if got.Method != "OPTIONS" || got.RequestURI != "*" {
3525+
t.Errorf("Expected OPTIONS * request, got %v", got)
3526+
}
3527+
case <-time.After(5 * time.Second):
3528+
t.Error("timeout")
3529+
}
3530+
}
3531+
34943532
// Tests regarding the ordering of Write, WriteHeader, Header, and
34953533
// Flush calls. In Go 1.0, rw.WriteHeader immediately flushed the
34963534
// (*response).header to the wire. In Go 1.1, the actual wire flush is

src/net/http/server.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -2596,6 +2596,10 @@ type Server struct {
25962596

25972597
Handler Handler // handler to invoke, http.DefaultServeMux if nil
25982598

2599+
// DisableGeneralOptionsHandler, if true, passes "OPTIONS *" requests to the Handler,
2600+
// otherwise responds with 200 OK and Content-Length: 0.
2601+
DisableGeneralOptionsHandler bool
2602+
25992603
// TLSConfig optionally provides a TLS configuration for use
26002604
// by ServeTLS and ListenAndServeTLS. Note that this value is
26012605
// cloned by ServeTLS and ListenAndServeTLS, so it's not
@@ -2922,7 +2926,7 @@ func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
29222926
if handler == nil {
29232927
handler = DefaultServeMux
29242928
}
2925-
if req.RequestURI == "*" && req.Method == "OPTIONS" {
2929+
if !sh.srv.DisableGeneralOptionsHandler && req.RequestURI == "*" && req.Method == "OPTIONS" {
29262930
handler = globalOptionsHandler{}
29272931
}
29282932

0 commit comments

Comments
 (0)