Skip to content

Commit

Permalink
Merge pull request #81 from jonnii/configurable-timeouts
Browse files Browse the repository at this point in the history
Ability to configure httpclient timeout
  • Loading branch information
jonnii authored Jul 31, 2018
2 parents 2039247 + 58848ed commit 493fce0
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 8 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 1.1.0

* Add ability to customize the HttpClient global timeout

## 1.0.0

* Add `netstandard1.6` target
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<AssemblyTitle>SpeakEasy.IntegrationTests</AssemblyTitle>
<VersionPrefix>2.0.0</VersionPrefix>
<Authors>jonnii</Authors>
<TargetFrameworks>netcoreapp2.0</TargetFrameworks>
<TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<AssemblyName>SpeakEasy.IntegrationTests</AssemblyName>
<PackageId>SpeakEasy.IntegrationTests</PackageId>
<PackageTags>SpeakEasy.IntegrationTests</PackageTags>
Expand Down
6 changes: 3 additions & 3 deletions src/SpeakEasy.Specifications/HttpClientSettingsSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,13 @@ class when_replacing_middleware_with_same_type
settings.Middleware.Replace(replacement);

It should_replace_middleware_in_place = () =>
settings.Middleware.AtPosition(1).ShouldBeOfExactType<UserAgentMiddleware>();
settings.Middleware.AtPosition(2).ShouldBeOfExactType<UserAgentMiddleware>();

It should_have_correct_middleware_count = () =>
settings.Middleware.Count.ShouldEqual(3);
settings.Middleware.Count.ShouldEqual(4);

It should_replace_instance = () =>
settings.Middleware.AtPosition(1).ShouldBeTheSameAs(replacement);
settings.Middleware.AtPosition(2).ShouldBeTheSameAs(replacement);
}

class TestMiddleware : IHttpMiddleware
Expand Down
16 changes: 15 additions & 1 deletion src/SpeakEasy.Specifications/HttpClientSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,24 @@ class when_building_system_client
static SystemHttpClient system_http_client;

Because of = () =>
system_http_client = client.BuildSystemClient(new CookieContainer());
system_http_client = client.BuildSystemClient(new CookieContainer(), null);

It should_create_client = () =>
system_http_client.ShouldNotBeNull();

It should_create_with_system_default_timeout = () =>
system_http_client.Timeout.ShouldEqual(new SystemHttpClient().Timeout);
}

class when_building_system_client_with_custom_timeout
{
static SystemHttpClient system_http_client;

Because of = () =>
system_http_client = client.BuildSystemClient(new CookieContainer(), TimeSpan.FromMinutes(10));

It should_create_with_custom_timeout = () =>
system_http_client.Timeout.ShouldEqual(TimeSpan.FromMinutes(10));
}

class when_getting_collection_resource
Expand Down
2 changes: 1 addition & 1 deletion src/SpeakEasy.Specifications/UserAgentSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class UserAgentSpecs
class default_user_agent
{
It should_contain_app_version = () =>
UserAgent.SpeakEasy.Name.ShouldEqual("SpeakEasy/1.0.0.0");
UserAgent.SpeakEasy.Name.ShouldContain("SpeakEasy/1.0");
}
}
}
10 changes: 8 additions & 2 deletions src/SpeakEasy/HttpClient.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
Expand Down Expand Up @@ -43,7 +44,7 @@ internal HttpClient(string rootUrl, HttpClientSettings settings)
settings.Validate();

var cookieContainer = new CookieContainer();
var client = BuildSystemClient(cookieContainer);
var client = BuildSystemClient(cookieContainer, settings.DefaultTimeout);

requestRunner = new RequestRunner(
client,
Expand Down Expand Up @@ -75,7 +76,7 @@ internal HttpClient(

public Resource Root { get; }

internal System.Net.Http.HttpClient BuildSystemClient(CookieContainer cookieContainer)
internal System.Net.Http.HttpClient BuildSystemClient(CookieContainer cookieContainer, TimeSpan? defaultTimeout)
{
var handler = new HttpClientHandler
{
Expand All @@ -89,6 +90,11 @@ internal System.Net.Http.HttpClient BuildSystemClient(CookieContainer cookieCont

var httpClient = new System.Net.Http.HttpClient(handler);

if (defaultTimeout != null)
{
httpClient.Timeout = defaultTimeout.Value;
}

settings.Authenticator.Authenticate(httpClient);

return httpClient;
Expand Down
8 changes: 8 additions & 0 deletions src/SpeakEasy/HttpClientSettings.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using SpeakEasy.ArrayFormatters;
using SpeakEasy.Authenticators;
using SpeakEasy.Middleware;
Expand All @@ -26,6 +27,7 @@ public HttpClientSettings()
Serializers.Add(new DefaultJsonSerializer());
Serializers.Add(new TextPlainSerializer());

Middleware.Append(new TimeoutMiddleware());
Middleware.Append(new UserAgentMiddleware());
}

Expand Down Expand Up @@ -69,6 +71,12 @@ public HttpClientSettings()
/// </summary>
public bool IsValid => Serializers.Any() && ArrayFormatter != null;

/// <summary>
/// The default timeout for the HttpClient to 30 minutes,
/// to use the system default (100 seconds) set this property to null.
/// </summary>
public TimeSpan? DefaultTimeout { get; set; } = TimeSpan.FromMinutes(30);

/// <summary>
/// Configures the give serializer
/// </summary>
Expand Down
23 changes: 23 additions & 0 deletions src/SpeakEasy/Middleware/TimeoutMiddleware.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Threading;
using System.Threading.Tasks;

namespace SpeakEasy.Middleware
{
public class TimeoutMiddleware : IHttpMiddleware
{
public IHttpMiddleware Next { get; set; }

public async Task<IHttpResponse> Invoke(IHttpRequest request, CancellationToken cancellationToken)
{
try
{
return await Next.Invoke(request, cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested)
{
throw new TimeoutException();
}
}
}
}

0 comments on commit 493fce0

Please sign in to comment.