feat(engine): add H2CConfig to allow configuring h2c http2.Server

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Abhiyan Khanal 2026-03-07 17:10:04 +05:45
parent 3e44fdc4d1
commit 47a03c7cf2
2 changed files with 57 additions and 0 deletions

8
gin.go
View File

@ -169,6 +169,11 @@ type Engine struct {
// UseH2C enable h2c support.
UseH2C bool
// H2CConfig optionally specifies the http2.Server configuration used for h2c connections.
// If nil, a default &http2.Server{} is used. Set this to configure options such as
// MaxConcurrentStreams, IdleTimeout, etc.
H2CConfig *http2.Server
// ContextWithFallback enable fallback Context.Deadline(), Context.Done(), Context.Err() and Context.Value() when Context.Request.Context() is not nil.
ContextWithFallback bool
@ -246,6 +251,9 @@ func (engine *Engine) Handler() http.Handler {
}
h2s := &http2.Server{}
if engine.H2CConfig != nil {
h2s = engine.H2CConfig
}
return h2c.NewHandler(engine, h2s)
}

View File

@ -120,6 +120,55 @@ func TestH2c(t *testing.T) {
assert.Equal(t, "<h1>Hello world</h1>", string(resp))
}
func TestH2CHandlerDefaultConfig(t *testing.T) {
r := Default()
r.UseH2C = true
handler := r.Handler()
// When UseH2C is true and H2CConfig is nil, Handler() should return an h2c handler (not the engine itself).
assert.NotEqual(t, r, handler)
}
func TestH2CHandlerWithCustomConfig(t *testing.T) {
ln, err := net.Listen("tcp", localhostIP+":0")
if err != nil {
t.Error(err)
}
r := Default()
r.UseH2C = true
r.H2CConfig = &http2.Server{
IdleTimeout: 60 * time.Second,
}
r.GET("/", func(c *Context) {
c.String(200, "<h1>Hello world</h1>")
})
go func() {
err := http.Serve(ln, r.Handler())
if err != nil {
t.Log(err)
}
}()
defer ln.Close()
url := "http://" + ln.Addr().String() + "/"
httpClient := http.Client{
Transport: &http2.Transport{
AllowHTTP: true,
DialTLS: func(netw, addr string, cfg *tls.Config) (net.Conn, error) {
return net.Dial(netw, addr)
},
},
}
res, err := httpClient.Get(url)
if err != nil {
t.Error(err)
}
resp, _ := io.ReadAll(res.Body)
assert.Equal(t, "<h1>Hello world</h1>", string(resp))
}
func TestLoadHTMLGlobTestMode(t *testing.T) {
ts := setupHTMLFiles(
t,