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

Support unencrypted HTTP/2 connections (i.e. h2c) #970

Open
na-- opened this issue Mar 21, 2019 · 15 comments
Open

Support unencrypted HTTP/2 connections (i.e. h2c) #970

na-- opened this issue Mar 21, 2019 · 15 comments
Labels
enhancement evaluation needed proposal needs to be validated or tested before fully implementing it in k6 help wanted new-http issues that would require (or benefit from) a new HTTP API refactor

Comments

@na--
Copy link
Member

na-- commented Mar 21, 2019

As seen in this forum question, previously the k6 docs indirectly mentioned support for h2c (HTTP/2 over cleartext TCP) connections. That was incorrect and I've fixed the docs to reflect that, but I'm also adding this issue so we can actually add support for it in the future. Please, add a 👍 here if you have a use case for h2c support in k6.

From a technical standpoint, we should likely do something like this. The problem is comes from the fact, that we rely on a preconfigured http.Transport from the Go stdlib, which we pass through http2.ConfigureTransport(transport) from golang.org/x/net/http2. We can't directly use the http2.Transport from the example above, because it doesn't contain a bunch of the options that http.Transport has and that we use...

Related issues:

@mstoykov
Copy link
Contributor

mstoykov commented Apr 5, 2019

Yoshi at the community forum suggested we add something like this curl flag.

1 similar comment
@mstoykov
Copy link
Contributor

mstoykov commented Apr 5, 2019

Yoshi at the community forum suggested we add something like this curl flag.

@na--
Copy link
Member Author

na-- commented Jun 12, 2019

A proposal on how something like this (among other things) could be implemented in k6 in a backwards compatible and reasonably performant and user-friendly way: #1045 (comment)

imiric pushed a commit that referenced this issue Sep 23, 2019
The hanging behavior described in #971 happens after this Golang change:
golang/go@5416204
, released in 1.12. If a `101 Switching Protocols` response is received,
`response.Body` will be replaced by an underlying `net.Conn`, and
reading it blocks indefinitely without a protocol implementation.

This is not a big problem for k6 in this case, since we don't support
protocol upgrades with the current HTTP API as shown in the example, so
the agreed solution was to detect it and return an error.

