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 h2c with prior knowledge #1398

Merged
merged 1 commit into from Feb 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 18 additions & 4 deletions gin.go
Expand Up @@ -16,6 +16,8 @@ import (

"github.com/gin-gonic/gin/internal/bytesconv"
"github.com/gin-gonic/gin/render"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
)

const defaultMultipartMemory = 32 << 20 // 32 MB
Expand Down Expand Up @@ -136,6 +138,9 @@ type Engine struct {
// method call.
MaxMultipartMemory int64

// Enable h2c support.
UseH2C bool

delims render.Delims
secureJSONPrefix string
HTMLRender render.HTMLRender
Expand Down Expand Up @@ -199,6 +204,15 @@ func Default() *Engine {
return engine
}

func (engine *Engine) Handler() http.Handler {
if !engine.UseH2C {
return engine
}

h2s := &http2.Server{}
return h2c.NewHandler(engine, h2s)
}

func (engine *Engine) allocateContext() *Context {
v := make(Params, 0, engine.maxParams)
return &Context{engine: engine, params: &v}
Expand Down Expand Up @@ -348,7 +362,7 @@ func (engine *Engine) Run(addr ...string) (err error) {

address := resolveAddress(addr)
debugPrint("Listening and serving HTTP on %s\n", address)
err = http.ListenAndServe(address, engine)
err = http.ListenAndServe(address, engine.Handler())
return
}

Expand Down Expand Up @@ -420,7 +434,7 @@ func (engine *Engine) RunTLS(addr, certFile, keyFile string) (err error) {
return err
}

err = http.ListenAndServeTLS(addr, certFile, keyFile, engine)
err = http.ListenAndServeTLS(addr, certFile, keyFile, engine.Handler())
return
}

Expand All @@ -443,7 +457,7 @@ func (engine *Engine) RunUnix(file string) (err error) {
defer listener.Close()
defer os.Remove(file)

err = http.Serve(listener, engine)
err = http.Serve(listener, engine.Handler())
return
}

Expand Down Expand Up @@ -480,7 +494,7 @@ func (engine *Engine) RunListener(listener net.Listener) (err error) {
return err
}

err = http.Serve(listener, engine)
err = http.Serve(listener, engine.Handler())
return
}

Expand Down
34 changes: 34 additions & 0 deletions gin_test.go
Expand Up @@ -19,6 +19,7 @@ import (
"time"

"github.com/stretchr/testify/assert"
"golang.org/x/net/http2"
)

func formatAsDate(t time.Time) string {
Expand Down Expand Up @@ -79,6 +80,39 @@ func TestLoadHTMLGlobDebugMode(t *testing.T) {
assert.Equal(t, "<h1>Hello world</h1>", string(resp))
}

func TestH2c(t *testing.T) {
ln, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
fmt.Println(err)
}
r := Default()
r.UseH2C = true
r.GET("/", func(c *Context) {
c.String(200, "<h1>Hello world</h1>")
})
go http.Serve(ln, r.Handler())
defer ln.Close()

url := "http://" + ln.Addr().String() + "/"

http := 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 := http.Get(url)
if err != nil {
fmt.Println(err)
}

resp, _ := ioutil.ReadAll(res.Body)
assert.Equal(t, "<h1>Hello world</h1>", string(resp))
}

func TestLoadHTMLGlobTestMode(t *testing.T) {
ts := setupHTMLFiles(
t,
Expand Down
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -10,6 +10,7 @@ require (
github.com/mattn/go-isatty v0.0.13
github.com/stretchr/testify v1.7.0
github.com/ugorji/go/codec v1.2.6
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
google.golang.org/protobuf v1.27.1
gopkg.in/yaml.v2 v2.4.0
)
1 change: 1 addition & 0 deletions go.sum
Expand Up @@ -53,6 +53,7 @@ github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down