Skip to content

net/http: support adding client certificate also for http/2 #18017

Closed
@balboah

Description

@balboah

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

1.7.3

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

darwin amd64

What did you do?

My first attempt to use a TLS client certificate for authenticating towards a http/2 only server looked something like this:

	cert, err := tls.LoadX509KeyPair(pub, key)
	if err != nil {
		return err
	}
	config := &tls.Config{
		Certificates: []tls.Certificate{cert},
	}
	config.BuildNameToCertificate()

	tr := http.Transport{
		TLSClientConfig: config,
	}
	client := &http.Client{
		Transport: &tr,
	}

	res, err := client.Do(req)

This code results in a HTTP/1.1 transport.

My 2nd attempt was to also define the NextProto:

	config := &tls.Config{
		Certificates: []tls.Certificate{cert},
		NextProtos: []string{"h2"},
	}

What did you expect to see?

I expected the http/2 upgrade to work seamlessly even with my custom client certificate specified.
This is how I've been authenticating with previous HTTP versions, I didn't expect the API to change.

What did you see instead?

Since the targeted server only supports HTTP/2, the returned request error was rather confusing:
malformed HTTP status code "client".

After reading the source of how the transport handling works for h2, I found these lines in net/http/transport.go:

   200		if t.TLSClientConfig != nil || t.Dial != nil || t.DialTLS != nil {
   201			// Be conservative and don't automatically enable
   202			// http2 if they've specified a custom TLS config or
   203			// custom dialers. Let them opt-in themselves via
   204			// http2.ConfigureTransport so we don't surprise them
   205			// by modifying their tls.Config. Issue 14275.
   206			return
   207		}

It refers to http2.ConfigureTransport, which is part of the external import golang.org/x/net/http2.
Importing and using this on my transport indeed fixed my problem.

To my surprise, I could not find any exported functionality in the standard library like this. I feel that it should be there, to make the http/2 client support complete.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DocumentationIssues describing a change to documentation.FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions