7

I have a Go server handling https requests:

package main
import (
        "fmt"
        "net/http"
        "log"
)
const (
        port       = "5966"
        cert       = "/tmp/cert.pem"
        key        = "/tmp/key.pem"
)
func main() {

        listen_at := ":" + port
        fmt.Println("Listening at", listen_at)
        go http.HandleFunc("/job_handler/", job_handler)
        log.Fatal(http.ListenAndServeTLS(listen_at, cert, key, nil))
}
func job_handler(w http.ResponseWriter, r *http.Request) {
       // do somework
}

Turns out in https mode, Go has transparent support for the HTTP/2 protocol. We've some clients that noticeably misbehave in HTTP/2, and hence we need to disable HTTP/2 on the server side.

Unfortunately, I can't use ENV variable GODEBUG=http2server=0 to disable HTTP/2. What's left is Server.TLSNextProto as documented here.

How can I use Server.TLSNextProto on my server code above to disable https/2?

1
  • It says it right there in the docs you linked: "Programs that must disable HTTP/2 can do so by setting Server.TLSNextProto to a non-nil, empty map." What's unclear about that? Commented Sep 24, 2019 at 22:57

2 Answers 2

12

The simplest setup that disables HTTP/2 is

package main

import (
    "log"
    "net/http"
    "crypto/tls"
)

func main() {

    m := http.NewServeMux()

    srv := &http.Server{
        Handler:      m,
        Addr:         "127.0.0.1:8080",
        TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler)),
    }

    log.Fatal(srv.ListenAndServe())

}

You can verify the support with

curl -v --http2-prior-knowledge http://localhost:8080
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you, and +1 for the curl verification tip!
Grzegorz can you tell me how that command verifies that HTTP2 is disabled? I am trying to disable HTTP2 in this manner, and the equivalent curl command is telling me "Connection state changed (HTTP/2 confirmed)" and then "Failed sending HTTP2 data, * nghttp2_session_send() failed: The user callback function failed(-902)" Is this what I should see? It sounds to me like this method has not in fact disabled HTTP2. Thanks.
@MartinDelVecchio The command parameters tells curl to use HTTP/2 protocol only. If the tool fails to communicate with server it means that HTTP/2 is not available. It is what we wanted to achieve.
OK. I am seeing the same errors when I don't tell curl to use HTTP2. When I explicitly tell it to use HTTP 1.1, I get success. But when I don't tell it, it tries HTTP2, fails, and returns an error.
1

Just an update since the OP said:

Unfortunately, I can't use ENV variable GODEBUG=http2server=0

In Go 1.21 and later you can just add //go:debug http2server=0 at the top of any source file of the main package. See The Go Blog

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.