introduce read http timeout listener

Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
This commit is contained in:
Jörn Friedrich Dreyer
2025-11-04 14:12:52 +01:00
parent 6e0bb09aff
commit 936a84096e
2 changed files with 55 additions and 4 deletions

View File

@@ -3,7 +3,9 @@ package http
import (
"crypto/tls"
"fmt"
"net"
"strings"
"time"
"github.com/opencloud-eu/opencloud/pkg/broker"
"github.com/opencloud-eu/opencloud/pkg/registry"
@@ -12,7 +14,6 @@ import (
mtracer "github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry"
occrypto "github.com/opencloud-eu/opencloud/pkg/crypto"
"go-micro.dev/v4"
"go-micro.dev/v4/server"
)
// Service simply wraps the go-micro web service.
@@ -24,7 +25,9 @@ type Service struct {
func NewService(opts ...Option) (Service, error) {
noopBroker := broker.NoOp{}
sopts := newOptions(opts...)
var mServer server.Server
var listener net.Listener
var err error
if sopts.TLSConfig.Enabled {
var cert tls.Certificate
var err error
@@ -50,11 +53,27 @@ func NewService(opts ...Option) (Service, error) {
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
}
mServer = mhttps.NewServer(server.TLSConfig(tlsConfig))
// Create TLS listener
listener, err = tls.Listen("tcp", sopts.Address, tlsConfig)
if err != nil {
return Service{}, fmt.Errorf("error starting TLS listener: %w", err)
}
} else {
mServer = mhttps.NewServer()
// Create Non-TLS listener
listener, err = net.Listen("tcp", sopts.Address)
if err != nil {
return Service{}, fmt.Errorf("error starting TCP listener: %w", err)
}
}
// Wrap listener with timeoutListener to set a read timeout
tl := timeoutListener{
Listener: listener,
readTimeout: time.Duration(3) * time.Second,
}
mServer := mhttps.NewServer(mhttps.Listener(tl))
wopts := []micro.Option{
micro.Server(mServer),
micro.Broker(noopBroker),

View File

@@ -0,0 +1,32 @@
package http
import (
"net"
"time"
)
type timeoutListener struct {
net.Listener
readTimeout time.Duration
}
func (tl timeoutListener) Accept() (net.Conn, error) {
c, err := tl.Listener.Accept()
if err != nil {
return nil, err
}
return &timeoutConn{Conn: c, readTimeout: tl.readTimeout}, nil
}
type timeoutConn struct {
net.Conn
readTimeout time.Duration
}
// Read implements a read with sliding timeout window.
func (c *timeoutConn) Read(b []byte) (int, error) {
if c.readTimeout > 0 {
_ = c.SetReadDeadline(time.Now().Add(c.readTimeout))
}
return c.Conn.Read(b)
}