This Golang change is currently incompatible with client timeouts[1],
though this will hopefully be resolved by the time we add support for
h2c (#970) or other protocols.

[1]: golang/go#31391

Closes #971
imiric pushed a commit that referenced this issue Sep 24, 2019
The hanging behavior described in #971 happens after this Golang change:
golang/go@5416204
, released in 1.12. If a `101 Switching Protocols` response is received,
`response.Body` will be replaced by an underlying `net.Conn`, and
reading it blocks indefinitely without a protocol implementation.

This is not a big problem for k6 in this case, since we don't support
protocol upgrades with the current HTTP API as shown in the example, so
the agreed solution was to detect it and return an error.

This Golang change is currently incompatible with client timeouts[1],
though this will hopefully be resolved by the time we add support for
h2c (#970) or other protocols.

[1]: golang/go#31391

Closes #971
imiric pushed a commit that referenced this issue Sep 26, 2019
The hanging behavior described in #971 happens after this Golang change:
golang/go@5416204
, released in 1.12. If a `101 Switching Protocols` response is received,
`response.Body` will be replaced by an underlying `net.Conn`, and
reading it blocks indefinitely without a protocol implementation.

This is not a big problem for k6 in this case, since we don't support
protocol upgrades with the current HTTP API as shown in the example, so
the agreed solution was to detect it and return an error.

This Golang change is currently incompatible with client timeouts[1],
though this will hopefully be resolved by the time we add support for
h2c (#970) or other protocols.

[1]: golang/go#31391

Closes #971
imiric pushed a commit that referenced this issue Sep 26, 2019
The hanging behavior described in #971 happens after this Golang change:
golang/go@5416204
, released in 1.12. If a `101 Switching Protocols` response is received,
`response.Body` will be replaced by an underlying `net.Conn`, and
reading it blocks indefinitely without a protocol implementation.

This is not a big problem for k6 in this case, since we don't support
protocol upgrades with the current HTTP API as shown in the example, so
the agreed solution was to detect it and return an error.

This Golang change is currently incompatible with client timeouts[1],
though this will hopefully be resolved by the time we add support for
h2c (#970) or other protocols.

[1]: golang/go#31391

Closes #971
cuonglm pushed a commit that referenced this issue Oct 15, 2019
The hanging behavior described in #971 happens after this Golang change:
golang/go@5416204
, released in 1.12. If a `101 Switching Protocols` response is received,
`response.Body` will be replaced by an underlying `net.Conn`, and
reading it blocks indefinitely without a protocol implementation.

This is not a big problem for k6 in this case, since we don't support
protocol upgrades with the current HTTP API as shown in the example, so
the agreed solution was to detect it and return an error.

This Golang change is currently incompatible with client timeouts[1],
though this will hopefully be resolved by the time we add support for
h2c (#970) or other protocols.

[1]: golang/go#31391

Closes #971
@RoySunnySean007
Copy link

Dear @na-- ,

Do we have any plan to support h2c connections?
Currently our servers are migration to h2c....

Thanks,
Roy

@na--
Copy link
Member Author

na-- commented Apr 14, 2021

@RoySunnySean007, I thought this was impossible to fix without either a breaking change, or a new k6/http API that allows users to select a custom Transport for their requests, because of the way we set up HTTP/2 support I explained in the top post.

However, I had another look, and it seems like things have changed recently on the Go side, with the introduction of a http2.ConfigureTransports() function that returns the new Transport: golang/net@08b3837

With this change, we may be able to configure support for h2c on the k6 side, without any breaking changes, though it's far from certain. We have to research some more, since the documentation for the AllowHTTP property of the http2.Transport explicitly says Note that this does not enable h2c support 😕

@na-- na-- added the evaluation needed proposal needs to be validated or tested before fully implementing it in k6 label Apr 14, 2021
@na-- na-- added this to the v0.33.0 milestone Apr 14, 2021
@RoySunnySean007
Copy link

Thanks @na-- !
Looking forward to the solution or work around~
Otherwise it will be disaster for us...

@na--
Copy link
Member Author

na-- commented Apr 14, 2021

Out of curiosity, why are you migrating to h2c? I thought that was a very marginal use case for HTTP/2... 😕

@RoySunnySean007
Copy link

Dear @na-- ,

There are additional CPU cost if we use HTTP/2 directly, so dev team decided to use h2c which is not friendly for us to conduct load test...:(

@ChristianSieboerger
Copy link

Hi @na-- ,

One more reason to support h2c is that h2c is used also in 5G Stand-Alone networks by some mobile operators.

BR,
Christian

@RoySunnySean007
Copy link

Dear @na-- ,

We found we can use curl --http2-prior-knowledge (Tells curl to issue its non-TLS HTTP requests using HTTP/2 without HTTP/1.1 Upgrade) to access our h2c spring boot server.

We tried to change AllowHTTP to true in https://github.com/golang/net/blob/master/http2/transport.go, but it doesn't work.

Do you have any suggestions? Thx in advance!

Thanks,
Roy

@na--
Copy link
Member Author

na-- commented Apr 15, 2021

It seems like you'd also have to overwrite the DialTLS method with a normal non-TLS dialing... 😞 See this for example.

Which probably makes it somewhat impossible to have a single HTTP client that supports both HTTP/2 with TLS as well as H2C 😞

@RoySunnySean007
Copy link

RoySunnySean007 commented Apr 15, 2021

Dear @na--

This is what we changed: https://github.com/k6io/k6/pull/1968/files
Seems it doesn't work, could u pls kindly help to have a look?
I will close this PR once you have checked it, thx!

Actually for us, we only need to support HTTP/2 w/o TLS

Thanks,
Roy

@na--
Copy link
Member Author

na-- commented Apr 19, 2021

@RoySunnySean007, I commented in the PR, but I haven't delved deeply in the Go HTTP/2 and H2C code to see exactly if my comment would resolve your issues. I suggest experimenting and reading up on the Go HTTP/2 docs in https://pkg.go.dev/golang.org/x/net/http2, but please do not submit a PR unless you figure out some way to make the change in a backwards-compatible manner.

@RoySunnySean007
Copy link

Sure, thx @na-- for teaching me !

@na-- na-- removed this from the v0.33.0 milestone Apr 21, 2021
@na-- na-- added the new-http issues that would require (or benefit from) a new HTTP API label Oct 18, 2021
@andreas-hakansson-ingka

Hi

I'd also love it if this was possible. Could there be a setting to allow us to control the AllowHTTP flag, of the http2.Transport, as mentioned at the bottom of this gist? https://github.com/thrawn01/h2c-golang-example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement evaluation needed proposal needs to be validated or tested before fully implementing it in k6 help wanted new-http issues that would require (or benefit from) a new HTTP API refactor
Projects
None yet
Development

No branches or pull requests

5 participants