从专题三开始分析Community Server的一些具体的技术实现,根据IIS对请求的处理流程,从HttpModule& HttpHandler切入话题,同时你也可以通过一系列的专题了解CS的运行过程,不只如此,所有的.Net 1.1 构架的Web App都是以同样的顺序执行的。
先了解一下IIS系统。它是一个程序,负责对网站的内容进行管理并且处理对客户的请求做出反应。当用户对一个页面提出请求时,IIS做如下反应(不考虑权限问题):
1.把对方请求的虚拟路径转换成物理路径
2.根据物理路径搜索请求的文件
3.找到文件后,获取文件的内容
4.生成Http头信息。
5.向客户端发送所有的文件内容:首先是头信息,然后是Html内容,最后是其它文件的内容。
6.客户端IE浏览器获得信息后,解析文件内容,找出其中的引用文件,如.js .css .gif等,向IIS请求这些文件。
7.IIS获取请求后,发送文件内容。
8.当浏览器获取所有内容后,生成内容界面,客户就看到图像/文本/其它内容了。
但是IIS本身是不支持动态页面的,也就是说它仅仅支持静态html页面的内容,对于如.asp,.aspx,.cgi,.php等,IIS并不会处理这些标记,它就会把它当作文本,丝毫不做处理发送到客户端。为了解决这个问题。IIS有一种机制,叫做ISAPI的筛选器,这个东西是一个标准组件(COM组件),当在在访问IIS所不能处理的文件时,如asp.net 1.1 中的IIS附加ISAPI筛选器如图:
Asp.net服务在注册到IIS的时候,会把每个扩展可以处理的文件扩展名注册到IIS里面(如:*.ascx、*.aspx等)。扩展启动后,就根据定义好的方式来处理IIS所不能处理的文件,然后把控制权跳转到专门处理代码的进程中。让这个进程开始处理代码,生成标准的HTML代码,生成后把这些代码加入到原有的Html中,最后把完整的Html返回给IIS,IIS再把内容发送到客户端。
有上面对ISAPI的简单描述,我们把HttpModule& HttpHandler分开讨论,并且结合CS进行具体的实现分析。
HttpModule:
HttpModule实现了ISAPI Filter的功能,是通过对IhttpModule接口的继承来处理。下面打开CS中的CommunityServerComponents项目下的CSHttpModule.cs文件(放在HttpModule目录)
//------------------------------------------------------------------------------
//<copyrightcompany="TelligentSystems">
//Copyright(c)TelligentSystemsCorporation.Allrightsreserved.
//</copyright>
//------------------------------------------------------------------------------

usingSystem;
usingSystem.IO;
usingSystem.Web;
usingCommunityServer.Components;
usingCommunityServer.Configuration;

namespaceCommunityServer


