feat(selfhost-web): make webapp-server timeouts configurable (#6147)
Signed-off-by: Rodrigo Kellermann <kellermann@gmail.com> Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>
This commit is contained in:
parent
9861ee84ad
commit
40ac84c115
3 changed files with 48 additions and 14 deletions
|
|
@ -16,15 +16,18 @@ docker build -t hoppscotch-webapp-server .
|
|||
|
||||
## Configuration
|
||||
|
||||
| Variable | Description | Default |
|
||||
|----------------------------------|------------------------------------|------------------------------------------------|
|
||||
| `WEBAPP_SERVER_PORT` | Server port | `3200` |
|
||||
| `FRONTEND_PATH` | Path to frontend assets | `/site/selfhost-web` (prod) or `../dist` (dev) |
|
||||
| `WEBAPP_SERVER_SIGNING_SECRET` | Secret string for key derivation | None |
|
||||
| `WEBAPP_SERVER_SIGNING_SEED` | Base64 encoded 32-byte seed | None |
|
||||
| `WEBAPP_SERVER_SIGNING_KEY` | Base64 encoded 64-byte private key | None |
|
||||
| `WEBAPP_SERVER_SIGNING_KEY_FILE` | Custom path for key file | `/data/webapp-server/signing.key` |
|
||||
| `GO_ENV` | Set to `development` for dev mode | None |
|
||||
| Variable | Description | Default |
|
||||
|----------------------------------|------------------------------------------------------------|------------------------------------------------|
|
||||
| `WEBAPP_SERVER_PORT` | Server port | `3200` |
|
||||
| `WEBAPP_SERVER_READ_TIMEOUT` | HTTP read timeout (Go duration, e.g. `30s`; `0` disables) | `15s` |
|
||||
| `WEBAPP_SERVER_WRITE_TIMEOUT` | HTTP write timeout (Go duration, e.g. `30s`; `0` disables) | `15s` |
|
||||
| `WEBAPP_SERVER_IDLE_TIMEOUT` | HTTP idle timeout (Go duration, e.g. `2m`; `0` disables) | `60s` |
|
||||
| `FRONTEND_PATH` | Path to frontend assets | `/site/selfhost-web` (prod) or `../dist` (dev) |
|
||||
| `WEBAPP_SERVER_SIGNING_SECRET` | Secret string for key derivation | None |
|
||||
| `WEBAPP_SERVER_SIGNING_SEED` | Base64 encoded 32-byte seed | None |
|
||||
| `WEBAPP_SERVER_SIGNING_KEY` | Base64 encoded 64-byte private key | None |
|
||||
| `WEBAPP_SERVER_SIGNING_KEY_FILE` | Custom path for key file | `/data/webapp-server/signing.key` |
|
||||
| `GO_ENV` | Set to `development` for dev mode | None |
|
||||
|
||||
## Signing Key Persistence
|
||||
|
||||
|
|
|
|||
|
|
@ -4,17 +4,43 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultPort = 3200
|
||||
DefaultFrontendPath = "/site/selfhost-web"
|
||||
DevFrontendPath = "../dist"
|
||||
|
||||
DefaultReadTimeout = 15 * time.Second
|
||||
DefaultWriteTimeout = 15 * time.Second
|
||||
DefaultIdleTimeout = 60 * time.Second
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Port int
|
||||
FrontendPath string
|
||||
ReadTimeout time.Duration
|
||||
WriteTimeout time.Duration
|
||||
IdleTimeout time.Duration
|
||||
}
|
||||
|
||||
// parseDuration reads a Go duration string from an env var (e.g. "30s", "2m", "0").
|
||||
// A value of "0" is valid and disables the timeout (net/http semantics).
|
||||
// If the variable is unset or invalid, it logs a warning and returns the fallback.
|
||||
func parseDuration(envKey string, fallback time.Duration) time.Duration {
|
||||
if s := os.Getenv(envKey); s != "" {
|
||||
if d, err := time.ParseDuration(s); err == nil && d >= 0 {
|
||||
if d == 0 {
|
||||
log.Printf("Using %s from environment: %s (timeout disabled)", envKey, s)
|
||||
} else {
|
||||
log.Printf("Using %s from environment: %s", envKey, s)
|
||||
}
|
||||
return d
|
||||
}
|
||||
log.Printf("Warning: Invalid %s value '%s', using default %v", envKey, s, fallback)
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
// Load reads config from env vars with sensible defaults
|
||||
|
|
@ -46,5 +72,9 @@ func Load() *Config {
|
|||
log.Println("Running in production mode, using frontend path: /site/selfhost-web")
|
||||
}
|
||||
|
||||
cfg.ReadTimeout = parseDuration("WEBAPP_SERVER_READ_TIMEOUT", DefaultReadTimeout)
|
||||
cfg.WriteTimeout = parseDuration("WEBAPP_SERVER_WRITE_TIMEOUT", DefaultWriteTimeout)
|
||||
cfg.IdleTimeout = parseDuration("WEBAPP_SERVER_IDLE_TIMEOUT", DefaultIdleTimeout)
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,14 +62,15 @@ func main() {
|
|||
|
||||
addr := fmt.Sprintf(":%d", cfg.Port)
|
||||
|
||||
// NOTE: these timeouts are pretty conservative
|
||||
// bump them if you're serving huge bundles over slow connections
|
||||
// NOTE: timeouts default to conservative values but can be overridden
|
||||
// via WEBAPP_SERVER_READ_TIMEOUT, WEBAPP_SERVER_WRITE_TIMEOUT, WEBAPP_SERVER_IDLE_TIMEOUT
|
||||
// (Go duration strings, e.g. "30s", "2m", "0" to disable)
|
||||
httpServer := &http.Server{
|
||||
Addr: addr,
|
||||
Handler: mux,
|
||||
ReadTimeout: 15 * time.Second,
|
||||
WriteTimeout: 15 * time.Second,
|
||||
IdleTimeout: 60 * time.Second,
|
||||
ReadTimeout: cfg.ReadTimeout,
|
||||
WriteTimeout: cfg.WriteTimeout,
|
||||
IdleTimeout: cfg.IdleTimeout,
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue