Skip to content

Commit

Permalink
Implement HTTP and TLS timeouts in CLI options.
Browse files Browse the repository at this point in the history
  • Loading branch information
wi1dcard committed Apr 18, 2024
1 parent 0bb5584 commit 21a2725
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 29 deletions.
20 changes: 5 additions & 15 deletions fingerproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"os"
"os/signal"
"syscall"
"time"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
Expand All @@ -23,15 +22,6 @@ import (

const logFlags = log.LstdFlags | log.Lshortfile | log.Lmsgprefix

const (
// TODO: expose these values in CLI flags
HTTPIdleTimeout = 180 * time.Second
HTTPReadTimeout = 60 * time.Second
HTTPWriteTimeout = 60 * time.Second
TLSHandshakeTimeout = 10 * time.Second
ReverseProxyFlushInterval = 100 * time.Millisecond
)

var (
// values are from CI build
BuildCommit = "GIT_COMMIT_PLACEHOLDER"
Expand Down Expand Up @@ -83,7 +73,7 @@ func defaultReverseProxyHTTPHandler(forwardTo *url.URL, headerInjectors []revers
forwardTo,
&httputil.ReverseProxy{
ErrorLog: ReverseProxyLog,
FlushInterval: ReverseProxyFlushInterval,
FlushInterval: parseReverseProxyFlushInterval(),
ErrorHandler: proxyErrorHandler,
// TODO: customize transport
Transport: http.DefaultTransport.(*http.Transport).Clone(),
Expand All @@ -110,10 +100,10 @@ func defaultProxyServer(handler http.Handler, tlsConfig *tls.Config) *proxyserve

svr.MetricsRegistry = PrometheusRegistry

svr.HTTPServer.IdleTimeout = HTTPIdleTimeout
svr.HTTPServer.ReadTimeout = HTTPReadTimeout
svr.HTTPServer.WriteTimeout = HTTPWriteTimeout
svr.TLSHandshakeTimeout = TLSHandshakeTimeout
svr.HTTPServer.IdleTimeout = parseHTTPIdleTimeout()
svr.HTTPServer.ReadTimeout = parseHTTPReadTimeout()
svr.HTTPServer.WriteTimeout = parseHTTPWriteTimeout()
svr.TLSHandshakeTimeout = parseTLSHandshakeTimeout()

return svr
}
Expand Down
107 changes: 94 additions & 13 deletions flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,30 @@ import (
"os"
"strconv"
"strings"
"time"
)

var (
flagListenAddr *string
flagForwardURL *string
flagCertFilename *string
flagKeyFilename *string
flagMetricsListenAddr *string
flagDurationMetricBuckets *string
flagPreserveHost *bool
flagEnableKubernetesProbe *bool
flagVerboseLogs *bool
flagVersion *bool
// basic
flagListenAddr, flagForwardURL *string

// tls
flagCertFilename, flagKeyFilename *string

// metrics
flagMetricsListenAddr, flagDurationMetricBuckets *string

// functionality
flagPreserveHost *bool
flagEnableKubernetesProbe *bool
flagReverseProxyFlushInterval *string

// timeouts
flagTimeoutHTTPIdle, flagTimeoutHTTPRead, flagTimeoutHTTPWrite, flagTimeoutTLSHandshake *string

// misc
flagVerboseLogs *bool
flagVersion *bool
)

func initFlags() {
Expand Down Expand Up @@ -72,6 +83,36 @@ func initFlags() {
"Enable kubernetes liveness/readiness probe support, equivalent to $ENABLE_KUBERNETES_PROBE",
)

flagReverseProxyFlushInterval = flag.String(
"reverse-proxy-flush-interval",
envWithDefault("REVERSE_PROXY_FLUSH_INTERVAL", "100ms"),
"See https://pkg.go.dev/net/http/httputil#ReverseProxy.FlushInterval, equivalent to $REVERSE_PROXY_FLUSH_INTERVAL",
)

flagTimeoutHTTPIdle = flag.String(
"timeout-http-idle",
envWithDefault("TIMEOUT_HTTP_IDLE", "180s"),
"See https://pkg.go.dev/net/http#Server.IdleTimeout, equivalent to $TIMEOUT_HTTP_IDLE",
)

flagTimeoutHTTPRead = flag.String(
"timeout-http-read",
envWithDefault("TIMEOUT_HTTP_READ", "60s"),
"See https://pkg.go.dev/net/http#Server.ReadTimeout, equivalent to $TIMEOUT_HTTP_READ",
)

flagTimeoutHTTPWrite = flag.String(
"timeout-http-write",
envWithDefault("TIMEOUT_HTTP_WRITE", "60s"),
"See https://pkg.go.dev/net/http#Server.WriteTimeout, equivalent to $TIMEOUT_HTTP_WRITE",
)

flagTimeoutTLSHandshake = flag.String(
"timeout-tls-handshake",
envWithDefault("TIMEOUT_TLS_HANDSHAKE", "10s"),
"Timeout for TLS handshakes, equivalent to $TIMEOUT_TLS_HANDSHAKE",
)

flagVerboseLogs = flag.Bool(
"verbose",
envWithDefaultBool("VERBOSE", false),
Expand All @@ -94,7 +135,7 @@ func parseFlags() {
func parseForwardURL() *url.URL {
forwardURL, err := url.Parse(*flagForwardURL)
if err != nil {
DefaultLog.Fatal(err)
DefaultLog.Fatalf(`invalid forward url "%s": %s`, *flagForwardURL, err)
}

return forwardURL
Expand All @@ -103,7 +144,7 @@ func parseForwardURL() *url.URL {
func parseTLSCerts() tls.Certificate {
tlsCert, err := tls.LoadX509KeyPair(*flagCertFilename, *flagKeyFilename)
if err != nil {
DefaultLog.Fatal(err)
DefaultLog.Fatalf(`invalid cert filename "%s" or certkey filename "%s": %s`, *flagCertFilename, *flagKeyFilename, err)
}
return tlsCert
}
Expand All @@ -115,10 +156,50 @@ func parseDurationMetricBuckets() []float64 {
for _, bucket := range bucketStrings {
parsedBucket, err := strconv.ParseFloat(strings.Trim(bucket, " "), 64)
if err != nil {
DefaultLog.Fatalf("bad duration metric buckets: %s", err)
DefaultLog.Fatalf(`invalid duration metric bucket "%s": %s`, bucket, err)
}
buckets = append(buckets, parsedBucket)
}

return buckets
}

func parseReverseProxyFlushInterval() time.Duration {
dur, err := time.ParseDuration(*flagReverseProxyFlushInterval)
if err != nil {
DefaultLog.Fatalf(`invalid tls handshake timeout "%s": %s`, *flagReverseProxyFlushInterval, dur)
}
return dur
}

func parseHTTPIdleTimeout() time.Duration {
dur, err := time.ParseDuration(*flagTimeoutHTTPIdle)
if err != nil {
DefaultLog.Fatalf(`invalid http idle timeout "%s": %s`, *flagTimeoutHTTPIdle, err)
}
return dur
}

func parseHTTPReadTimeout() time.Duration {
dur, err := time.ParseDuration(*flagTimeoutHTTPRead)
if err != nil {
DefaultLog.Fatalf(`invalid http read timeout "%s": %s`, *flagTimeoutHTTPRead, err)
}
return dur
}

func parseHTTPWriteTimeout() time.Duration {
dur, err := time.ParseDuration(*flagTimeoutHTTPWrite)
if err != nil {
DefaultLog.Fatalf(`invalid http write timeout "%s": %s`, *flagTimeoutHTTPWrite, err)
}
return dur
}

func parseTLSHandshakeTimeout() time.Duration {
dur, err := time.ParseDuration(*flagTimeoutTLSHandshake)
if err != nil {
DefaultLog.Fatalf(`invalid tls handshake timeout "%s": %s`, *flagTimeoutTLSHandshake, err)
}
return dur
}
1 change: 0 additions & 1 deletion pkg/ja4/ja4.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ const (
signatureAlgorithmSeparator = ","
)

// TODO: add tests
type JA4Fingerprint struct {
//
// JA4_a
Expand Down

0 comments on commit 21a2725

Please sign in to comment.