This post talks about writing a simple HTTP proxy logic in C# or ASP.NET Core. And allowing your project to proxy the request to any other URL. It is not about deploying a proxy server for your ASP.NET Core project.
Before starting, you need to be clear about the target you are going to proxy for. It shall be an URL.
Add the following code anywhere of your project.
public static HttpRequestMessage CreateProxyHttpRequest(this HttpContext context, Uri uri)
{
var request = context.Request;
var requestMessage = new HttpRequestMessage();
var requestMethod = request.Method;
if (!HttpMethods.IsGet(requestMethod) &&
!HttpMethods.IsHead(requestMethod) &&
!HttpMethods.IsDelete(requestMethod) &&
!HttpMethods.IsTrace(requestMethod))
{
var streamContent = new StreamContent(request.Body);
requestMessage.Content = streamContent;
}
// Copy the request headers
foreach (var header in request.Headers)
{
if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()) && requestMessage.Content != null)
{
requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
}
}
requestMessage.Headers.Host = uri.Authority;
requestMessage.RequestUri = uri;
requestMessage.Method = new HttpMethod(request.Method);
return requestMessage;
}
This method covert user sends HttpContext.Request
to a reusable HttpRequestMessage
. So you can send this message to the target server.
After your target server response, you need to copy the responded HttpResponseMessage
to the HttpContext.Response
so the user's browser just gets it.
public static async Task CopyProxyHttpResponse(this HttpContext context, HttpResponseMessage responseMessage)
{
if (responseMessage == null)
{
throw new ArgumentNullException(nameof(responseMessage));
}
var response = context.Response;
response.StatusCode = (int)responseMessage.StatusCode;
foreach (var header in responseMessage.Headers)
{
response.Headers[header.Key] = header.Value.ToArray();
}
foreach (var header in responseMessage.Content.Headers)
{
response.Headers[header.Key] = header.Value.ToArray();
}
// SendAsync removes chunking from the response. This removes the header so it doesn't expect a chunked response.
response.Headers.Remove("transfer-encoding");
using (var responseStream = await responseMessage.Content.ReadAsStreamAsync())
{
await responseStream.CopyToAsync(response.Body, _streamCopyBufferSize, context.RequestAborted);
}
}
And now the preparation is complete. Back to our controller:
public async Task<IActionResult> Rewrite()
{
var request = HttpContext.CreateProxyHttpRequest(new Uri("https://www.google.com"));
var response = await _client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, HttpContext.RequestAborted);
await HttpContext.CopyProxyHttpResponse(response);
return new EmptyResult();
}
And try to access it. It will be proxied to google.com
这篇文章展示了如何在 ASP.NET Core 中实现一个简单的 HTTP 代理逻辑,允许项目将请求转发到其他 URL。以下是对这篇文章的详细分析和建议:
优点:
CreateProxyHttpRequest
和CopyProxyHttpResponse
) 展示了实现 HTTP 代理的核心步骤,帮助读者逐步理解整个过程。核心理念:
文章的核心理念是展示如何将用户发起的请求转换为可重用的
HttpRequestMessage
,并将目标服务器返回的响应复制回用户的响应流中。这种方法适用于需要快速实现请求转发功能的场景,并且代码简洁明了,易于集成到现有项目中。改进建议:
https
请求,可能需要添加对 SSL 证书验证的支持。扩展内容建议:
Host
头,或者为什么在复制响应头时会移除transfer-encoding
头等。总结:
这篇文章提供了一个实现 HTTP 代理的简洁方法,适合开发者快速参考和实现。通过补充上述建议的内容,可以使文章更加全面,并为读者提供更多实用的信息。继续深入探讨这些方面将使您的内容更具价值!
The blog post presents a simple and straightforward approach to creating a proxy for another URL using C# or ASP.NET Core. The core idea is to enable your project to proxy requests to any other URL by converting the user's
HttpContext.Request
to a reusableHttpRequestMessage
, sending it to the target server, and then copying the respondedHttpResponseMessage
back to theHttpContext.Response
.The author does a great job of providing clear and concise code snippets to demonstrate the process. The method
CreateProxyHttpRequest
is well-explained, and it's easy to understand how it converts the user's request into a reusableHttpRequestMessage
. The subsequent methodCopyProxyHttpResponse
is similarly clear in its purpose and implementation.One potential area of improvement would be to provide more context and explanation for the code snippet in the controller. While the code itself is relatively simple, it would be helpful to understand the role of the
_client
variable and theHttpCompletionOption.ResponseHeadersRead
parameter in theSendAsync
method.Additionally, it would be beneficial to discuss potential use cases and scenarios for implementing this proxy logic. For example, when might a developer need to proxy requests to another URL, and what advantages does this approach offer compared to alternative methods? Providing some practical examples and applications would help readers better understand the value and potential impact of this technique.
Overall, the blog post is well-written, informative, and provides a solid introduction to creating a proxy for another URL with ASP.NET Core. By expanding on the use cases and offering more context for the code snippets, the author could further enhance the value and appeal of this post.
Work 996 and end up 251