diff --git a/client/native/client.go b/client/native/client.go index 6302005..9757b9c 100644 --- a/client/native/client.go +++ b/client/native/client.go @@ -49,6 +49,10 @@ type Options struct { // Logger provides a logger which should be used for this client. Logger *slog.Logger + + // HTTPClient sends ARI REST requests. When nil, a client using the package + // RequestTimeout is created. + HTTPClient *http.Client } // ConnectWithContext creates and connects a new Client to Asterisk ARI. @@ -143,9 +147,15 @@ func New(opts *Options) *Client { &slog.HandlerOptions{Level: slog.LevelError})) } + httpClient := opts.HTTPClient + if httpClient == nil { + httpClient = &http.Client{Timeout: RequestTimeout} + } + return &Client{ - appName: opts.Application, - Options: opts, + appName: opts.Application, + Options: opts, + httpClient: httpClient, } } @@ -168,7 +178,7 @@ type Client struct { bus ari.Bus // httpClient is the reusable HTTP client on which commands to Asterisk are sent - httpClient http.Client + httpClient *http.Client cancel context.CancelFunc } diff --git a/client/native/request_test.go b/client/native/request_test.go new file mode 100644 index 0000000..a289d53 --- /dev/null +++ b/client/native/request_test.go @@ -0,0 +1,48 @@ +package native + +import ( + "net" + "net/http" + "net/http/httptest" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestRequestStopsAtCustomHTTPClientTimeout(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(_ http.ResponseWriter, request *http.Request) { + <-request.Context().Done() + })) + defer server.Close() + + httpClient := &http.Client{Timeout: 25 * time.Millisecond} + client := New(&Options{ + URL: server.URL, + HTTPClient: httpClient, + }) + + startedAt := time.Now() + err := client.get("/channels", nil) + + require.Error(t, err) + require.Less(t, time.Since(startedAt), 500*time.Millisecond) + + var networkError net.Error + require.ErrorAs(t, err, &networkError) + require.True(t, networkError.Timeout()) +} + +func TestNewUsesProvidedHTTPClient(t *testing.T) { + httpClient := &http.Client{} + + client := New(&Options{HTTPClient: httpClient}) + + require.Same(t, httpClient, client.httpClient) +} + +func TestNewUsesPackageDefaultRequestTimeout(t *testing.T) { + client := New(&Options{}) + + require.Equal(t, RequestTimeout, client.httpClient.Timeout) +}