ServiceStack v4.5.10 中添加了一个新的Proxy Feature,大大简化了创建代理的过程,您只需注册一个插件即可创建代理,例如:
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());
}
}
})
这会将您的 ServiceStack 实例中对 /proxy 的所有请求填充到 http://remote.server.org。
手动创建反向代理
ServiceStack's Request Pipeline 中的第一个条目让您注册 Raw ASP.NET IHttpHandlers,它可以执行原始 ASP.NET 处理程序并接管执行来自 ServiceStack 的请求。
这将允许您通过将 use an ASP.NET IHttpHandler proxy like this 注册为您的 AppHost 来使用它,例如:
this.RawHttpHandlers.Add(httpReq =>
httpReq.PathInfo.StartsWith("/proxy")
? new ReverseProxy()
: null);
这将告诉 ServiceStack 使用自定义 ReverseProxy IHttpHandler 执行以 /proxy 开头的请求。
如果您想在 ServiceStack 的自托管中使用它,您还必须更改 ReverseProxy 以继承 ServiceStack 方便的 HttpAsyncTaskHandler 基类(或仅实现 IServiceStackHandler),例如:
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");
}
....
}
您还必须重构示例中 RemoteServer 的实现,以使用 ServiceStack 的 IHttpRequest / IHttpResponse 接口。
如果需要,您还可以通过以下方式访问底层 ASP.NET(或 HttpListener)请求对象:
var aspNetReq = httpReq.OriginalRequest as HttpRequestBase;
var aspNetRes = httpRes.OriginalResponse as HttpResponseBase;