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
TT-968 enabled h2c by default #3380
Conversation
…rl which should contains h2c://
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, we need a rebase
gateway/api_loader.go
Outdated
if strings.HasPrefix(spec.Proxy.TargetURL, "h2c://") { | ||
spec.Proxy.TargetURL = strings.Replace(spec.Proxy.TargetURL, "h2c://", "http://", 1) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are we replacing target scheme here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we treat h2c as alias to http. Probably should be followed by conned in source code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused, from reading h2c
is not http
traffic please see this doc comment https://pkg.go.dev/golang.org/x/net/http2/h2c#NewHandler
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This link actually has good description, saying that h2c is http1.1 compatible
gateway/api_loader.go
Outdated
@@ -763,6 +766,9 @@ func loadApps(specs []*APISpec) { | |||
shouldTrace := trace.IsEnabled() | |||
for _, spec := range specs { | |||
func() { | |||
if strings.Contains(spec.Proxy.TargetURL, "h2c://") { | |||
spec.Protocol = "h2c" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we check if spec.Protocol
is already set? If for instance spec.Protocol=http
and target is h2c
is that allowed? If not then spec is not valid we should emit an error or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gernest if http is set, and the target contains "h2c://" then it has major precedence, hence we set h2c as protocol. Also, I recall that from the very beggining we did this in this way due that FE doesn't have a protocol option h2c
. At this point we infer the protocol from the target url
gateway/proxy_muxer.go
Outdated
w: h.(*handleWrapper), | ||
h: h2c.NewHandler(h, &http2.Server{}), | ||
} | ||
// by default enabling h2c by wrapping handler in h2c. This ensures all features including tracing work |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very big assumptions. By default we provide http proxy, so h2c,tcp etc are special case. You explicitly set protocol to h2c inside loadApps why not check it here?. I see this will be a major source of headache.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gernest hi, can you elaborate regarding why it could be a major source of headache? currently by enabling h2c by default we're looking to simplify the process the most that we can
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sredxny
By design http2
is supposed to be served over TLS, h2c
is an edge case/optional that is not supported by major browsers.
The only use case for h2c
is when using gRPC
without tls, which is also an edge case. Why do we make edge cases default behaviour? Like I said before http/http2 is the only thing we should take for granted, we should let our customers to choose anything else
Please see this stackoverflow answer on why http2 should always be on TLS https://stackoverflow.com/a/46789195
currently by enabling h2c by default we're looking to simplify the process the most that we can
What process are you simplifying? A process of choosing protocol to use? Why this protocol: "h2c"
is not simple?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
protocol field require you to have separate gateway port, while in general there is no reasons for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the issue here is to remove the need for separate port?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general yes. The whole idea of h2c that it works though standard http protocol, and if special header found, it enable special mode which kinda emulate http2 by using http as transport.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changes done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
/release to release-3-lts |
Working on it! Note that it can take a few minutes. |
* fix grpc proxy connection * clean and format code * clean code * remove h2c config from gateway config * replace h2c protocol from url and set it as http * removed config enable_h2c at api level and infer it from the target url which should contains h2c:// * update grpc test * gofmt gw file * enabled h2c by default to http servers * remove duplicated registeering of healthcheck Co-authored-by: tbuchaillot <tombuchaillot89@gmail.com> (cherry picked from commit 5c8870a)
@matiasinsaurralde Succesfully merged |
/release to release-3 |
Working on it! Note that it can take a few minutes. |
* fix grpc proxy connection * clean and format code * clean code * remove h2c config from gateway config * replace h2c protocol from url and set it as http * removed config enable_h2c at api level and infer it from the target url which should contains h2c:// * update grpc test * gofmt gw file * enabled h2c by default to http servers * remove duplicated registeering of healthcheck Co-authored-by: tbuchaillot <tombuchaillot89@gmail.com> (cherry picked from commit 5c8870a)
@matiasinsaurralde Succesfully merged |
Description
now for all the http proxies (including the main router of gw) is activated h2c. However, this doesn't means we will consume the upstream via h2c as this should be activated via
target_url
. This should be merged after #3372Related Issue
https://tyktech.atlassian.net/browse/TT-968
Motivation and Context
give solution to https://tyktech.atlassian.net/browse/TT-968
How This Has Been Tested
curl -v --http2-prior-knowledge http://tyk-gateway:8080/keyless/uuid
)grpcurl -plaintext -proto helloworld.proto -d '{"name": "sredny"}' tyk-gateway:12345 helloworld.Greeter/SayHello
)Screenshots (if appropriate)
Types of changes
Checklist
fork, don't request your
master
!master
branch (left side). Also, you should startyour branch off our latest
master
.go mod tidy && go mod vendor
go fmt -s
go vet