mirror of
https://github.com/umputun/reproxy.git
synced 2024-10-26 10:10:12 +03:00
all timeouts are customizable #5
This commit is contained in:
parent
06a6d595b3
commit
64fd98a130
14
README.md
14
README.md
@ -98,6 +98,7 @@ Assets server can be used without any proxy providers. In this mode reproxy acts
|
||||
- `--gzip` enables gizp compression for responses.
|
||||
- `--max=N` allows to set the maximum size of request (default 64k)
|
||||
- `--header` sets extra header(s) added to each proxied request
|
||||
- `--timeout.*` various timeouts for both server and proxy transport. See `timeout` section in [All Application Options](https://github.com/umputun/reproxy#all-application-options)
|
||||
|
||||
## Ping and health checks
|
||||
|
||||
@ -110,7 +111,6 @@ reproxy provides 2 endpoints for this purpose:
|
||||
|
||||
```
|
||||
-l, --listen= listen on host:port (default: 127.0.0.1:8080) [$LISTEN]
|
||||
-t, --timeout= proxy timeout (default: 5s) [$TIMEOUT]
|
||||
-m, --max= max response size (default: 64000) [$MAX_SIZE]
|
||||
-g, --gzip enable gz compression [$GZIP]
|
||||
-x, --header= proxy headers [$HEADER]
|
||||
@ -153,10 +153,20 @@ static:
|
||||
--static.enabled enable static provider [$STATIC_ENABLED]
|
||||
--static.rule= routing rules [$STATIC_RULES]
|
||||
|
||||
timeout:
|
||||
--timeout.read-header= read header server timeout (default: 5s) [$TIMEOUT_READ_HEADER]
|
||||
--timeout.write= write server timeout (default: 30s) [$TIMEOUT_WRITE]
|
||||
--timeout.idle= idle server timeout (default: 30s) [$TIMEOUT_IDLE]
|
||||
--timeout.dial= dial transport timeout (default: 30s) [$TIMEOUT_DIAL]
|
||||
--timeout.keep-alive= keep-alive transport timeout (default: 30s) [$TIMEOUT_KEEP_ALIVE]
|
||||
--timeout.resp-header= response header transport timeout (default: 5s) [$TIMEOUT_RESP_HEADER]
|
||||
--timeout.idle-conn= idle connection transport timeout (default: 90s) [$TIMEOUT_IDLE_CONN]
|
||||
--timeout.tls= TLS hanshake transport timeout (default: 10s) [$TIMEOUT_TLS]
|
||||
--timeout.continue= expect continue transport timeout (default: 1s) [$TIMEOUT_CONTINUE]
|
||||
|
||||
Help Options:
|
||||
-h, --help Show this help message
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Status
|
||||
|
33
app/main.go
33
app/main.go
@ -24,11 +24,10 @@ import (
|
||||
)
|
||||
|
||||
var opts struct {
|
||||
Listen string `short:"l" long:"listen" env:"LISTEN" default:"127.0.0.1:8080" description:"listen on host:port"`
|
||||
TimeOut time.Duration `short:"t" long:"timeout" env:"TIMEOUT" default:"5s" description:"proxy timeout"`
|
||||
MaxSize int64 `short:"m" long:"max" env:"MAX_SIZE" default:"64000" description:"max response size"`
|
||||
GzipEnabled bool `short:"g" long:"gzip" env:"GZIP" description:"enable gz compression"`
|
||||
ProxyHeaders []string `short:"x" long:"header" env:"HEADER" description:"proxy headers" env-delim:","`
|
||||
Listen string `short:"l" long:"listen" env:"LISTEN" default:"127.0.0.1:8080" description:"listen on host:port"`
|
||||
MaxSize int64 `short:"m" long:"max" env:"MAX_SIZE" default:"64000" description:"max response size"`
|
||||
GzipEnabled bool `short:"g" long:"gzip" env:"GZIP" description:"enable gz compression"`
|
||||
ProxyHeaders []string `short:"x" long:"header" env:"HEADER" description:"proxy headers" env-delim:","`
|
||||
|
||||
SSL struct {
|
||||
Type string `long:"type" env:"TYPE" description:"ssl (auto) support" choice:"none" choice:"static" choice:"auto" default:"none"` //nolint
|
||||
@ -72,6 +71,18 @@ var opts struct {
|
||||
Rules []string `long:"rule" env:"RULES" description:"routing rules" env-delim:";"`
|
||||
} `group:"static" namespace:"static" env-namespace:"STATIC"`
|
||||
|
||||
Timeouts struct {
|
||||
ReadHeader time.Duration `long:"read-header" env:"READ_HEADER" default:"5s" description:"read header server timeout"`
|
||||
Write time.Duration `long:"write" env:"WRITE" default:"30s" description:"write server timeout"`
|
||||
Idle time.Duration `long:"idle" env:"IDLE" default:"30s" description:"idle server timeout"`
|
||||
Dial time.Duration `long:"dial" env:"DIAL" default:"30s" description:"dial transport timeout"`
|
||||
KeepAlive time.Duration `long:"keep-alive" env:"KEEP_ALIVE" default:"30s" description:"keep-alive transport timeout"`
|
||||
ResponseHeader time.Duration `long:"resp-header" env:"RESP_HEADER" default:"5s" description:"response header transport timeout"`
|
||||
IdleConn time.Duration `long:"idle-conn" env:"IDLE_CONN" default:"90s" description:"idle connection transport timeout"`
|
||||
TLSHandshake time.Duration `long:"tls" env:"TLS" default:"10s" description:"TLS hanshake transport timeout"`
|
||||
ExpectContinue time.Duration `long:"continue" env:"CONTINUE" default:"1s" description:"expect continue transport timeout"`
|
||||
} `group:"timeout" namespace:"timeout" env-namespace:"TIMEOUT"`
|
||||
|
||||
NoSignature bool `long:"no-signature" env:"NO_SIGNATURE" description:"disable reproxy signature headers"`
|
||||
Dbg bool `long:"dbg" env:"DEBUG" description:"debug mode"`
|
||||
}
|
||||
@ -130,7 +141,6 @@ func main() {
|
||||
Version: revision,
|
||||
Matcher: svc,
|
||||
Address: opts.Listen,
|
||||
TimeOut: opts.TimeOut,
|
||||
MaxBodySize: opts.MaxSize,
|
||||
AssetsLocation: opts.Assets.Location,
|
||||
AssetsWebRoot: opts.Assets.WebRoot,
|
||||
@ -139,6 +149,17 @@ func main() {
|
||||
ProxyHeaders: opts.ProxyHeaders,
|
||||
AccessLog: accessLog,
|
||||
DisableSignature: opts.NoSignature,
|
||||
Timeouts: proxy.Timeouts{
|
||||
ReadHeader: opts.Timeouts.ReadHeader,
|
||||
Write: opts.Timeouts.Write,
|
||||
Idle: opts.Timeouts.Idle,
|
||||
Dial: opts.Timeouts.Dial,
|
||||
KeepAlive: opts.Timeouts.KeepAlive,
|
||||
IdleConn: opts.Timeouts.IdleConn,
|
||||
TLSHandshake: opts.Timeouts.TLSHandshake,
|
||||
ExpectContinue: opts.Timeouts.ExpectContinue,
|
||||
ResponseHeader: opts.Timeouts.ResponseHeader,
|
||||
},
|
||||
}
|
||||
if err := px.Run(context.Background()); err != nil {
|
||||
log.Fatalf("[ERROR] proxy server failed, %v", err) //nolint gocritic
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
|
||||
func TestHttp_healthHandler(t *testing.T) {
|
||||
port := rand.Intn(10000) + 40000
|
||||
h := Http{TimeOut: 200 * time.Millisecond, Address: fmt.Sprintf("127.0.0.1:%d", port)}
|
||||
h := Http{Timeouts: Timeouts{ResponseHeader: 200 * time.Millisecond}, Address: fmt.Sprintf("127.0.0.1:%d", port)}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
|
||||
defer cancel()
|
||||
|
||||
|
@ -24,7 +24,6 @@ import (
|
||||
type Http struct { //nolint golint
|
||||
Matcher
|
||||
Address string
|
||||
TimeOut time.Duration
|
||||
AssetsLocation string
|
||||
AssetsWebRoot string
|
||||
MaxBodySize int64
|
||||
@ -34,6 +33,7 @@ type Http struct { //nolint golint
|
||||
Version string
|
||||
AccessLog io.Writer
|
||||
DisableSignature bool
|
||||
Timeouts Timeouts
|
||||
}
|
||||
|
||||
// Matcher source info (server and route) to the destination url
|
||||
@ -44,6 +44,21 @@ type Matcher interface {
|
||||
Mappers() (mappers []discovery.URLMapper)
|
||||
}
|
||||
|
||||
// Timeouts consolidate timeouts for both server and transport
|
||||
type Timeouts struct {
|
||||
// server timeouts
|
||||
ReadHeader time.Duration
|
||||
Write time.Duration
|
||||
Idle time.Duration
|
||||
// transport timeouts
|
||||
Dial time.Duration
|
||||
KeepAlive time.Duration
|
||||
IdleConn time.Duration
|
||||
TLSHandshake time.Duration
|
||||
ExpectContinue time.Duration
|
||||
ResponseHeader time.Duration
|
||||
}
|
||||
|
||||
// Run the lister and request's router, activate rest server
|
||||
func (h *Http) Run(ctx context.Context) error {
|
||||
|
||||
@ -140,16 +155,16 @@ func (h *Http) proxyHandler() http.HandlerFunc {
|
||||
h.setXRealIP(r)
|
||||
},
|
||||
Transport: &http.Transport{
|
||||
ResponseHeaderTimeout: h.TimeOut,
|
||||
ResponseHeaderTimeout: h.Timeouts.ResponseHeader,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
Timeout: h.Timeouts.Dial,
|
||||
KeepAlive: h.Timeouts.KeepAlive,
|
||||
}).DialContext,
|
||||
ForceAttemptHTTP2: true,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
IdleConnTimeout: h.Timeouts.IdleConn,
|
||||
TLSHandshakeTimeout: h.Timeouts.TLSHandshake,
|
||||
ExpectContinueTimeout: h.Timeouts.ExpectContinue,
|
||||
},
|
||||
}
|
||||
|
||||
@ -229,9 +244,9 @@ func (h *Http) makeHTTPServer(addr string, router http.Handler) *http.Server {
|
||||
return &http.Server{
|
||||
Addr: addr,
|
||||
Handler: router,
|
||||
ReadHeaderTimeout: 5 * time.Second,
|
||||
WriteTimeout: 30 * time.Second,
|
||||
IdleTimeout: 30 * time.Second,
|
||||
ReadHeaderTimeout: h.Timeouts.ReadHeader,
|
||||
WriteTimeout: h.Timeouts.Write,
|
||||
IdleTimeout: h.Timeouts.Idle,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,8 @@ import (
|
||||
|
||||
func TestHttp_Do(t *testing.T) {
|
||||
port := rand.Intn(10000) + 40000
|
||||
h := Http{TimeOut: 200 * time.Millisecond, Address: fmt.Sprintf("127.0.0.1:%d", port), AccessLog: io.Discard}
|
||||
h := Http{Timeouts: Timeouts{ResponseHeader: 200 * time.Millisecond}, Address: fmt.Sprintf("127.0.0.1:%d", port),
|
||||
AccessLog: io.Discard}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
|
||||
defer cancel()
|
||||
|
||||
@ -92,7 +93,7 @@ func TestHttp_Do(t *testing.T) {
|
||||
|
||||
func TestHttp_DoWithAssets(t *testing.T) {
|
||||
port := rand.Intn(10000) + 40000
|
||||
h := Http{TimeOut: 200 * time.Millisecond, Address: fmt.Sprintf("127.0.0.1:%d", port),
|
||||
h := Http{Timeouts: Timeouts{ResponseHeader: 200 * time.Millisecond}, Address: fmt.Sprintf("127.0.0.1:%d", port),
|
||||
AccessLog: io.Discard, AssetsWebRoot: "/static", AssetsLocation: "testdata", DisableSignature: true}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
|
||||
defer cancel()
|
||||
|
Loading…
Reference in New Issue
Block a user