mirror of
https://github.com/caddyserver/caddy.git
synced 2025-05-24 02:02:26 -04:00
check http version while reading the connection
This commit is contained in:
parent
6c1d6b06b4
commit
c537d9bc5c
@ -552,7 +552,8 @@ func (app *App) Start() error {
|
|||||||
// check if the connection is h2c
|
// check if the connection is h2c
|
||||||
ln = &http2Listener{
|
ln = &http2Listener{
|
||||||
useTLS: useTLS,
|
useTLS: useTLS,
|
||||||
useH2C: h2cok,
|
useH1: h1ok,
|
||||||
|
useH2: h2ok || h2cok,
|
||||||
Listener: ln,
|
Listener: ln,
|
||||||
logger: app.logger,
|
logger: app.logger,
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,11 @@ type connectionStater interface {
|
|||||||
// can do this.
|
// can do this.
|
||||||
// 2. After wrapping the connection doesn't implement connectionStater, emit a warning so that listener
|
// 2. After wrapping the connection doesn't implement connectionStater, emit a warning so that listener
|
||||||
// wrapper authors will hopefully implement it.
|
// wrapper authors will hopefully implement it.
|
||||||
|
// 3. check if the connection matches a specific http version. h2/h2c has a distinct preface.
|
||||||
type http2Listener struct {
|
type http2Listener struct {
|
||||||
useTLS bool
|
useTLS bool
|
||||||
useH2C bool
|
useH1 bool
|
||||||
|
useH2 bool
|
||||||
net.Listener
|
net.Listener
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
}
|
}
|
||||||
@ -39,21 +41,14 @@ func (h *http2Listener) Accept() (net.Conn, error) {
|
|||||||
if _, ok := conn.(connectionStater); !ok {
|
if _, ok := conn.(connectionStater); !ok {
|
||||||
h.logger.Warn("tls is enabled, but listener wrapper returns a connection that doesn't implement connectionStater")
|
h.logger.Warn("tls is enabled, but listener wrapper returns a connection that doesn't implement connectionStater")
|
||||||
}
|
}
|
||||||
return &http2Conn{
|
|
||||||
idx: len(http2.ClientPreface),
|
|
||||||
Conn: conn,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := conn.(connectionStater); ok {
|
if _, ok := conn.(connectionStater); ok {
|
||||||
h.logger.Warn("tls is disabled, but listener wrapper returns a connection that implements connectionStater")
|
h.logger.Warn("tls is disabled, but listener wrapper returns a connection that implements connectionStater")
|
||||||
return &http2Conn{
|
|
||||||
idx: len(http2.ClientPreface),
|
|
||||||
Conn: conn,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.useH2C {
|
// if both h1 and h2 are enabled, we don't need to check the preface
|
||||||
|
if h.useH1 && h.useH2 {
|
||||||
return &http2Conn{
|
return &http2Conn{
|
||||||
idx: len(http2.ClientPreface),
|
idx: len(http2.ClientPreface),
|
||||||
Conn: conn,
|
Conn: conn,
|
||||||
@ -61,13 +56,17 @@ func (h *http2Listener) Accept() (net.Conn, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &http2Conn{
|
return &http2Conn{
|
||||||
|
h2Expected: h.useH2,
|
||||||
Conn: conn,
|
Conn: conn,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type http2Conn struct {
|
type http2Conn struct {
|
||||||
// check h2 preface if it's smaller that the preface
|
// current index where the preface should match,
|
||||||
|
// no matching is done if idx is >= len(http2.ClientPreface)
|
||||||
idx int
|
idx int
|
||||||
|
// whether the connection is expected to be h2/h2c
|
||||||
|
h2Expected bool
|
||||||
// log if one such connection is detected
|
// log if one such connection is detected
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
net.Conn
|
net.Conn
|
||||||
@ -79,14 +78,16 @@ func (c *http2Conn) Read(p []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
n, err := c.Conn.Read(p)
|
n, err := c.Conn.Read(p)
|
||||||
for i := range n {
|
for i := range n {
|
||||||
// mismatch
|
// first mismatch, close the connection if h2 is expected
|
||||||
if p[i] != http2.ClientPreface[c.idx] {
|
if p[i] != http2.ClientPreface[c.idx] && c.h2Expected {
|
||||||
c.idx = len(http2.ClientPreface)
|
c.logger.Debug("h1 connection detected, but h1 is not enabled")
|
||||||
return n, err
|
_ = c.Conn.Close()
|
||||||
|
return 0, io.EOF
|
||||||
}
|
}
|
||||||
c.idx++
|
c.idx++
|
||||||
if c.idx == len(http2.ClientPreface) {
|
// matching complete
|
||||||
c.logger.Warn("h2c connection detected, but h2c is not enabled")
|
if c.idx == len(http2.ClientPreface) && !c.h2Expected {
|
||||||
|
c.logger.Debug("h2/h2c connection detected, but h2/h2c is not enabled")
|
||||||
_ = c.Conn.Close()
|
_ = c.Conn.Close()
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user