Skip to content

x/net/http2: should interpret Connection: close request header as Request.Close = true #14227

@admtnnr

Description

@admtnnr

Related to #14214, it doesn't seem possible to explicitly set a protocol version when sending via an http.Transport and this breaks when sending requests with certain headers to servers supporting HTTP2. As an example, the following encounters the same 400 error from the GFE as we were previously seeing with the Proxy-Connection header:

package main

import (
    "net/http"
    "net/url"
    "os"
)

func main() {
    req := &http.Request{
        Method: "GET",
        URL: &url.URL{
            Scheme: "https",
            Host:   "www.google.co.uk",
            Path:   "/",
        },
        ProtoMajor: 1,
        ProtoMinor: 1,
        Proto:      "HTTP/1.1",
        Host:       "www.google.co.uk",
        Header: http.Header{
            "Connection": []string{"close"},
        },
    }
    req.Write(os.Stdout)

    // Uncomment to Nerf HTTP2 support and the request succeeds.
    // http.DefaultTransport.(*http.Transport).TLSNextProto = make(map[string]func(string, *tls.Conn) http.RoundTripper)

    res, err := http.DefaultTransport.RoundTrip(req)
    if err != nil {
        panic(err)
    }
    res.Write(os.Stdout)
}

// Example:
// GET / HTTP/1.1
// Host: www.google.co.uk
// User-Agent: Go-http-client/1.1
// Connection: close
//
// HTTP/2.0 400 Bad Request
// Content-Length: 54
// Content-Type: text/html; charset=UTF-8
// Date: Thu, 04 Feb 2016 14:37:38 GMT
// Server: GFE/2.0
//
// <html><title>Error 400 (Bad Request)!!1</title></html>

For non-HTTP2 requests the Connection header is perfectly valid, but when upgraded by http.Transport to HTTP2 they become invalid and break.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions