Created
May 29, 2013 01:29
-
-
Save pmhsfelix/5667375 to your computer and use it in GitHub Desktop.
A ASP.NET Web API based local proxy that forwards via Runscope, using @darrelmiller RunscopeMessageHandler. Just configure your HTTP client (e.g. a browser) to use a proxy at 127.0.01:8080
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Concurrent; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Linq; | |
using System.Net; | |
using System.Net.Http; | |
using System.Net.Http.Headers; | |
using System.ServiceModel; | |
using System.Text; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using System.Web.Http.SelfHost; | |
namespace SelfHostedProxy | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
const string bucketKey = TODO; | |
Trace.Listeners.Add(new ConsoleTraceListener()); | |
var config = new HttpSelfHostConfiguration("http://localhost:8080") | |
{ | |
TransferMode = TransferMode.Streamed | |
}; | |
var server = new HttpSelfHostServer(config, new ChangeRequestUriToOriginServer(new RunscopeMessageHandler(bucketKey, new ProxyMessageHandler()))); | |
server.OpenAsync().Wait(); | |
Trace.TraceInformation("server is opened"); | |
Console.ReadKey(); | |
server.CloseAsync().Wait(); | |
Trace.TraceInformation("server is closed, bye"); | |
} | |
} | |
internal class ChangeRequestUriToOriginServer : DelegatingHandler | |
{ | |
public ChangeRequestUriToOriginServer(HttpMessageHandler next) | |
{ | |
InnerHandler = next; | |
} | |
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) | |
{ | |
var host = request.Headers.Host; | |
request.RequestUri = new Uri(new Uri(request.RequestUri.Scheme + "://" + host), request.RequestUri.PathAndQuery); | |
return base.SendAsync(request, cancellationToken); | |
} | |
} | |
internal class ProxyMessageHandler : DelegatingHandler | |
{ | |
private static readonly HttpClient client = new HttpClient(); | |
async protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) | |
{ | |
try{ | |
request.Headers.TransferEncoding.Clear(); | |
RemoveConnectionHeadersFrom(request.Headers, request.Headers.Connection); | |
if(request.Content != null && request.Content.Headers.ContentType == null) | |
{ | |
request.Content = null; | |
} | |
Trace.TraceInformation("forwarding {0} request to {1}", request.Method, request.RequestUri); | |
request.Headers.Host = null; | |
var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken); | |
response.Headers.TransferEncoding.Clear(); | |
RemoveConnectionHeadersFrom(response.Headers, response.Headers.Connection); | |
Trace.TraceInformation("received {0} response from {1} with status {2}", | |
request.Method, request.RequestUri, response.StatusCode); | |
return response; | |
}catch(Exception e) | |
{ | |
return new HttpResponseMessage(HttpStatusCode.InternalServerError) | |
{ | |
Content = new StringContent(e.Message) | |
}; | |
} | |
} | |
private static void RemoveConnectionHeadersFrom(HttpHeaders headers, IEnumerable<string> names ) | |
{ | |
foreach (var name in names) | |
{ | |
headers.Remove(name); | |
} | |
headers.Remove("Connection"); | |
} | |
} | |
public class RunscopeMessageHandler : DelegatingHandler | |
{ | |
//... Get it from https://github.com/darrelmiller/RunscopeMessageHandler | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment