Commit 7bebc6b7 authored by Filippo Valsorda's avatar Filippo Valsorda

net/http: fix and normalize the [Server.][ListenAnd]Serve[TLS] docs

The only inaccurate part was the HTTP/2 caveat in Server.ServeTLS, which
only applies to the plain Serve variant.

The restriction implemented in shouldConfigureHTTP2ForServe is not on
the setupHTTP2_ServeTLS codepath because ServeTLS owns the tls.Listener,
so we fix it for the user instead of disabling HTTP/2.

Fixes #24607

Change-Id: Ie5f207d0201f09db27bf81b75535e5f6fdaf91e2
Reviewed-on: https://go-review.googlesource.com/103815Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent fe68ab3b
...@@ -137,3 +137,25 @@ func ExampleServer_Shutdown() { ...@@ -137,3 +137,25 @@ func ExampleServer_Shutdown() {
<-idleConnsClosed <-idleConnsClosed
} }
func ExampleListenAndServeTLS() {
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "Hello, TLS!\n")
})
// One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.
log.Printf("About to listen on 8443. Go to https://127.0.0.1:8443/")
err := http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", nil)
log.Fatal(err)
}
func ExampleListenAndServe() {
// Hello world, the web server
helloHandler := func(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "Hello, world!\n")
}
http.HandleFunc("/hello", helloHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
...@@ -2419,8 +2419,7 @@ func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) { ...@@ -2419,8 +2419,7 @@ func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
// creating a new service goroutine for each. The service goroutines // creating a new service goroutine for each. The service goroutines
// read requests and then call handler to reply to them. // read requests and then call handler to reply to them.
// //
// The handler is typically nil, in which case the DefaultServeMux is // The handler is typically nil, in which case the DefaultServeMux is used.
// used.
// //
// HTTP/2 support is only enabled if the Listener returns *tls.Conn // HTTP/2 support is only enabled if the Listener returns *tls.Conn
// connections and they were configured with "h2" in the TLS // connections and they were configured with "h2" in the TLS
...@@ -2436,12 +2435,14 @@ func Serve(l net.Listener, handler Handler) error { ...@@ -2436,12 +2435,14 @@ func Serve(l net.Listener, handler Handler) error {
// creating a new service goroutine for each. The service goroutines // creating a new service goroutine for each. The service goroutines
// read requests and then call handler to reply to them. // read requests and then call handler to reply to them.
// //
// Handler is typically nil, in which case the DefaultServeMux is used. // The handler is typically nil, in which case the DefaultServeMux is used.
// //
// Additionally, files containing a certificate and matching private key // Additionally, files containing a certificate and matching private key
// for the server must be provided. If the certificate is signed by a // for the server must be provided. If the certificate is signed by a
// certificate authority, the certFile should be the concatenation // certificate authority, the certFile should be the concatenation
// of the server's certificate, any intermediates, and the CA's certificate. // of the server's certificate, any intermediates, and the CA's certificate.
//
// ServeTLS always returns a non-nil error.
func ServeTLS(l net.Listener, handler Handler, certFile, keyFile string) error { func ServeTLS(l net.Listener, handler Handler, certFile, keyFile string) error {
srv := &Server{Handler: handler} srv := &Server{Handler: handler}
return srv.ServeTLS(l, certFile, keyFile) return srv.ServeTLS(l, certFile, keyFile)
...@@ -2751,8 +2752,11 @@ func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) { ...@@ -2751,8 +2752,11 @@ func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
// ListenAndServe listens on the TCP network address srv.Addr and then // ListenAndServe listens on the TCP network address srv.Addr and then
// calls Serve to handle requests on incoming connections. // calls Serve to handle requests on incoming connections.
// Accepted connections are configured to enable TCP keep-alives. // Accepted connections are configured to enable TCP keep-alives.
//
// If srv.Addr is blank, ":http" is used. // If srv.Addr is blank, ":http" is used.
// ListenAndServe always returns a non-nil error. //
// ListenAndServe always returns a non-nil error. After Shutdown or Close,
// the returned error is ErrServerClosed.
func (srv *Server) ListenAndServe() error { func (srv *Server) ListenAndServe() error {
if srv.shuttingDown() { if srv.shuttingDown() {
return ErrServerClosed return ErrServerClosed
...@@ -2867,10 +2871,6 @@ func (srv *Server) Serve(l net.Listener) error { ...@@ -2867,10 +2871,6 @@ func (srv *Server) Serve(l net.Listener) error {
// certFile should be the concatenation of the server's certificate, // certFile should be the concatenation of the server's certificate,
// any intermediates, and the CA's certificate. // any intermediates, and the CA's certificate.
// //
// For HTTP/2 support, srv.TLSConfig should be initialized before
// calling ServeTLS and must contain the string "h2" in its NextProtos
// field.
//
// ServeTLS always returns a non-nil error. After Shutdown or Close, the // ServeTLS always returns a non-nil error. After Shutdown or Close, the
// returned error is ErrServerClosed. // returned error is ErrServerClosed.
func (srv *Server) ServeTLS(l net.Listener, certFile, keyFile string) error { func (srv *Server) ServeTLS(l net.Listener, certFile, keyFile string) error {
...@@ -3000,32 +3000,11 @@ func logf(r *Request, format string, args ...interface{}) { ...@@ -3000,32 +3000,11 @@ func logf(r *Request, format string, args ...interface{}) {
} }
} }
// ListenAndServe listens on the TCP network address addr // ListenAndServe listens on the TCP network address addr and then calls
// and then calls Serve with handler to handle requests // Serve with handler to handle requests on incoming connections.
// on incoming connections.
// Accepted connections are configured to enable TCP keep-alives. // Accepted connections are configured to enable TCP keep-alives.
// Handler is typically nil, in which case the DefaultServeMux is
// used.
//
// A trivial example server is:
//
// package main
//
// import (
// "io"
// "net/http"
// "log"
// )
// //
// // hello world, the web server // The handler is typically nil, in which case the DefaultServeMux is used.
// func HelloServer(w http.ResponseWriter, req *http.Request) {
// io.WriteString(w, "hello, world!\n")
// }
//
// func main() {
// http.HandleFunc("/hello", HelloServer)
// log.Fatal(http.ListenAndServe(":12345", nil))
// }
// //
// ListenAndServe always returns a non-nil error. // ListenAndServe always returns a non-nil error.
func ListenAndServe(addr string, handler Handler) error { func ListenAndServe(addr string, handler Handler) error {
...@@ -3038,36 +3017,13 @@ func ListenAndServe(addr string, handler Handler) error { ...@@ -3038,36 +3017,13 @@ func ListenAndServe(addr string, handler Handler) error {
// matching private key for the server must be provided. If the certificate // matching private key for the server must be provided. If the certificate
// is signed by a certificate authority, the certFile should be the concatenation // is signed by a certificate authority, the certFile should be the concatenation
// of the server's certificate, any intermediates, and the CA's certificate. // of the server's certificate, any intermediates, and the CA's certificate.
//
// A trivial example server is:
//
// import (
// "log"
// "net/http"
// )
//
// func handler(w http.ResponseWriter, req *http.Request) {
// w.Header().Set("Content-Type", "text/plain")
// w.Write([]byte("This is an example server.\n"))
// }
//
// func main() {
// http.HandleFunc("/", handler)
// log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/")
// err := http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil)
// log.Fatal(err)
// }
//
// One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.
//
// ListenAndServeTLS always returns a non-nil error.
func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error { func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {
server := &Server{Addr: addr, Handler: handler} server := &Server{Addr: addr, Handler: handler}
return server.ListenAndServeTLS(certFile, keyFile) return server.ListenAndServeTLS(certFile, keyFile)
} }
// ListenAndServeTLS listens on the TCP network address srv.Addr and // ListenAndServeTLS listens on the TCP network address srv.Addr and
// then calls Serve to handle requests on incoming TLS connections. // then calls ServeTLS to handle requests on incoming TLS connections.
// Accepted connections are configured to enable TCP keep-alives. // Accepted connections are configured to enable TCP keep-alives.
// //
// Filenames containing a certificate and matching private key for the // Filenames containing a certificate and matching private key for the
...@@ -3110,8 +3066,8 @@ func (srv *Server) setupHTTP2_ServeTLS() error { ...@@ -3110,8 +3066,8 @@ func (srv *Server) setupHTTP2_ServeTLS() error {
// setupHTTP2_Serve is called from (*Server).Serve and conditionally // setupHTTP2_Serve is called from (*Server).Serve and conditionally
// configures HTTP/2 on srv using a more conservative policy than // configures HTTP/2 on srv using a more conservative policy than
// setupHTTP2_ServeTLS because Serve may be called // setupHTTP2_ServeTLS because Serve is called after tls.Listen,
// concurrently. // and may be called concurrently. See shouldConfigureHTTP2ForServe.
// //
// The tests named TestTransportAutomaticHTTP2* and // The tests named TestTransportAutomaticHTTP2* and
// TestConcurrentServerServe in server_test.go demonstrate some // TestConcurrentServerServe in server_test.go demonstrate some
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment