mihomo/component/tls/httpserver.go
wwqgtxx d036d98128
Some checks failed
Test / test (1.20, macos-13) (push) Waiting to run
Test / test (1.20, macos-latest) (push) Waiting to run
Test / test (1.20, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.20, windows-latest) (push) Waiting to run
Test / test (1.21, macos-13) (push) Waiting to run
Test / test (1.21, macos-latest) (push) Waiting to run
Test / test (1.21, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.21, windows-latest) (push) Waiting to run
Test / test (1.22, macos-13) (push) Waiting to run
Test / test (1.22, macos-latest) (push) Waiting to run
Test / test (1.22, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.22, windows-latest) (push) Waiting to run
Test / test (1.23, macos-13) (push) Waiting to run
Test / test (1.23, macos-latest) (push) Waiting to run
Test / test (1.23, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.23, windows-latest) (push) Waiting to run
Test / test (1.24, macos-13) (push) Waiting to run
Test / test (1.24, macos-latest) (push) Waiting to run
Test / test (1.24, ubuntu-24.04-arm) (push) Waiting to run
Test / test (1.24, windows-latest) (push) Waiting to run
Test / test (1.20, ubuntu-latest) (push) Failing after 1s
Test / test (1.21, ubuntu-latest) (push) Failing after 1s
Test / test (1.22, ubuntu-latest) (push) Failing after 1s
Test / test (1.23, ubuntu-latest) (push) Failing after 1s
Test / test (1.24, ubuntu-latest) (push) Failing after 1s
Trigger CMFA Update / trigger-CMFA-update (push) Failing after 0s
fix: http server does not handle http2 logic correctly
2025-05-18 23:05:00 +08:00

69 lines
1.7 KiB
Go

package tls
import (
"context"
"net"
"net/http"
"time"
N "github.com/metacubex/mihomo/common/net"
"github.com/metacubex/mihomo/log"
"golang.org/x/net/http2"
)
func extractTlsHandshakeTimeoutFromServer(s *http.Server) time.Duration {
var ret time.Duration
for _, v := range [...]time.Duration{
s.ReadHeaderTimeout,
s.ReadTimeout,
s.WriteTimeout,
} {
if v <= 0 {
continue
}
if ret == 0 || v < ret {
ret = v
}
}
return ret
}
// NewListenerForHttps returns a net.Listener for (*http.Server).Serve()
// the "func (c *conn) serve(ctx context.Context)" in http\server.go
// only do tls handshake and check NegotiatedProtocol with std's *tls.Conn
// so we do the same logic to let http2 (not h2c) work fine
func NewListenerForHttps(l net.Listener, httpServer *http.Server, tlsConfig *Config) net.Listener {
http2Server := &http2.Server{}
_ = http2.ConfigureServer(httpServer, http2Server)
return N.NewHandleContextListener(context.Background(), l, func(ctx context.Context, conn net.Conn) (net.Conn, error) {
c := Server(conn, tlsConfig)
tlsTO := extractTlsHandshakeTimeoutFromServer(httpServer)
if tlsTO > 0 {
dl := time.Now().Add(tlsTO)
_ = conn.SetReadDeadline(dl)
_ = conn.SetWriteDeadline(dl)
}
err := c.HandshakeContext(ctx)
if err != nil {
return nil, err
}
// Restore Conn-level deadlines.
if tlsTO > 0 {
_ = conn.SetReadDeadline(time.Time{})
_ = conn.SetWriteDeadline(time.Time{})
}
if c.ConnectionState().NegotiatedProtocol == http2.NextProtoTLS {
http2Server.ServeConn(c, &http2.ServeConnOpts{BaseConfig: httpServer})
return nil, net.ErrClosed
}
return c, nil
}, func(a any) {
log.Errorln("https server panic: %s", a)
})
}