Skip to content

Commit 05ff045

Browse files
AlexanderYastrebovneild
authored andcommitted
net/http: add Server.DisableOptionsHandler for custom handling of OPTIONS *
Fixes #41773 Change-Id: I432ad5410d5e3bb0aff3a6e0eea6906ab1b214e2 GitHub-Last-Rev: 57d1ee2 GitHub-Pull-Request: #49014 Reviewed-on: https://go-review.googlesource.com/c/go/+/356410 Reviewed-by: Brad Fitzpatrick <[email protected]> Run-TryBot: hopehook <[email protected]> Reviewed-by: Damien Neil <[email protected]> Reviewed-by: Robert Griesemer <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent f7e6986 commit 05ff045

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

api/next/41773.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pkg net/http, type Server struct, DisableGeneralOptionsHandler bool #41773

src/net/http/serve_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3492,6 +3492,37 @@ func TestOptions(t *testing.T) {
34923492
}
34933493
}
34943494

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

src/net/http/server.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2584,6 +2584,10 @@ type Server struct {
25842584

25852585
Handler Handler // handler to invoke, http.DefaultServeMux if nil
25862586

2587+
// DisableGeneralOptionsHandler, if true, passes "OPTIONS *" requests to the Handler,
2588+
// otherwise responds with 200 OK and Content-Length: 0.
2589+
DisableGeneralOptionsHandler bool
2590+
25872591
// TLSConfig optionally provides a TLS configuration for use
25882592
// by ServeTLS and ListenAndServeTLS. Note that this value is
25892593
// cloned by ServeTLS and ListenAndServeTLS, so it's not
@@ -2916,7 +2920,7 @@ func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
29162920
if handler == nil {
29172921
handler = DefaultServeMux
29182922
}
2919-
if req.RequestURI == "*" && req.Method == "OPTIONS" {
2923+
if !sh.srv.DisableGeneralOptionsHandler && req.RequestURI == "*" && req.Method == "OPTIONS" {
29202924
handler = globalOptionsHandler{}
29212925
}
29222926

0 commit comments

Comments
 (0)