{

//*********************************************************************
//CSHttpModule
//

/**////<summary>
///ThisHttpModuleencapsulatesalltheforumsrelatedeventsthatoccur
///duringASP.NETapplicationstart-up,errors,andendrequest.
///</summary>
//***********************************************************************/
publicclassCSHttpModule:IHttpModule


{

Membervariablesandinheritedproperties/methods#regionMembervariablesandinheritedproperties/methods

publicStringModuleName


{

get
{return"CSHttpModule";}
}


//*********************************************************************
//ForumsHttpModule
//

/**////<summary>
///InitializestheHttpModuleandperformsthewireupofallapplication
///events.
///</summary>
///<paramname="application">Applicationthemoduleisbeingrunfor</param>
publicvoidInit(HttpApplicationapplication)


{
//Wire-upapplicationevents
//
application.BeginRequest+=newEventHandler(this.Application_BeginRequest);
application.AuthenticateRequest+=newEventHandler(Application_AuthenticateRequest);
application.Error+=newEventHandler(this.Application_OnError);
application.AuthorizeRequest+=newEventHandler(this.Application_AuthorizeRequest);

//settingsID=SiteSettingsManager.GetSiteSettings(application.Context).SettingsID;
Jobs.Instance().Start();
//CSExceptionex=newCSException(CSExceptionType.ApplicationStart,"AppicationStarted"+AppDomain.CurrentDomain.FriendlyName);
//ex.Log();
}

//intsettingsID;
publicvoidDispose()


{
//CSExceptionex=newCSException(CSExceptionType.ApplicationStop,"ApplicationStopping"+AppDomain.CurrentDomain.FriendlyName);
//ex.Log(settingsID);
Jobs.Instance().Stop();
}


Installer#regionInstaller




#endregion


#endregion


ApplicationOnError#regionApplicationOnError
privatevoidApplication_OnError(Objectsource,EventArgse)


{
HttpApplicationapplication=(HttpApplication)source;
HttpContextcontext=application.Context;

CSExceptioncsException=context.Server.GetLastError()asCSException;

if(csException==null)
csException=context.Server.GetLastError().GetBaseException()asCSException;

try


{
if(csException!=null)


{
switch(csException.ExceptionType)


{
caseCSExceptionType.UserInvalidCredentials:
caseCSExceptionType.AccessDenied:
caseCSExceptionType.AdministrationAccessDenied:
caseCSExceptionType.ModerateAccessDenied:
caseCSExceptionType.PostDeleteAccessDenied:
caseCSExceptionType.PostProblem:
caseCSExceptionType.UserAccountBanned:
caseCSExceptionType.ResourceNotFound:
caseCSExceptionType.UserUnknownLoginError:
caseCSExceptionType.SectionNotFound:
csException.Log();
break;
}
}
else


{
Exceptionex=context.Server.GetLastError();
if(ex.InnerException!=null)
ex=ex.InnerException;

csException=newCSException(CSExceptionType.UnknownError,ex.Message,context.Server.GetLastError());

System.Data.SqlClient.SqlExceptionsqlEx=exasSystem.Data.SqlClient.SqlException;
if(sqlEx==null||sqlEx.Number!=-2)//don'tlogtimeouts
csException.Log();
}
}

catch
{}//notmuchtodohere,butwewanttopreventinfiniteloopingwithourerrorhandles

CSEvents.CSException(csException);
}


#endregion



ApplicationAuthenticateRequest#regionApplicationAuthenticateRequest

privatevoidApplication_AuthenticateRequest(Objectsource,EventArgse)


{
HttpContextcontext=HttpContext.Current;
Providerp=null;
ExtensionModulemodule=null;

//Iftheinstallerismakingtherequestterminateearly

if(CSConfiguration.GetConfig().AppLocation.CurrentApplicationType==ApplicationType.Installer)
{
return;
}

//Onlycontinueifwehaveavalidcontext
//
if((context==null)||(context.User==null))
return;

try


{
//Logictohandlevariousauthenticationtypes
//
switch(context.User.Identity.GetType().Name.ToLower())


{

//Microsoftpassport
case"passportidentity":
p=(Provider)CSConfiguration.GetConfig().Extensions["PassportAuthentication"];
module=ExtensionModule.Instance(p);
if(module!=null)
module.ProcessRequest();
else
gotodefault;
break;

//Windows
case"windowsidentity":
p=(Provider)CSConfiguration.GetConfig().Extensions["WindowsAuthentication"];
module=ExtensionModule.Instance(p);
if(module!=null)
module.ProcessRequest();
else
gotodefault;
break;

//Forms
case"formsidentity":
p=(Provider)CSConfiguration.GetConfig().Extensions["FormsAuthentication"];
module=ExtensionModule.Instance(p);
if(module!=null)
module.ProcessRequest();
else
gotodefault;
break;

//Custom
case"customidentity":
p=(Provider)CSConfiguration.GetConfig().Extensions["CustomAuthentication"];
module=ExtensionModule.Instance(p);
if(module!=null)
module.ProcessRequest();
else
gotodefault;
break;

default:
CSContext.Current.UserName=context.User.Identity.Name;
break;

}

}
catch(Exceptionex)


{
CSExceptionforumEx=newCSException(CSExceptionType.UnknownError,"ErrorinAuthenticateRequest",ex);
forumEx.Log();

throwforumEx;
}

////Gettherolestheuserbelongsto
////
//Rolesroles=newRoles();
//roles.GetUserRoles();
}
#endregion


ApplicationAuthorizeRequest#regionApplicationAuthorizeRequest

privatevoidApplication_AuthorizeRequest(Objectsource,EventArgse)
{


if(CSConfiguration.GetConfig().AppLocation.CurrentApplicationType==ApplicationType.Installer)


{
//CSContext.Create(context);
return;
}


HttpApplicationapplication=(HttpApplication)source;
HttpContextcontext=application.Context;

CSContextcsContext=CSContext.Current;
//boolenableBannedUsersToLogin=CSContext.Current.SiteSettings.EnableBannedUsersToLogin;

////Iftheinstallerismakingtherequestterminateearly
//if(csContext.ApplicationType==ApplicationType.Installer){
//return;
//}

//csContext.User=CSContext.Current.User;
