//梳理下asp.net 对请求的处理流程:
[Guid("08a2c56f-7c16-41c1-a8be-432917a1a2d1"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
public interface IISAPIRuntime
{
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true), SecurityPermission(SecurityAction.InheritanceDemand, Unrestricted = true)]
void StartProcessing();
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true), SecurityPermission(SecurityAction.InheritanceDemand, Unrestricted = true)]
void StopProcessing();
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true), SecurityPermission(SecurityAction.InheritanceDemand, Unrestricted = true)]
[return: MarshalAs(UnmanagedType.I4)]
int ProcessRequest([In] IntPtr ecb, [MarshalAs(UnmanagedType.I4)] [In] int useProcessModel);
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true), SecurityPermission(SecurityAction.InheritanceDemand, Unrestricted = true)]
void DoGCCollect();
}
[Guid("15eb8d20-d4ed-4855-a276-91a75a696955"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
internal interface IISAPIRuntime2
{
void StartProcessing();
void StopProcessing();
[return: MarshalAs(UnmanagedType.I4)]
int ProcessRequest([In] IntPtr ecb, [MarshalAs(UnmanagedType.I4)] [In] int useProcessModel);
void DoGCCollect();
}
public sealed class ISAPIRuntime : MarshalByRefObject, IISAPIRuntime, IISAPIRuntime2, IRegisteredObject{
//ISAPIRuntime.ProcessRequest 这是iis调用.net的入口 这实现了一个com接口
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
public int ProcessRequest(IntPtr ecb, int iWRType)
{
IntPtr intPtr = IntPtr.Zero;
if (iWRType == 2)
{
intPtr = ecb;
ecb = UnsafeNativeMethods.GetEcb(intPtr);
}
ISAPIWorkerRequest iSAPIWorkerRequest = null;
int result;
try
{
bool useOOP = iWRType == 1;
//根据IIS穿过来的非托管参数 创建WorkRequest对象
iSAPIWorkerRequest = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP);
iSAPIWorkerRequest.Initialize();
string appPathTranslated = iSAPIWorkerRequest.GetAppPathTranslated();
string appDomainAppPathInternal = HttpRuntime.AppDomainAppPathInternal;
if (appDomainAppPathInternal == null || StringUtil.EqualsIgnoreCase(appPathTranslated, appDomainAppPathInternal))
{
//调用HttpRuntime.ProcessRequest 来处理请求
HttpRuntime.ProcessRequestNoDemand(iSAPIWorkerRequest);
result = 0;
}
else
{
HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged, SR.GetString("Hosting_Phys_Path_Changed", new object[]
{
appDomainAppPathInternal,
appPathTranslated
}));
result = 1;
}
}
catch (Exception ex)
{
try
{
WebBaseEvent.RaiseRuntimeError(ex, this);
}
catch
{
}
if (iSAPIWorkerRequest == null || !(iSAPIWorkerRequest.Ecb == IntPtr.Zero))
{
throw;
}
if (intPtr != IntPtr.Zero)
{
UnsafeNativeMethods.SetDoneWithSessionCalled(intPtr);
}
if (ex is ThreadAbortException)
{
Thread.ResetAbort();
}
result = 0;
}
return result;
}
}
/*HttpWorkerRequest有:
abstract class ISAPIWorkerRequest,
class ISAPIWorkerRequestInProc:ISAPIWorkerRequest,
class ISAPIWorkerRequestInProcForIIS6:ISAPIWorkerRequestInProc,
class ISAPIWorkerRequestInProcForIIS7:ISAPIWorkerRequestInProcForIIS6,
class ISAPIWorkerRequestOutOfProc:ISAPIWorkerRequest 几种实现 ,
封装了大部分.net 托管代码和iis本地代码数据交互的操作 (包括客户端数据的读写,连接状态的判断,客户端IP的获取等操作)
*/
/*HttpRuntime.ProcessRequestNoDemand 这个里面判断了 是否有请求队列
如果就将当前请求放入队列 从队列中取出合适的请求
*/
internal static void ProcessRequestNoDemand(HttpWorkerRequest wr)
{
RequestQueue requestQueue = HttpRuntime._theRuntime._requestQueue;
wr.UpdateInitialCounters();
if (requestQueue != null)
{
wr = requestQueue.GetRequestToExecute(wr);
}
if (wr != null)
{
HttpRuntime.CalculateWaitTimeAndUpdatePerfCounter(wr);
//记录最新的请求开始时间到HttpWorkerRequest._startTime
wr.ResetStartTime();
//开始处理请求对象 ProcessRequestNow 只是简单的封装了
//HttpRuntime.ProcessRequestInternal(wr) 实例方法
HttpRuntime.ProcessRequestNow(wr);
}
}
//RequestQueue.GetRequestToExecute
internal HttpWorkerRequest GetRequestToExecute(HttpWorkerRequest wr)
{
int num;
int num2;
//从当前线程池里取出可用线程数量
ThreadPool.GetAvailableThreads(out num, out num2);
int num3;
if (this._iis6)
{
num3 = num; //iis6及以下 忽略异步线程数
}
else
{
num3 = ((num2 > num) ? num : num2);//
}
//队列中无待处理请求 直接返回
if (num3 >= this._minExternFreeThreads && this._count == 0)
{
return wr;
}
bool flag = RequestQueue.IsLocal(wr);
if (flag && num3 >= this._minLocalFreeThreads && this._count == 0)
{
return wr;
}
//队列中待处理请求数量超限 拒绝当前请求
if (this._count >= this._queueLimit)
{
HttpRuntime.RejectRequestNow(wr, false);
return null;
}
//当前请求入队
this.QueueRequest(wr, flag);
//从队列中取出一个待处理请求
if (num3 >= this._minExternFreeThreads)
{
wr = this.DequeueRequest(false);
}
else if (num3 >= this._minLocalFreeThreads)
{
wr = this.DequeueRequest(true);
}
else
{
//尝试增加更多的处理线程
wr = null;
this.ScheduleMoreWorkIfNeeded();
}
return wr;
}
//HttpRuntime.ProcessRequestInternal
private void ProcessRequestInternal(HttpWorkerRequest wr)
{
Interlocked.Increment(ref this._activeRequestCount);
//当前HttpRuntime 对象已经销毁 返回错误
if (this._disposingHttpRuntime)
{
try
{
wr.SendStatus(503, "Server Too Busy");
wr.SendKnownResponseHeader(12, "text/html; charset=utf-8");
byte[] bytes = Encoding.ASCII.GetBytes("<html><body>Server Too Busy</body></html>");
byte[] expr_45 = bytes;
wr.SendResponseFromMemory(expr_45, expr_45.Length);
wr.FlushResponse(true);
wr.EndOfRequest();
}
finally
{
Interlocked.Decrement(ref this._activeRequestCount);
}
return;
}
HttpContext httpContext;
try
{
//生成 HttpContext 对象
httpContext = new HttpContext(wr, false);
}
catch
{
try
{
wr.SendStatus(400, "Bad Request");
wr.SendKnownResponseHeader(12, "text/html; charset=utf-8");
byte[] bytes2 = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>");
byte[] expr_A5 = bytes2;
wr.SendResponseFromMemory(expr_A5, expr_A5.Length);
wr.FlushResponse(true);
wr.EndOfRequest();
return;
}
finally
{
Interlocked.Decrement(ref this._activeRequestCount);
}
}
wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, httpContext);
HostingEnvironment.IncrementBusyCount();
try
{
try
{
//如果是第一次请求 根据系统配置做一些初始化工作
//最终调用HttpRuntime.FirstRequestInit
this.EnsureFirstRequestInit(httpContext);
}
catch
{
if (!httpContext.Request.IsDebuggingRequest)
{
throw;
}
}
//简单的封装响应写入流
httpContext.Response.InitResponseWriter();
//关键点-获取请求处理Handler 其中包括application初始化 httpModule执行
IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(httpContext);
if (applicationInstance == null)
{
throw new HttpException(SR.GetString("Unable_create_app_object"));
}
if (EtwTrace.IsTraceEnabled(5, 1))
{
EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, httpContext.WorkerRequest, applicationInstance.GetType().FullName, "Start");
}
//判断是否异步Handler
if (applicationInstance is IHttpAsyncHandler)
{
//调用异步处理流程 HttpApplication.BeginProcessRequest
IHttpAsyncHandler httpAsyncHandler = (IHttpAsyncHandler)applicationInstance;
httpContext.AsyncAppHandler = httpAsyncHandler;
httpAsyncHandler.BeginProcessRequest(httpContext, this._handlerCompletionCallback, httpContext);
}
else
{
//直接处理 HttpApplication.ProcessRequest
applicationInstance.ProcessRequest(httpContext);
//请求处理结束,做些收尾工作
this.FinishRequest(httpContext.WorkerRequest, httpContext, null);
}
}
catch (Exception e)
{
httpContext.Response.InitResponseWriter();
this.FinishRequest(wr, httpContext, e);
}
}
//HttpRuntime.FirstRequestInit 设置一些应用程序的基本配置
private void FirstRequestInit(HttpContext context)
{
Exception ex = null;
if (HttpRuntime.InitializationException == null && this._appDomainId != null)
{
try
{
using (new ApplicationImpersonationContext())
{
CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture;
try
{
//初始化HTTP配置
HttpRuntime.InitHttpConfiguration();
HttpRuntime.CheckApplicationEnabled();
this.CheckAccessToTempDirectory();
this.InitializeHealthMonitoring();
//初始化请求队列
this.InitRequestQueue();
this.InitTrace(context);
HealthMonitoringManager.StartHealthMonitoringHeartbeat();
HttpRuntime.RestrictIISFolders(context);
this.PreloadAssembliesFromBin();
this.InitHeaderEncoding();
HttpEncoder.InitializeOnFirstRequest();
RequestValidator.InitializeOnFirstRequest();
if (context.WorkerRequest is ISAPIWorkerRequestOutOfProc)
{
ProcessModelSection arg_8E_0 = RuntimeConfig.GetMachineConfig().ProcessModel;
}
}
finally
{
Thread.CurrentThread.CurrentUICulture = currentUICulture;
HttpRuntime.SetCurrentThreadCultureWithAssert(currentCulture);
}
}
}
catch (ConfigurationException ex)
{
}
catch (Exception ex2)
{
ex = new HttpException(SR.GetString("XSP_init_error", new object[]
{
ex2.Message
}), ex2);
}
finally
{
}
}
if (HttpRuntime.InitializationException != null)
{
throw new HttpException(HttpRuntime.InitializationException.Message, HttpRuntime.InitializationException);
}
if (ex != null)
{
HttpRuntime.InitializationException = ex;
throw ex;
}
HttpRuntime.AddAppDomainTraceMessage("FirstRequestInit");
}
//HttpApplicationFactory.GetApplicationInstance
internal static IHttpHandler GetApplicationInstance(HttpContext context)
{
if (HttpApplicationFactory._customApplication != null)
{
return HttpApplicationFactory._customApplication;
}
if (context.Request.IsDebuggingRequest)
{
return new HttpDebugHandler();
}
//这里面关联了global.asax 并解析了Application_OnStart
// Application_Start Application_OnEnd Application_End Session_OnEnd Session_End 等一些(object,EventArgs)方法
HttpApplicationFactory._theApplicationFactory.EnsureInited();
//调用Application_Start方法
HttpApplicationFactory._theApplicationFactory.EnsureAppStartCalled(context);
//获取HttpApplication
return HttpApplicationFactory._theApplicationFactory.GetNormalApplicationInstance(context);
}
//HttpApplicationFactory.GetNormalApplicationInstance
private HttpApplication GetNormalApplicationInstance(HttpContext context)
{
//从池中获取可用 HttpApplication 如果没有再创建,用完后会入池的
HttpApplication httpApplication = null;
Stack freeList = this._freeList;
lock (freeList)
{
if (this._numFreeAppInstances > 0)
{
httpApplication = (HttpApplication)this._freeList.Pop();
this._numFreeAppInstances--;
if (this._numFreeAppInstances < this._minFreeAppInstances)
{
this._minFreeAppInstances = this._numFreeAppInstances;
}
}
}
if (httpApplication == null)
{
httpApplication = (HttpApplication)HttpRuntime.CreateNonPublicInstance(this._theApplicationType);
using (new ApplicationImpersonationContext())
{
//初始化 HttpApplication 主要完成的工作时HttpModule的初始化和处理请求过程中每个步骤触发事件处理程序的准备
//在 HttpModule.Init可以注册HttpApplication 各个阶段的事件
httpApplication.InitInternal(context, this._state, this._eventHandlerMethods);
}
}
if (AppSettings.UseTaskFriendlySynchronizationContext)
{
httpApplication.ApplicationInstanceConsumersCounter = new CountdownTask(1);
Task arg_DD_0 = httpApplication.ApplicationInstanceConsumersCounter.Task;
Action<Task, object> arg_DD_1;
if ((arg_DD_1 = HttpApplicationFactory.<>c.<>9__37_0) == null)
{
arg_DD_1 = (HttpApplicationFactory.<>c.<>9__37_0 = new Action<Task, object>(HttpApplicationFactory.<>c.<>9.<GetNormalApplicationInstance>b__37_0));
}
arg_DD_0.ContinueWith(arg_DD_1, httpApplication, TaskContinuationOptions.ExecuteSynchronously);
}
return httpApplication;
}
// HttpApplication.InitInternal
internal void InitInternal(HttpContext context, HttpApplicationState state, MethodInfo[] handlers)
{
this._state = state;
PerfCounters.IncrementCounter(AppPerfCounter.PIPELINES);
try
{
try
{
this._initContext = context;
this._initContext.ApplicationInstance = this;
context.ConfigurationPath = context.Request.ApplicationPathObject;
using (new DisposableHttpContextWrapper(context))
{
if (HttpRuntime.UseIntegratedPipeline) //判断iis管道模式
{
try
{
context.HideRequestResponse = true;
this._hideRequestResponse = true;
//初始化HttpModule HttpApplication.InitModulesCommon
this.InitIntegratedModules();
goto IL_6B;
}
finally
{
context.HideRequestResponse = false;
this._hideRequestResponse = false;
}
}
//初始化HttpModule 最终调用了 HttpApplication.InitModulesCommon
this.InitModules();
IL_6B:
if (handlers != null)
{
this.HookupEventHandlersForApplicationAndModules(handlers);
}
this._context = context;
if (HttpRuntime.UseIntegratedPipeline && this._context != null)
{
this._context.HideRequestResponse = true;
}
this._hideRequestResponse = true;
try
{
this.Init();
}
catch (Exception error)
{
this.RecordError(error);
}
}
if (HttpRuntime.UseIntegratedPipeline && this._context != null)
{
this._context.HideRequestResponse = false;
}
this._hideRequestResponse = false;
this._context = null;
this._resumeStepsWaitCallback = new WaitCallback(this.ResumeStepsWaitCallback);
if (HttpRuntime.UseIntegratedPipeline)
{
this._stepManager = new HttpApplication.PipelineStepManager(this);
}
else
{
this._stepManager = new HttpApplication.ApplicationStepManager(this);
}
this._stepManager.BuildSteps(this._resumeStepsWaitCallback);
}
finally
{
this._initInternalCompleted = true;
context.ConfigurationPath = null;
this._initContext.ApplicationInstance = null;
this._initContext = null;
}
}
catch
{
throw;
}
}
//HttpApplication.InitModulesCommon
private void InitModulesCommon()
{
int count = this._moduleCollection.Count;
for (int i = 0; i < count; i++)
{
this._currentModuleCollectionKey = this._moduleCollection.GetKey(i);
this._moduleCollection[i].Init(this); //调用各注册Module的IHttpModule.Init方法初始化
}
this._currentModuleCollectionKey = null;
this.InitAppLevelCulture();
}