What would it take to build a simple proxy server using ServiceStack? [closed]

隐身守侯 提交于 2019-12-23 05:47:12

问题


I'm wondering how difficult it would be to build a proxy service upon/with ServiceStack. Considering how fast ServiceStack is with Redis / serialization / etc., and how simple it is to implement the stack in general, this seems very tempting. Anyone else attempt this? How difficult would this be?


回答1:


A new Proxy Feature was added in ServiceStack v4.5.10 that greatly simplifies creating a proxy where you can create a proxy by just registering a plugin, e.g:

Plugins.Add(new ProxyFeature(
    matchingRequests: req => req.PathInfo.StartsWith("/proxy"),
    resolveUrl:req => $"http://remote.server.org" + req.RawUrl.Replace("/proxy","/")) 
{
    // Use TransformResponse to rewrite response returned
    TransformResponse = async (res, responseStream) => 
    {
        using (var reader = new StreamReader(responseStream, Encoding.UTF8))
        {
            var responseBody = await reader.ReadToEndAsync();
            var replacedBody = responseBody.Replace(
                "http://remote.server.org",
                "https://external.domain.com/proxy");
            return MemoryStreamFactory.GetStream(replacedBody.ToUtf8Bytes());
        }
    }
})

Which fill forward all requests to /proxy in your ServiceStack instance to http://remote.server.org.

Manually Creating a Reverse Proxy

The first entry in ServiceStack's Request Pipeline lets your register Raw ASP.NET IHttpHandlers which can execute raw ASP.NET Handlers and take over executing the request from ServiceStack.

This will let you use a use an ASP.NET IHttpHandler proxy like this by registering it your AppHost, e.g:

this.RawHttpHandlers.Add(httpReq =>
    httpReq.PathInfo.StartsWith("/proxy")
        ? new ReverseProxy()
        : null);                

This would tell ServiceStack to execute requests starting with /proxy with the custom ReverseProxy IHttpHandler.

If you want to use it in ServiceStack's self-hosts you would also have to change ReverseProxy to also inherit from ServiceStack's convenient HttpAsyncTaskHandler base class (or just implement IServiceStackHandler), e.g:

public class ReverseProxy : HttpAsyncTaskHandler
{
    public override void ProcessRequest(IRequest req, IResponse res, 
        string operationName)
    {
        var httpReq = (IHttpRequest)req; //Get HTTP-specific Interfaces
        var httpRes = (IHttpResponse)res;

        // Create a connection to the Remote Server to redirect all requests
        var server = new RemoteServer(httpReq, httpRes);
        // Create a request with same data in navigator request
        HttpWebRequest request = server.GetRequest();

        // Send the request to the remote server and return the response
        HttpWebResponse response = server.GetResponse(request);
        byte[] responseData = server.GetResponseStreamBytes(response);

        // Send the response to client
        res.ContentType = response.ContentType;
        res.OutputStream.Write(responseData, 0, responseData.Length);
        server.SetContextCookies(response); // Handle cookies to navigator

        res.EndHttpHandlerRequest(); // End Request
    }

    public override void ProcessRequest(HttpContextBase context)
    {
        var httpReq = context.ToRequest("CustomAction");
        ProcessRequest(httpReq, httpReq.Response, "CustomAction");
    }

    ....
}

You would also have to refactor the implementation of RemoteServer in the example to work with ServiceStack's IHttpRequest / IHttpResponse interfaces.

If it's needed you can also access the underlying ASP.NET (or HttpListener) request objects with:

var aspNetReq = httpReq.OriginalRequest as HttpRequestBase; 
var aspNetRes = httpRes.OriginalResponse as HttpResponseBase; 


来源:https://stackoverflow.com/questions/21945412/what-would-it-take-to-build-a-simple-proxy-server-using-servicestack

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!