Skip to content

net/http: add Server.OptionsHandler to allow custom handling of OPTIONS * #41773

@simonmittag

Description

@simonmittag

What version of Go are you using (go version)?

1.15.2

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/simonmittag/Library/Caches/go-build"
GOENV="/Users/simonmittag/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/simonmittag/projects/gopath/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/simonmittag/projects/gopath"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/opt/go/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/opt/go/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/fx/nx1t7v3s6xjc55_tvv1fkwgw0000gn/T/go-build132638656=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Global options requests are described here: https://tools.ietf.org/html/rfc7231#page-31

   An OPTIONS request with an asterisk ("*") as the request-target
   (Section 5.3 of [RFC7230]) applies to the server in general rather
   than to a specific resource.

Run this request against an instance of golang http.Server (I'm using this one: https://github.com/simonmittag/j8a/blob/master/server.go), like so:

curl -v -X OPTIONS --request-target '*' --http1.1 https://j8a.io

What did you see?

A canned response from net.http built-in serverHandler, bypassing any handlers I specify.

> OPTIONS * HTTP/1.1
> Host: j8a.io
> User-Agent: curl/7.72.0
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Length: 0
< Date: Sat, 03 Oct 2020 22:13:13 GMT

What did you expect to see?

Would like to customise the server response to this request and include "Allow" HTTP headers to limit the global HTTP methods made available by the server instance. However response for this request is hardcoded into net/http serverHandler: https://github.com/golang/go/blob/master/src/net/http/server.go, line 2859 which overrides handler with the built-in globalOptionsHandler

func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
	handler := sh.srv.Handler
	if handler == nil {
		handler = DefaultServeMux
	}
	if req.RequestURI == "*" && req.Method == "OPTIONS" {
		handler = globalOptionsHandler{}
	}
	handler.ServeHTTP(rw, req)
}

Can you allow users to specify this handler as an argument to http.Server?

server := &http.Server{
    GlobalOptionsHandler: myHandler,
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions