NOISSUE - Add HTTP server timeouts

Signed-off-by: dusan <borovcanindusan1@gmail.com>
This commit is contained in:
dusan
2025-11-28 18:21:25 +01:00
parent f96ddab9dd
commit 5807cf1754
8 changed files with 41 additions and 42 deletions
+4 -1
View File
@@ -329,8 +329,11 @@ func proxyWS(ctx context.Context, cfg config, logger *slog.Logger, sessionHandle
}
func healthcheck(cfg config) func() error {
client := &http.Client{
Timeout: 30 * time.Second,
}
return func() error {
res, err := http.Get(cfg.MQTTTargetHealthCheck)
res, err := client.Get(cfg.MQTTTargetHealthCheck)
if err != nil {
return err
}
+2 -2
View File
@@ -59,8 +59,8 @@ require (
require (
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-20250912141014-52f32327d4b0.1 // indirect
cloud.google.com/go/compute/metadata v0.9.0 // indirect
dario.cat/mergo v1.0.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
dario.cat/mergo v1.0.2 // indirect
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
+4 -4
View File
@@ -3,14 +3,14 @@ buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.10-202509121410
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/0x6flab/namegenerator v1.4.0 h1:QnkI813SZsI/hYnKD9pg3mkIlcYzCx0N4hnzb0YYME4=
github.com/0x6flab/namegenerator v1.4.0/go.mod h1:2sQzXuS6dX/KEwWtB6GJU729O3m4gBdD5oAU8hd0SyY=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
+5 -1
View File
@@ -30,6 +30,10 @@ var scopes = []string{
"https://www.googleapis.com/auth/userinfo.profile",
}
var httpClient = &http.Client{
Timeout: defTimeout,
}
var _ mgoauth2.Provider = (*config)(nil)
type config struct {
@@ -85,7 +89,7 @@ func (cfg *config) Exchange(ctx context.Context, code string) (oauth2.Token, err
}
func (cfg *config) UserInfo(accessToken string) (uclient.User, error) {
resp, err := http.Get(userInfoURL + url.QueryEscape(accessToken))
resp, err := httpClient.Get(userInfoURL + url.QueryEscape(accessToken))
if err != nil {
return uclient.User{}, err
}
+5 -26
View File
@@ -18,6 +18,7 @@ import (
"github.com/absmach/supermq/pkg/policies"
"github.com/absmach/supermq/pkg/postgres"
"github.com/absmach/supermq/pkg/roles"
"github.com/lib/pq"
)
var _ roles.Repository = (*Repository)(nil)
@@ -460,25 +461,14 @@ func (repo *Repository) RoleListActions(ctx context.Context, roleID string) ([]s
}
func (repo *Repository) RoleCheckActionsExists(ctx context.Context, roleID string, actions []string) (bool, error) {
q := fmt.Sprintf(`SELECT COUNT(*) FROM %s_role_actions WHERE role_id = :role_id AND action IN ('%s')`, repo.tableNamePrefix, strings.Join(actions, ","))
q := fmt.Sprintf(`SELECT COUNT(*) FROM %s_role_actions WHERE role_id = $1 AND action = ANY($2)`, repo.tableNamePrefix)
params := map[string]any{
"role_id": roleID,
}
var count int
query, err := repo.db.NamedQueryContext(ctx, q, params)
err := repo.db.QueryRowxContext(ctx, q, roleID, pq.Array(actions)).Scan(&count)
if err != nil {
return false, errors.Wrap(repoerr.ErrViewEntity, err)
}
defer query.Close()
if query.Next() {
if err := query.Scan(&count); err != nil {
return false, errors.Wrap(repoerr.ErrViewEntity, err)
}
}
// Check if the count matches the number of actions provided
if count != len(actions) {
return false, nil
@@ -638,25 +628,14 @@ func (repo *Repository) RoleListMembers(ctx context.Context, roleID string, limi
}
func (repo *Repository) RoleCheckMembersExists(ctx context.Context, roleID string, members []string) (bool, error) {
q := fmt.Sprintf(`SELECT COUNT(*) FROM %s_role_members WHERE role_id = :role_id AND member_id IN ('%s')`, repo.tableNamePrefix, strings.Join(members, ","))
q := fmt.Sprintf(`SELECT COUNT(*) FROM %s_role_members WHERE role_id = $1 AND member_id = ANY($2)`, repo.tableNamePrefix)
params := map[string]any{
"role_id": roleID,
}
var count int
query, err := repo.db.NamedQueryContext(ctx, q, params)
err := repo.db.QueryRowxContext(ctx, q, roleID, pq.Array(members)).Scan(&count)
if err != nil {
return false, errors.Wrap(repoerr.ErrViewEntity, err)
}
defer query.Close()
if query.Next() {
if err := query.Scan(&count); err != nil {
return false, errors.Wrap(repoerr.ErrViewEntity, err)
}
}
if count != len(members) {
return false, nil
}
+1 -1
View File
@@ -1483,7 +1483,7 @@ func NewSDK(conf Config) SDK {
msgContentType: conf.MsgContentType,
client: &http.Client{Transport: otelhttp.NewTransport(&http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
InsecureSkipVerify: !conf.TLSVerification,
},
})},
curlFlag: conf.CurlFlag,
+9 -1
View File
@@ -27,7 +27,15 @@ var _ server.Server = (*httpServer)(nil)
func NewServer(ctx context.Context, cancel context.CancelFunc, name string, config server.Config, handler http.Handler, logger *slog.Logger) server.Server {
baseServer := server.NewBaseServer(ctx, cancel, name, config, logger)
hserver := &http.Server{Addr: baseServer.Address, Handler: handler}
hserver := &http.Server{
Addr: baseServer.Address,
Handler: handler,
ReadTimeout: config.ReadTimeout,
WriteTimeout: config.WriteTimeout,
ReadHeaderTimeout: config.ReadHeaderTimeout,
IdleTimeout: config.IdleTimeout,
MaxHeaderBytes: config.MaxHeaderBytes,
}
return &httpServer{
BaseServer: baseServer,
+11 -6
View File
@@ -26,12 +26,17 @@ type Server interface {
// Config is a struct that contains the configuration for the server.
type Config struct {
Host string `env:"HOST" envDefault:"localhost"`
Port string `env:"PORT" envDefault:""`
CertFile string `env:"SERVER_CERT" envDefault:""`
KeyFile string `env:"SERVER_KEY" envDefault:""`
ServerCAFile string `env:"SERVER_CA_CERTS" envDefault:""`
ClientCAFile string `env:"CLIENT_CA_CERTS" envDefault:""`
Host string `env:"HOST" envDefault:"localhost"`
Port string `env:"PORT" envDefault:""`
CertFile string `env:"SERVER_CERT" envDefault:""`
KeyFile string `env:"SERVER_KEY" envDefault:""`
ServerCAFile string `env:"SERVER_CA_CERTS" envDefault:""`
ClientCAFile string `env:"CLIENT_CA_CERTS" envDefault:""`
ReadTimeout time.Duration `env:"SERVER_READ_TIMEOUT" envDefault:"15s"`
WriteTimeout time.Duration `env:"SERVER_WRITE_TIMEOUT" envDefault:"15s"`
ReadHeaderTimeout time.Duration `env:"SERVER_READ_HEADER_TIMEOUT" envDefault:"5s"`
IdleTimeout time.Duration `env:"SERVER_IDLE_TIMEOUT" envDefault:"60s"`
MaxHeaderBytes int `env:"SERVER_MAX_HEADER_BYTES" envDefault:"1048576"` // 1 << 20
}
type BaseServer struct {