创建代理转发的中间件的一段代码不太明白,有高手帮忙解释下。

一品梅 2021-04-08 01:59:02
public class ProxyMiddleware
{
// private ProxyHttpClient _proxyHttpClient;
private const string CDN_HEADER_NAME = "Cache-Control";
private static readonly string[] NotForwardedHttpHeaders = new[] { "Connection", "Host" };////Http头文件的这两个属性在下面代码中用到,这两个状态属性是什么意思,如果头文件中没有这两个属性,代表什么意思呢?
private readonly RequestDelegate _next;
private readonly ILogger<ProxyMiddleware> _logger;

public ProxyMiddleware(
RequestDelegate next,
ILogger<ProxyMiddleware> logger

)
{
_next = next;
_logger = logger;
//_proxyHttpClient = proxyHttpClient;
}

/// <summary>
/// 通过中间件,拦截访问,检测前缀,并转发
/// </summary>
/// <param name="context"></param>
/// <param name="urlRewriter"></param>
/// <returns></returns>
public async Task Invoke(HttpContext context, IUrlRewriter urlRewriter, ProxyHttpClient proxyHttpClient)
{
var targetUri = await urlRewriter.RewriteUri(context);

if (targetUri != null)
{
var requestMessage = GenerateProxifiedRequest(context, targetUri);
await SendAsync(context, requestMessage, proxyHttpClient);

return;
}

await _next(context);
}

private async Task SendAsync(HttpContext context, HttpRequestMessage requestMessage, ProxyHttpClient proxyHttpClient)
{


using (var responseMessage = await proxyHttpClient.Client.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted))
{
context.Response.StatusCode = (int)responseMessage.StatusCode;

foreach (var header in responseMessage.Headers)
{
context.Response.Headers[header.Key] = header.Value.ToArray();
}

foreach (var header in responseMessage.Content.Headers)
{
context.Response.Headers[header.Key] = header.Value.ToArray();
}

context.Response.Headers.Remove("transfer-encoding");

if (!context.Response.Headers.ContainsKey(CDN_HEADER_NAME))
{
context.Response.Headers.Add(CDN_HEADER_NAME, "no-cache, no-store");
}

await responseMessage.Content.CopyToAsync(context.Response.Body);
}
}

private static HttpRequestMessage GenerateProxifiedRequest(HttpContext context, Uri targetUri)
{
var requestMessage = new HttpRequestMessage();
CopyRequestContentAndHeaders(context, requestMessage);
requestMessage.RequestUri = targetUri;
requestMessage.Headers.Host = targetUri.Host;
requestMessage.Method = GetMethod(context.Request.Method);
return requestMessage;
}

private static void CopyRequestContentAndHeaders(HttpContext context, HttpRequestMessage requestMessage)
{
var requestMethod = context.Request.Method;
if (!HttpMethods.IsGet(requestMethod) &&
!HttpMethods.IsHead(requestMethod) &&
!HttpMethods.IsDelete(requestMethod) &&
!HttpMethods.IsTrace(requestMethod))
{
var streamContent = new StreamContent(context.Request.Body);
requestMessage.Content = streamContent;
}

foreach (var header in context.Request.Headers)
{
if (!NotForwardedHttpHeaders.Contains(header.Key))////Http头文件的这两个属性(connection,Host)这两个状态属性是什么意思,如果头文件中没有这两个属性,代表什么意思呢?
{
if (header.Key != "User-Agent")//////这句判断又什么意思呢?
{
if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()) && requestMessage.Content != null)
{
requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
}
}
else
{
string userAgent = header.Value.Count > 0 ? (header.Value[0] + " " + context.TraceIdentifier) : string.Empty;

if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, userAgent) && requestMessage.Content != null)
{
requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, userAgent);////主体文件属性里又都多了个头属性,这个头属性又啥意思,请结合代码帮解释下。
}
}

}
}
}

private static HttpMethod GetMethod(string method)
{
if (HttpMethods.IsDelete(method)) return HttpMethod.Delete;
if (HttpMethods.IsGet(method)) return HttpMethod.Get;
if (HttpMethods.IsHead(method)) return HttpMethod.Head;
if (HttpMethods.IsOptions(method)) return HttpMethod.Options;
if (HttpMethods.IsPost(method)) return HttpMethod.Post;
if (HttpMethods.IsPut(method)) return HttpMethod.Put;
if (HttpMethods.IsTrace(method)) return HttpMethod.Trace;
return new HttpMethod(method);
}
...全文
450 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Hello World, 2021-04-10
  • 打赏
  • 举报
回复
继承可以把共用的部分写在父类里,子类只要实现特殊的一些功能就好了。 System.Net.Http.Headers.HttpHeaders派生了以下三个类: System.Net.Http.Headers.HttpContentHeaders System.Net.Http.Headers.HttpRequestHeaders System.Net.Http.Headers.HttpResponseHeaders 多数特征是一样的,但有些特殊的就在子类实现了
一品梅 2021-04-10
  • 打赏
  • 举报
回复
感谢解答。 另,十分感谢好友群群友的热心回答。 HttpHeaders是抽象类,表示[b]HTTP HEADERS 你注意我为什么用大写 大写是HTTP规范的定义,表示的是“它实际上的东西” 下面是抽象类及其派生类 HttpHeaders抽象类恰恰没有定义属性。下面的派生类分别根据其职责定义其对应的属性。 HttpRequestHeaders类的属性,表示客户端请求的HEADER; HttpResponseHeaders类的属性,表示服务器发送过来的HEADER; HttpContentHeaders类的属性,表示作用于CONTENT的HEADER; 这里,到了HttpContentHeaders,就实现了内容类型,内容长度等字段,对应你了解的HTTP HEADER,就是Content-Length、Content-Length等HEADER 面向对象的设计中最重要的思想之一就是语义。
一品梅 2021-04-09
  • 打赏
  • 举报
回复
一品梅 2021-04-09
  • 打赏
  • 举报
回复
发现了,后者继承前者的。是在HttpRequestMessage.Content这个返回的是HttpContent,它有个Headers属性,返回HttpContentHeaders 类,这个类继承System.Net.Http.Headers.HttpHeaders。微软这样设计的目的是什么,这不是多此一举吗?前者没法添加,在后者里添加。 我们通用的Header头不都是直接获取HttpHeaders吗?什么时候要用到后者呢?
一品梅 2021-04-08
  • 打赏
  • 举报
回复
看了你给推荐的文章,非常感谢。 if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, userAgent) && requestMessage.Content != null) { requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, userAgent); ////主体文件属性里又都多了个头属性,这个头属性又啥意思,请结合代码帮解释下。 //如果TryAddWithoutValidation返回false或者requestMessage.Content != null就再执行TryAddWithoutValidation,没有多一个头属性 } 这两个还没搞懂
Hello World, 2021-04-08
  • 打赏
  • 举报
回复
Request.Headers的属性可以参考这篇文章:https://blog.csdn.net/qq_41807489/article/details/104372202 如果标准的请求头是NotForwardedHttpHeaders中的则进行处理 if (header.Key != "User-Agent")就是判断这个头信息不是关于浏览器的 [code=c#] //获取用户代理中的第一个属性,用于判断浏览器类型 string userAgent = header.Value.Count > 0 ? (header.Value[0] + " " + context.TraceIdentifier) : string.Empty; if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, userAgent) && requestMessage.Content != null) { requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, userAgent); ////主体文件属性里又都多了个头属性,这个头属性又啥意思,请结合代码帮解释下。 //如果TryAddWithoutValidation返回false或者requestMessage.Content != null就再执行TryAddWithoutValidation,没有多一个头属性 } [/code]
一品梅 2021-04-08
  • 打赏
  • 举报
回复
private static readonly string[] NotForwardedHttpHeaders = new[] { "Connection", "Host" };////Http头文件的这两个属性在下面代码中用到,这两个状态属性是什么意思,如果头文件中没有这两个属性,代表什么意思呢?

62,241

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