Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http: http.ListenAndServeTLS lowercasing request header keys #15472

Closed
deankarn opened this issue Apr 27, 2016 · 3 comments

Comments

Projects
None yet
3 participants
@deankarn
Copy link

commented Apr 27, 2016

Please answer these questions before submitting your issue. Thanks!

  1. What version of Go are you using (go version)?
go version go1.6.2 darwin/amd64
  1. What operating system and processor architecture are you using (go env)?
GOARCH="amd64"
GOBIN="/Users/dean/.go/bin"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/dean/.go"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.6.2/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.6.2/libexec/pkg/tool/darwin_amd64"
GO15VENDOREXPERIMENT="1"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fno-common"
CXX="clang++"
CGO_ENABLED="1"
  1. What did you do?

unfortunately I could not make a runnable example, a valid SSL Certificate seems to be needed to recreate this issue, using:

tr := &http.Transport{
    TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}

client := &http.Client{Transport: tr}

or

tlsConfig := &tls.Config{
    Certificates: make([]tls.Certificate, 1),
}

tlsConfig.Certificates[0], err = tls.X509KeyPair([]byte(httpPem), []byte(httpKey))
if err != nil {
    log.Fatal(err)
}
server = &http.Server{Addr: port, Handler: handler, TLSConfig: tlsConfig}
server.ListenAndServeTLS("","")

the issue does not occur, only using the http.ListenAndServerTLS that I could find so far. below is what causes the issue (need to use your own Cretificates + URL.

package main

import (
    "errors"
    "fmt"
    "log"
    "net/http"
    "time"
)

func main() {
    go server()

    time.Sleep(3000)

    req, err := http.NewRequest("GET", "https://localhost:8080", nil)
    if err != nil {
        log.Fatal(errors.New("Error Creating Request:" + err.Error()))
    }

    req.Header.Set("UPDATE_API_KEY", "Efewfjnewjkfewjkfew")

    // tr := &http.Transport{
    //  TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    // }

    // client := &http.Client{Transport: tr}

    // This issue is very specific, using the code above actually works as expected
    client := &http.Client{}

    _, err = client.Do(req)
    if err != nil {
        log.Fatal(fmt.Sprint("ERROR Fetching Updates:", err))
    }
}

func server() {

    handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Println(r.Header)
    })

    http.ListenAndServeTLS(":8080", "path to certFile", "path to keyFile", handler)
}

Go 1.6 does not have this issue, either patch 1.6.1 or 1.6.2 caused this.

  1. What did you expect to see?
map[User-Agent:[Go-http-client/1.1] UPDATE_API_KEY:[Efewfjnewjkfewjkfew] Accept-Encoding:[gzip]]

map key of "UPDATE_API_KEY" is correct
  1. What did you see instead?
map[Accept-Encoding:[gzip] User-Agent:[Go-http-client/2.0] update_api_key:[Efewfjnewjkfewjkfew]]

map key of "update_api_key" is not correct
@bradfitz

This comment has been minimized.

Copy link
Member

commented Apr 27, 2016

The difference is HTTP/2. With HTTP/2, all header fields must be sent lowercase, mandated by the spec. In HTTP/1 any case is allowed, and they should be compared case-insensitively.

Go tries to map things into their Go-canonical form via https://golang.org/pkg/net/http/#CanonicalHeaderKey but because it has an underscore in it, Go does nothing (but fixed in Go 1.7).

I'd recommend using a hyphen instead of an underscore if possible. Otherwise you'll have to enumerate over the map keys looking for the "UpDaTE_api_KEY" yourself, normalizing the case of the keys as you look.

@bradfitz

This comment has been minimized.

Copy link
Member

commented Apr 27, 2016

Btw, b24c6fb (issue #13767) was the commit which fixed this. It will be included in Go 1.7.

@deankarn

This comment has been minimized.

Copy link
Author

commented Apr 27, 2016

Thanks 👍

@deankarn deankarn closed this Apr 27, 2016

@golang golang locked and limited conversation to collaborators Apr 27, 2017

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.