您的位置:首页 > 编程语言 > ASP

Asp.net请求处理之管道处理介绍

2012-11-07 00:00 531 查看
在了解Asp.net请求处理流程的过程中,个人认为有必要从源代码的角度来了解asp.net管道是怎么实现的。

在此之前大家有必要了解一些asp.net请求流程的基本东东,如ASP.NET 请求处理流程、Asp.net管道、ASP.NET管线与应用程序生命周期

我们大家都知道HttpRuntime主要的方法是

public static void ProcessRequest(HttpWorkerRequest wr)
private void ProcessRequestInternal(HttpWorkerRequest wr) 
{ 
HttpContext context; 
try 
{ 
context = new HttpContext(wr, false); 
} 
catch 
{ 
wr.SendStatus(400, "Bad Request"); 
wr.SendKnownResponseHeader(12, "text/html; charset=utf-8"); 
byte[] bytes = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>"); 
wr.SendResponseFromMemory(bytes, bytes.Length); 
wr.FlushResponse(true); 
wr.EndOfRequest(); 
return; 
} 
wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, context); 
Interlocked.Increment(ref this._activeRequestCount); 
HostingEnvironment.IncrementBusyCount(); 
try 
{ 
try 
{ 
this.EnsureFirstRequestInit(context); 
} 
catch 
{ 
if (!context.Request.IsDebuggingRequest) 
{ 
throw; 
} 
} 
context.Response.InitResponseWriter(); 
IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context); 
if (applicationInstance == null) 
{ 
throw new HttpException(SR.GetString("Unable_create_app_object")); 
} 
if (EtwTrace.IsTraceEnabled(5, 1)) 
{ 
EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, applicationInstance.GetType().FullName, "Start"); 
} 
if (applicationInstance is IHttpAsyncHandler) 
{ 
IHttpAsyncHandler handler2 = (IHttpAsyncHandler) applicationInstance; 
context.AsyncAppHandler = handler2; 
handler2.BeginProcessRequest(context, this._handlerCompletionCallback, context); 
} 
else 
{ 
applicationInstance.ProcessRequest(context); 
this.FinishRequest(context.WorkerRequest, context, null); 
} 
} 
catch (Exception exception) 
{ 
context.Response.InitResponseWriter(); 
this.FinishRequest(wr, context, exception); 
} 
}

我们看到里面有这么一句

IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);用来获取HttpApplication,而HttpApplication实现了IHttpAsyncHandler接口public class HttpApplication : IHttpAsyncHandler, IHttpHandler, IComponent, IDisposable,最后调用application的BeginProcessRequest方法。
HttpApplicationFactory.GetApplicationInstance(context)主要是调用GetNormalApplicationInstance
internal static IHttpHandler GetApplicationInstance(HttpContext context) 
{ 
if (_customApplication != null) 
{ 
return _customApplication; 
} 
if (context.Request.IsDebuggingRequest) 
{ 
return new HttpDebugHandler(); 
} 
_theApplicationFactory.EnsureInited(); 
_theApplicationFactory.EnsureAppStartCalled(context); 
return _theApplicationFactory.GetNormalApplicationInstance(context); 
}

private HttpApplication GetNormalApplicationInstance(HttpContext context) 
{ 
HttpApplication application = null; 
lock (this._freeList) 
{ 
if (this._numFreeAppInstances > 0) 
{ 
application = (HttpApplication) this._freeList.Pop(); 
this._numFreeAppInstances--; 
if (this._numFreeAppInstances < this._minFreeAppInstances) 
{ 
this._minFreeAppInstances = this._numFreeAppInstances; 
} 
} 
} 
if (application == null) 
{ 
application = (HttpApplication) HttpRuntime.CreateNonPublicInstance(this._theApplicationType); 
using (new ApplicationImpersonationContext()) 
{ 
application.InitInternal(context, this._state, this._eventHandlerMethods); 
} 
} 
return application; 
}

在GetNormalApplicationInstance里面有一个比较关键的方法application.InitInternal(context, this._state, this._eventHandlerMethods);我们猜测它是做Application初始化的工作,包括http管道的初始化。
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) 
{ 
try 
{ 
context.HideRequestResponse = true; 
this._hideRequestResponse = true; 
this.InitIntegratedModules(); 
goto Label_006B; 
} 
finally 
{ 
context.HideRequestResponse = false; 
this._hideRequestResponse = false; 
} 
} 
this.InitModules(); 
Label_006B: 
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 exception) 
{ 
this.RecordError(exception); 
} 
} 
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 PipelineStepManager(this); 
} 
else 
{ 
this._stepManager = new ApplicationStepManager(this); 
} 
this._stepManager.BuildSteps(this._resumeStepsWaitCallback); 
} 
finally 
{ 
this._initInternalCompleted = true; 
context.ConfigurationPath = null; 
this._initContext.ApplicationInstance = null; 
this._initContext = null; 
} 
} 
catch 
{ 
throw; 
} 
}

