Skip to content

Instantly share code, notes, and snippets.

@jonathanpeppers
Last active February 4, 2017 06:00
Show Gist options
  • Save jonathanpeppers/26b993f5c393c351852782fc38d6f92c to your computer and use it in GitHub Desktop.
Save jonathanpeppers/26b993f5c393c351852782fc38d6f92c to your computer and use it in GitHub Desktop.
Custom IHttpClient for SignalR
public class NativeHttpClient : IHttpClient
{
private HttpClient _client;
private IConnection _connection;
public void Initialize(IConnection connection)
{
_connection = connection;
_client = new HttpClient();
_client.Timeout = TimeSpan.FromMilliseconds(-1); //NOTE: infinite timeout because upper SignalR layer handles timeouts
}
public async Task<IResponse> Get(string url, Action<IRequest> prepareRequest, bool isLongRunning)
{
var request = new Request(HttpMethod.Get, url);
prepareRequest(request);
return await Send(request, isLongRunning);
}
public async Task<IResponse> Post(string url, Action<IRequest> prepareRequest, IDictionary<string, string> postData, bool isLongRunning)
{
var request = new Request(HttpMethod.Post, url);
request.Content = new FormUrlEncodedContent(postData);
prepareRequest(request);
return await Send(request, isLongRunning);
}
private async Task<IResponse> Send(Request request, bool isLongRunning)
{
var option = isLongRunning ? HttpCompletionOption.ResponseHeadersRead : HttpCompletionOption.ResponseContentRead;
var httpResponse = await _client.SendAsync(request, option, request.Cancellation.Token);
var response = new Response(httpResponse);
await response.ReadStream();
return response;
}
private class Request : HttpRequestMessage, IRequest
{
public Request(HttpMethod method, string url) : base(method, url) { }
public CancellationTokenSource Cancellation = new CancellationTokenSource();
public string UserAgent { get; set; }
public string Accept { get; set; }
public void Abort()
{
Cancellation.Cancel();
}
public void SetRequestHeaders(IDictionary<string, string> headers)
{
if (UserAgent != null)
{
Headers.TryAddWithoutValidation("User-Agent", UserAgent);
}
if (Accept != null)
{
Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(Accept));
}
foreach (KeyValuePair<string, string> headerEntry in headers)
{
Headers.Add(headerEntry.Key, headerEntry.Value);
}
}
}
private class Response : IResponse
{
private HttpResponseMessage _response;
private Stream _stream;
public Response(HttpResponseMessage response)
{
_response = response;
}
public async Task ReadStream()
{
_stream = await _response.Content.ReadAsStreamAsync();
}
public Stream GetStream()
{
return _stream;
}
public void Dispose()
{
if (_stream != null)
{
_stream.Dispose();
_stream = null;
}
if (_response != null)
{
_response.Dispose();
_response = null;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment