NetCore解读请求处理管道
时间:2021-10-09
本文章向大家介绍NetCore解读请求处理管道,主要包括NetCore解读请求处理管道使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一、请求处理管道
前面分别介绍了服务器、中间件管道、托管服务和主机,那么请求管道具体是怎样的,它们之间有什么关系?正常来说,ASP.NET Core的请求处理管道由一个服务器和中间件管道构成。但对于面向传输层的服务器来说,它其实没有中间件的概念。不管服务器类型,当服务器接收到请求之后,会将该请求分发给一个处理器进行处理,对服务器而言,这个处理器就是一个HTTP应用,此应用通过IHttpApplication<TContext>接口来表示,如下是IHttpApplication<TContext> 的定义:
/// <summary> /// Represents an application. /// </summary> /// <typeparam name="TContext">The context associated with the application.</typeparam> public interface IHttpApplication<TContext> where TContext : notnull { /// <summary> /// Create a TContext given a collection of HTTP features. /// </summary> /// <param name="contextFeatures">A collection of HTTP features to be used for creating the TContext.</param> /// <returns>The created TContext.</returns> TContext CreateContext(IFeatureCollection contextFeatures); /// <summary> /// Asynchronously processes an TContext. /// </summary> /// <param name="context">The TContext that the operation will process.</param> Task ProcessRequestAsync(TContext context); /// <summary> /// Dispose a given TContext. /// </summary> /// <param name="context">The TContext to be disposed.</param> /// <param name="exception">The Exception thrown when processing did not complete successfully, otherwise null.</param> void DisposeContext(TContext context, Exception? exception); }
由于服务器是通过IServer接口表示的,所以可以将ASP.NET Core框架的核心视为由IServer和IHttpApplication<TContext>对象组成的管道,即请求处理管道。
我们可以根据需要注册不同类型的服务器,在默认情况下,IHttpApplication由HostingApplication实现,如下面源码所示:
internal class HostingApplication : IHttpApplication<HostingApplication.Context>
HostingApplication对象由指定的RequestDelegate对象来完成所有的请求处理工作,如下面源码所示:
internal class HostingApplication : IHttpApplication<HostingApplication.Context> { private readonly RequestDelegate _application; private readonly IHttpContextFactory? _httpContextFactory; private readonly DefaultHttpContextFactory? _defaultHttpContextFactory; private readonly HostingApplicationDiagnostics _diagnostics; public HostingApplication( RequestDelegate application, ILogger logger, DiagnosticListener diagnosticSource, ActivitySource activitySource, DistributedContextPropagator propagator, IHttpContextFactory httpContextFactory) { _application = application; _diagnostics = new HostingApplicationDiagnostics(logger, diagnosticSource, activitySource, propagator); if (httpContextFactory is DefaultHttpContextFactory factory) { _defaultHttpContextFactory = factory; } else { _httpContextFactory = httpContextFactory; } }
..........// Execute the request public Task ProcessRequestAsync(Context context) { return _application(context.HttpContext!); }
............
}
而RequestDelegate就是中间件委托链,所有的这一切都被GenericWebHostService整合在一起。如下是GenericWebHostService类的StartAsync方法:
public async Task StartAsync(CancellationToken cancellationToken) { HostingEventSource.Log.HostStart(); var serverAddressesFeature = Server.Features.Get<IServerAddressesFeature>(); var addresses = serverAddressesFeature?.Addresses; if (addresses != null && !addresses.IsReadOnly && addresses.Count == 0) { var urls = Configuration[WebHostDefaults.ServerUrlsKey]; if (!string.IsNullOrEmpty(urls)) { serverAddressesFeature!.PreferHostingUrls = WebHostUtilities.ParseBool(Configuration, WebHostDefaults.PreferHostingUrlsKey); foreach (var value in urls.Split(';', StringSplitOptions.RemoveEmptyEntries)) { addresses.Add(value); } } } //中间件委托链 RequestDelegate? application = null; try { var configure = Options.ConfigureApplication; if (configure == null) { throw new InvalidOperationException($"No application configured. Please specify an application via IWebHostBuilder.UseStartup, IWebHostBuilder.Configure, or specifying the startup assembly via {nameof(WebHostDefaults.StartupAssemblyKey)} in the web host configuration."); } var builder = ApplicationBuilderFactory.CreateBuilder(Server.Features); foreach (var filter in StartupFilters.Reverse()) { configure = filter.Configure(configure); } configure(builder); // Build the request pipeline application = builder.Build(); } catch (Exception ex) { Logger.ApplicationError(ex); if (!Options.WebHostOptions.CaptureStartupErrors) { throw; } var showDetailedErrors = HostingEnvironment.IsDevelopment() || Options.WebHostOptions.DetailedErrors; application = ErrorPageBuilder.BuildErrorPageApplication(HostingEnvironment.ContentRootFileProvider, Logger, showDetailedErrors, ex); } //创建HostingApplication对象,关联中间件委托链 var httpApplication = new HostingApplication(application, Logger, DiagnosticListener, ActivitySource, Propagator, HttpContextFactory); await Server.StartAsync(httpApplication, cancellationToken); if (addresses != null) { foreach (var address in addresses) { Log.ListeningOnAddress(LifetimeLogger, address); } } if (Logger.IsEnabled(LogLevel.Debug)) { foreach (var assembly in Options.WebHostOptions.GetFinalHostingStartupAssemblies()) { Log.StartupAssemblyLoaded(Logger, assembly); } } if (Options.HostingStartupExceptions != null) { foreach (var exception in Options.HostingStartupExceptions.InnerExceptions) { Logger.HostingStartupAssemblyError(exception); } } }
二、请求管道简略图
三、请求管道流程图
原文地址:https://www.cnblogs.com/qtiger/p/15386971.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Nmap NSE 缺陷
- Golang服务器热重启、热升级、热更新(safe and graceful hot-restart/reload http server)详解
- Nmap NSE 库分析 >>> shortport
- Linux 后门系列之 python3 反弹shell & 隐藏后门
- nc 反弹shell | Linux 后门系列
- dash & rbash & nc.openbsd | Linux 后门系列
- 通达OA getshell | Nmap 脚本
- Golang的优雅重启
- 通达OA文件包含全版本 getshell | Nmap 脚本
- NSE代码生成器 | Nmap 脚本
- shell 加密传输 | Linux后门系列
- msf反弹一把梭 | Linux后门系列
- IDEA 远程调试
- 不落地反弹meterpreter | Linux后门系列
- rsyslog的安装、使用、详解