这个方法关键的代码在于:

if (HttpRuntime.UseIntegratedPipeline) 
{ 
this._stepManager = new PipelineStepManager(this); 
} 
else 
{ 
this._stepManager = new ApplicationStepManager(this); 
} 
this._stepManager.BuildSteps(this._resumeStepsWaitCallback);

我想大家看到这里就会明白为什么IIS7会有集成模式和经典模式了吧。可能大家不怎么重视此代码,让我们来看看经典模式的ApplicationStepManager

internal class ApplicationStepManager : HttpApplication.StepManager 
{ 
// Fields 
private int _currentStepIndex; 
private int _endRequestStepIndex; 
private HttpApplication.IExecutionStep[] _execSteps; 
private int _numStepCalls; 
private int _numSyncStepCalls; 
private WaitCallback _resumeStepsWaitCallback; 

// Methods 
internal ApplicationStepManager(HttpApplication app) : base(app) 
{ 
} 

internal override void BuildSteps(WaitCallback stepCallback) 
{ 
ArrayList steps = new ArrayList(); 
HttpApplication app = base._application; 
bool flag = false; 
UrlMappingsSection urlMappings = RuntimeConfig.GetConfig().UrlMappings; 
flag = urlMappings.IsEnabled && (urlMappings.UrlMappings.Count > 0); 
steps.Add(new HttpApplication.ValidateRequestExecutionStep(app)); 
steps.Add(new HttpApplication.ValidatePathExecutionStep(app)); 
if (flag) 
{ 
steps.Add(new HttpApplication.UrlMappingsExecutionStep(app)); 
} 
app.CreateEventExecutionSteps(HttpApplication.EventBeginRequest, steps); 
app.CreateEventExecutionSteps(HttpApplication.EventAuthenticateRequest, steps); 
app.CreateEventExecutionSteps(HttpApplication.EventDefaultAuthentication, steps); 
app.CreateEventExecutionSteps(HttpApplication.EventPostAuthenticateRequest, steps); 
app.CreateEventExecutionSteps(HttpApplication.EventAuthorizeRequest, steps); 
app.CreateEventExecutionSteps(HttpApplication.EventPostAuthorizeRequest, steps); 
app.CreateEventExecutionSteps(HttpApplication.EventResolveRequestCache, steps); 
app.CreateEventExecutionSteps(HttpApplication.EventPostResolveRequestCache, steps); 
steps.Add(new HttpApplication.MapHandlerExecutionStep(app)); 
app.CreateEventExecutionSteps(HttpApplication.EventPostMapRequestHandler, steps); 
app.CreateEventExecutionSteps(HttpApplication.EventAcquireRequestState, steps); 
app.CreateEventExecutionSteps(HttpApplication.EventPostAcquireRequestState, steps); 
app.CreateEventExecutionSteps(HttpApplication.EventPreRequestHandlerExecute, steps); 
steps.Add(new HttpApplication.CallHandlerExecutionStep(app)); 
app.CreateEventExecutionSteps(HttpApplication.EventPostRequestHandlerExecute, steps); 
app.CreateEventExecutionSteps(HttpApplication.EventReleaseRequestState, steps); 
app.CreateEventExecutionSteps(HttpApplication.EventPostReleaseRequestState, steps); 
steps.Add(new HttpApplication.CallFilterExecutionStep(app)); 
app.CreateEventExecutionSteps(HttpApplication.EventUpdateRequestCache, steps); 
app.CreateEventExecutionSteps(HttpApplication.EventPostUpdateRequestCache, steps); 
this._endRequestStepIndex = steps.Count; 
app.CreateEventExecutionSteps(HttpApplication.EventEndRequest, steps); 
steps.Add(new HttpApplication.NoopExecutionStep()); 
this._execSteps = new HttpApplication.IExecutionStep[steps.Count]; 
steps.CopyTo(this._execSteps); 
this._resumeStepsWaitCallback = stepCallback; 
} 

internal override void InitRequest() 
{ 
this._currentStepIndex = -1; 
this._numStepCalls = 0; 
this._numSyncStepCalls = 0; 
base._requestCompleted = false; 
} 

[DebuggerStepperBoundary] 
internal override void ResumeSteps(Exception error) 
{ 
bool flag = false; 
bool completedSynchronously = true; 
HttpApplication application = base._application; 
HttpContext context = application.Context; 
HttpApplication.ThreadContext context2 = null; 
AspNetSynchronizationContext syncContext = context.SyncContext; 
lock (base._application) 
{ 
try 
{ 
context2 = application.OnThreadEnter(); 
} 
catch (Exception exception) 
{ 
if (error == null) 
{ 
error = exception; 
} 
} 
try 
{ 
try 
{ 
Label_0045: 
if (syncContext.Error != null) 
{ 
error = syncContext.Error; 
syncContext.ClearError(); 
} 
if (error != null) 
{ 
application.RecordError(error); 
error = null; 
} 
if (syncContext.PendingOperationsCount > 0) 
{ 
syncContext.SetLastCompletionWorkItem(this._resumeStepsWaitCallback); 
} 
else 
{ 
if ((this._currentStepIndex < this._endRequestStepIndex) && ((context.Error != null) || base._requestCompleted)) 
{ 
context.Response.FilterOutput(); 
this._currentStepIndex = this._endRequestStepIndex; 
} 
else 
{ 
this._currentStepIndex++; 
} 
if (this._currentStepIndex >= this._execSteps.Length) 
{ 
flag = true; 
} 
else 
{ 
this._numStepCalls++; 
context.SyncContext.Enable(); 
error = application.ExecuteStep(this._execSteps[this._currentStepIndex], ref completedSynchronously); 
if (completedSynchronously) 
{ 
this._numSyncStepCalls++; 
goto Label_0045; 
} 
} 
} 
} 
finally 
{ 
if (context2 != null) 
{ 
try 
{ 
context2.Leave(); 
} 
catch 
{ 
} 
} 
} 
} 
catch 
{ 
throw; 
} 
} 
if (flag) 
{ 
context.Unroot(); 
application.AsyncResult.Complete(this._numStepCalls == this._numSyncStepCalls, null, null); 
application.ReleaseAppInstance(); 
} 
} 
}

