Skip to content

Instantly share code, notes, and snippets.

@shiftkey
Created January 13, 2014 16:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shiftkey/8402772 to your computer and use it in GitHub Desktop.
Save shiftkey/8402772 to your computer and use it in GitHub Desktop.
Wireup a HttpClient with proxy support in Octokit.net
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace Octokit
{
/// <summary>
/// Generic Http client with Proxy support for use in Octokit.net
/// </summary>
public class HttpClientWithProxyAdapter : IHttpClient
{
readonly IWebProxy _proxy;
public HttpClientWithProxyAdapter(IWebProxy proxy)
{
_proxy = proxy;
}
public async Task<IResponse<T>> Send<T>(IRequest request)
{
Ensure.ArgumentNotNull(request, "request");
var httpOptions = new HttpClientHandler
{
AllowAutoRedirect = request.AllowAutoRedirect
};
if (httpOptions.SupportsProxy)
{
httpOptions.UseProxy = true;
httpOptions.Proxy = _proxy;
}
if (httpOptions.SupportsAutomaticDecompression)
{
httpOptions.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
}
var http = new HttpClient(httpOptions)
{
BaseAddress = request.BaseAddress,
Timeout = request.Timeout,
};
using (var requestMessage = BuildRequestMessage(request))
{
// Make the request
var responseMessage = await http.SendAsync(requestMessage, HttpCompletionOption.ResponseContentRead)
.ConfigureAwait(false);
return await BuildResponse<T>(responseMessage).ConfigureAwait(false);
}
}
protected async virtual Task<IResponse<T>> BuildResponse<T>(HttpResponseMessage responseMessage)
{
Ensure.ArgumentNotNull(responseMessage, "responseMessage");
string responseBody = null;
string contentType = null;
using (var content = responseMessage.Content)
{
if (content != null)
{
responseBody = await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);
contentType = GetContentType(content);
}
}
var response = new ApiResponse<T>
{
Body = responseBody,
StatusCode = responseMessage.StatusCode,
ContentType = contentType
};
foreach (var h in responseMessage.Headers)
{
response.Headers.Add(h.Key, h.Value.First());
}
return response;
}
protected virtual HttpRequestMessage BuildRequestMessage(IRequest request)
{
Ensure.ArgumentNotNull(request, "request");
HttpRequestMessage requestMessage = null;
try
{
requestMessage = new HttpRequestMessage(request.Method, request.Endpoint);
foreach (var header in request.Headers)
{
requestMessage.Headers.Add(header.Key, header.Value);
}
var httpContent = request.Body as HttpContent;
if (httpContent != null)
{
requestMessage.Content = httpContent;
}
var body = request.Body as string;
if (body != null)
{
requestMessage.Content = new StringContent(body, Encoding.UTF8, request.ContentType);
}
var bodyStream = request.Body as Stream;
if (bodyStream != null)
{
requestMessage.Content = new StreamContent(bodyStream);
requestMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(request.ContentType);
}
}
catch (Exception)
{
if (requestMessage != null)
{
requestMessage.Dispose();
}
throw;
}
return requestMessage;
}
static string GetContentType(HttpContent httpContent)
{
if (httpContent.Headers != null && httpContent.Headers.ContentType != null)
{
return httpContent.Headers.ContentType.MediaType;
}
return null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment