Skip to content

Commit

Permalink
client: add optional http timeout (#270)
Browse files Browse the repository at this point in the history
  • Loading branch information
komuw authored Jun 8, 2023
1 parent c5a2a85 commit e940f49
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Most recent version is listed first.
# v0.0.49
- Add mux Resolve function: https://github.com/komuw/ong/pull/268
- Use http.Handler as the http middleware instead of http.HandlerFunc: https://github.com/komuw/ong/pull/269
- Add optional http timeout: https://github.com/komuw/ong/pull/270

## v0.0.48
- Change attest import path: https://github.com/komuw/ong/pull/265
Expand Down
33 changes: 21 additions & 12 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ import (
const (
logIDHeader = string(octx.LogCtxKey)
errPrefix = "ong/client:"
// The wikipedia monitoring dashboards are public: https://grafana.wikimedia.org/?orgId=1
// In there we can see that the p95 response times for http GET requests is ~700ms: https://grafana.wikimedia.org/d/RIA1lzDZk/application-servers-red?orgId=1
// and the p95 response times for http POST requests is ~3seconds:
// Thus, we set the timeout to be twice that.
defaultTimeout = 3 * 2 * time.Second
)

// Most of the code here is inspired by(or taken from):
Expand All @@ -31,24 +36,28 @@ const (

// Safe creates a http client that has some good defaults & is safe from server-side request forgery (SSRF).
// It also logs requests and responses using [log.Logger]
func Safe(l *slog.Logger) *http.Client {
return new(true, l)
// The timeout is optional.
func Safe(l *slog.Logger, timeout ...time.Duration) *http.Client {
t := defaultTimeout
if len(timeout) > 0 {
t = timeout[0]
}
return new(true, t, l)
}

// Unsafe creates a http client that has some good defaults & is NOT safe from server-side request forgery (SSRF).
// It also logs requests and responses using [log.Logger]
func Unsafe(l *slog.Logger) *http.Client {
return new(false, l)
// The timeout is optional
func Unsafe(l *slog.Logger, timeout ...time.Duration) *http.Client {
t := defaultTimeout
if len(timeout) > 0 {
t = timeout[0]
}
return new(false, t, l)
}

// new creates a client. Use [Safe] or [Unsafe] instead.
func new(ssrfSafe bool, l *slog.Logger) *http.Client {
// The wikipedia monitoring dashboards are public: https://grafana.wikimedia.org/?orgId=1
// In there we can see that the p95 response times for http GET requests is ~700ms: https://grafana.wikimedia.org/d/RIA1lzDZk/application-servers-red?orgId=1
// and the p95 response times for http POST requests is ~3seconds:
// Thus, we set the timeout to be twice that.
timeout := 3 * 2 * time.Second

func new(ssrfSafe bool, timeout time.Duration, l *slog.Logger) *http.Client {
dialer := &net.Dialer{
// Using Dialer.ControlContext instead of Dialer.Control allows;
// - propagation of logging contexts, metric context or other metadata down to the callback.
Expand Down Expand Up @@ -81,7 +90,7 @@ func new(ssrfSafe bool, l *slog.Logger) *http.Client {
MaxIdleConns: 100,
IdleConnTimeout: 3 * timeout,
TLSHandshakeTimeout: timeout,
ExpectContinueTimeout: 1 * time.Second,
ExpectContinueTimeout: (timeout / 5),
}

lr := &loggingRT{transport, l}
Expand Down
2 changes: 1 addition & 1 deletion mux/mux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ func TestMux(t *testing.T) {
"ong/mux/mux_test.go:26", // location where `someMuxHandler` is declared.
},
{
"failure",
"bad",
"/",
"",
"",
Expand Down

0 comments on commit e940f49

Please sign in to comment.