说简单一点这个类中的internal override void BuildSteps(WaitCallback stepCallback)方法就是为我们注册那19个管道事件, internal override void ResumeSteps(Exception error)就是依次执行此管道事件,而 steps.Add(new HttpApplication.MapHandlerExecutionStep(app));是映射我们的handler
internal class MapHandlerExecutionStep : HttpApplication.IExecutionStep 
{ 
// Fields 
private HttpApplication _application; 

// Methods 
internal MapHandlerExecutionStep(HttpApplication app) 
{ 
this._application = app; 
} 

void HttpApplication.IExecutionStep.Execute() 
{ 
HttpContext context = this._application.Context; 
HttpRequest request = context.Request; 
if (EtwTrace.IsTraceEnabled(5, 1)) 
{ 
EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_ENTER, context.WorkerRequest); 
} 
context.Handler = this._application.MapHttpHandler(context, request.RequestType, request.FilePathObject, request.PhysicalPathInternal, false); 
if (EtwTrace.IsTraceEnabled(5, 1)) 
{ 
EtwTrace.Trace(EtwTraceType.ETW_TYPE_MAPHANDLER_LE***E, context.WorkerRequest); 
} 
} 

// Properties 
bool HttpApplication.IExecutionStep.CompletedSynchronously 
{ 
get 
{ 
return true; 
} 
} 

bool HttpApplication.IExecutionStep.IsCancellable 
{ 
get 
{ 
return false; 
} 
} 
}

里面的调用主要是

context.Handler = this._application.MapHttpHandler(context, request.RequestType, request.FilePathObject, request.PhysicalPathInternal, false);

而HttpApplication的MapHttpHandler如下:
internal IHttpHandler MapHttpHandler(HttpContext context, string requestType, VirtualPath path, string pathTranslated, bool useAppConfig) 
{ 
IHttpHandler handler = (context.ServerExecuteDepth == 0) ? context.RemapHandlerInstance : null; 
using (new ApplicationImpersonationContext()) 
{ 
if (handler != null) 
{ 
return handler; 
} 
HttpHandlerAction mapping = this.GetHandlerMapping(context, requestType, path, useAppConfig); 
if (mapping == null) 
{ 
PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_NOT_FOUND); 
PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_FAILED); 
throw new HttpException(SR.GetString("Http_handler_not_found_for_request_type", new object[] { requestType })); 
} 
IHttpHandlerFactory factory = this.GetFactory(mapping); 
try 
{ 
IHttpHandlerFactory2 factory2 = factory as IHttpHandlerFactory2; 
if (factory2 != null) 
{ 
handler = factory2.GetHandler(context, requestType, path, pathTranslated); 
} 
else 
{ 
handler = factory.GetHandler(context, requestType, path.VirtualPathString, pathTranslated); 
} 
} 
catch (FileNotFoundException exception) 
{ 
if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) 
{ 
throw new HttpException(0x194, null, exception); 
} 
throw new HttpException(0x194, null); 
} 
catch (DirectoryNotFoundException exception2) 
{ 
if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) 
{ 
throw new HttpException(0x194, null, exception2); 
} 
throw new HttpException(0x194, null); 
} 
catch (PathTooLongException exception3) 
{ 
if (HttpRuntime.HasPathDiscoveryPermission(pathTranslated)) 
{ 
throw new HttpException(0x19e, null, exception3); 
} 
throw new HttpException(0x19e, null); 
} 
if (this._handlerRecycleList == null) 
{ 
this._handlerRecycleList = new ArrayList(); 
} 
this._handlerRecycleList.Add(new HandlerWithFactory(handler, factory)); 
} 
return handler; 
}

在MapHttpHandler里创建了IHttpHandlerFactory,进而创建了httphandler。

在ApplicationStepManager中BuildSteps的方法有steps.Add(new HttpApplication.CallHandlerExecutionStep(app));这么一句,这就是注册调用我们hanndler的地方。
internal class CallHandlerExecutionStep : HttpApplication.IExecutionStep 
{ 
// Fields 
private HttpApplication _application; 
private AsyncCallback _completionCallback; 
private IHttpAsyncHandler _handler; 
private bool _sync; 

// Methods 
internal CallHandlerExecutionStep(HttpApplication app) 
{ 
this._application = app; 
this._completionCallback = new AsyncCallback(this.OnAsyncHandlerCompletion); 
} 

private void OnAsyncHandlerCompletion(IAsyncResult ar) 
{ 
if (!ar.CompletedSynchronously) 
{ 
HttpContext context = this._application.Context; 
Exception error = null; 
try 
{ 
try 
{ 
this._handler.EndProcessRequest(ar); 
} 
finally 
{ 
context.Response.GenerateResponseHeadersForHandler(); 
} 
} 
catch (Exception exception2) 
{ 
if ((exception2 is ThreadAbortException) || ((exception2.InnerException != null) && (exception2.InnerException is ThreadAbortException))) 
{ 
this._application.CompleteRequest(); 
} 
else 
{ 
error = exception2; 
} 
} 
if (EtwTrace.IsTraceEnabled(4, 4)) 
{ 
EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LE***E, context.WorkerRequest); 
} 
this._handler = null; 
context.SetStartTime(); 
if (HttpRuntime.IsLegacyCas) 
{ 
this.ResumeStepsWithAssert(error); 
} 
else 
{ 
this.ResumeSteps(error); 
} 
} 
} 

private void ResumeSteps(Exception error) 
{ 
this._application.ResumeStepsFromThreadPoolThread(error); 
} 

[PermissionSet(SecurityAction.Assert, Unrestricted=true)] 
private void ResumeStepsWithAssert(Exception error) 
{ 
this.ResumeSteps(error); 
} 

void HttpApplication.IExecutionStep.Execute() 
{ 
HttpContext context = this._application.Context; 
IHttpHandler handler = context.Handler; 
if (EtwTrace.IsTraceEnabled(4, 4)) 
{ 
EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_ENTER, context.WorkerRequest); 
} 
if ((handler != null) && HttpRuntime.UseIntegratedPipeline) 
{ 
IIS7WorkerRequest workerRequest = context.WorkerRequest as IIS7WorkerRequest; 
if ((workerRequest != null) && workerRequest.IsHandlerExecutionDenied()) 
{ 
this._sync = true; 
HttpException exception = new HttpException(0x193, SR.GetString("Handler_access_denied")); 
exception.SetFormatter(new PageForbiddenErrorFormatter(context.Request.Path, SR.GetString("Handler_access_denied"))); 
throw exception; 
} 
} 
if (handler == null) 
{ 
this._sync = true; 
} 
else if (handler is IHttpAsyncHandler) 
{ 
IHttpAsyncHandler handler2 = (IHttpAsyncHandler) handler; 
this._sync = false; 
this._handler = handler2; 
IAsyncResult result = handler2.BeginProcessRequest(context, this._completionCallback, null); 
if (result.CompletedSynchronously) 
{ 
this._sync = true; 
this._handler = null; 
try 
{ 
handler2.EndProcessRequest(result); 
} 
finally 
{ 
context.Response.GenerateResponseHeadersForHandler(); 
} 
if (EtwTrace.IsTraceEnabled(4, 4)) 
{ 
EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LE***E, context.WorkerRequest); 
} 
} 
} 
else 
{ 
this._sync = true; 
context.SyncContext.SetSyncCaller(); 
try 
{ 
handler.ProcessRequest(context); 
} 
finally 
{ 
context.SyncContext.ResetSyncCaller(); 
if (EtwTrace.IsTraceEnabled(4, 4)) 
{ 
EtwTrace.Trace(EtwTraceType.ETW_TYPE_HTTPHANDLER_LE***E, context.WorkerRequest); 
} 
context.Response.GenerateResponseHeadersForHandler(); 
} 
} 
} 

// Properties 
bool HttpApplication.IExecutionStep.CompletedSynchronously 
{ 
get 
{ 
return this._sync; 
} 
} 

bool HttpApplication.IExecutionStep.IsCancellable 
{ 
get 
{ 
return !(this._application.Context.Handler is IHttpAsyncHandler); 
} 
} 
}

在代码中我们看到handler2.BeginProcessRequest(context, this._completionCallback, null);。。。handler.ProcessRequest(context);这2句代码是不是很熟悉啊。

在让我们回头看看HttpApplication的BeginProcessRequest方法
IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) 
{ 
this._context = context; 
this._context.ApplicationInstance = this; 
this._stepManager.InitRequest(); 
this._context.Root(); 
HttpAsyncResult result = new HttpAsyncResult(cb, extraData); 
this.AsyncResult = result; 
if (this._context.TraceIsEnabled) 
{ 
HttpRuntime.Profile.StartRequest(this._context); 
} 
this.ResumeSteps(null); 
return result; 
}

里面调用了ResumeSteps方法
private void ResumeSteps(Exception error) 
{ 
this._stepManager.ResumeSteps(error); 
}

回到我们先前的ApplicationStepManager的ResumeSteps方法,里面有一句

error = application.ExecuteStep(this._execSteps[this._currentStepIndex], ref completedSynchronously);

Ahhpaplication的ExecuteStep方法
internal Exception ExecuteStep(IExecutionStep step, ref bool completedSynchronously) 
{ 
Exception exception = null; 
try 
{ 
try 
{ 
if (step.IsCancellable) 
{ 
this._context.BeginCancellablePeriod(); 
try 
{ 
step.Execute(); 
} 
finally 
{ 
this._context.EndCancellablePeriod(); 
} 
this._context.WaitForExceptionIfCancelled(); 
} 
else 
{ 
step.Execute(); 
} 
if (!step.CompletedSynchronously) 
{ 
completedSynchronously = false; 
return null; 
} 
} 
catch (Exception exception2) 
{ 
exception = exception2; 
if (ImpersonationContext.CurrentThreadTokenExists) 
{ 
exception2.Data["ASPIMPERSONATING"] = string.Empty; 
} 
if ((exception2 is ThreadAbortException) && ((Thread.CurrentThread.ThreadState & ThreadState.AbortRequested) == ThreadState.Running)) 
{ 
exception = null; 
this._stepManager.CompleteRequest(); 
} 
} 
catch 
{ 
} 
} 
catch (ThreadAbortException exception3) 
{ 
if ((exception3.ExceptionState != null) && (exception3.ExceptionState is CancelModuleException)) 
{ 
CancelModuleException exceptionState = (CancelModuleException) exception3.ExceptionState; 
if (exceptionState.Timeout) 
{ 
exception = new HttpException(SR.GetString("Request_timed_out"), null, 0xbb9); 
PerfCounters.IncrementCounter(AppPerfCounter.REQUESTS_TIMED_OUT); 
} 
else 
{ 
exception = null; 
this._stepManager.CompleteRequest(); 
} 
Thread.ResetAbort(); 
} 
} 
completedSynchronously = true; 
return exception; 
}

是真正执行IExecutionStep的Execute方法。

通过以上的分析我们可以简单的理解asp.net在管道模式下管道主要是通过ApplicationStepManager来注册和调用的。集成模式下的PipelineStepManager和ApplicationStepManager结构类似。

个人在这里只是抛砖引玉,希望大家拍砖。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