国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

Community Server專題三:HttpModule

2024-07-21 02:29:28
字體:
供稿:網(wǎng)友

從專題三開始分析community server的一些具體的技術(shù)實現(xiàn),根據(jù)iis對請求的處理流程,從httpmodule& httphandler切入話題,同時你也可以通過一系列的專題了解cs的運行過程,不只如此,所有的.net 1.1 構(gòu)架的web app都是以同樣的順序執(zhí)行的。

先了解一下iis系統(tǒng)。它是一個程序,負(fù)責(zé)對網(wǎng)站的內(nèi)容進(jìn)行管理并且處理對客戶的請求做出反應(yīng)。當(dāng)用戶對一個頁面提出請求時,iis做如下反應(yīng)(不考慮權(quán)限問題):

1.把對方請求的虛擬路徑轉(zhuǎn)換成物理路徑

2.根據(jù)物理路徑搜索請求的文件

3.找到文件后,獲取文件的內(nèi)容

4.生成http頭信息。

5.向客戶端發(fā)送所有的文件內(nèi)容:首先是頭信息,然后是html內(nèi)容,最后是其它文件的內(nèi)容。

6.客戶端ie瀏覽器獲得信息后,解析文件內(nèi)容,找出其中的引用文件,如.js .css .gif等,向iis請求這些文件。

7.iis獲取請求后,發(fā)送文件內(nèi)容。

8.當(dāng)瀏覽器獲取所有內(nèi)容后,生成內(nèi)容界面,客戶就看到圖像/文本/其它內(nèi)容了。

但是iis本身是不支持動態(tài)頁面的,也就是說它僅僅支持靜態(tài)html頁面的內(nèi)容,對于如.asp,.aspx,.cgi,.php等,iis并不會處理這些標(biāo)記,它就會把它當(dāng)作文本,絲毫不做處理發(fā)送到客戶端。為了解決這個問題。iis有一種機制,叫做isapi的篩選器,這個東西是一個標(biāo)準(zhǔn)組件(com組件),當(dāng)在在訪問iis所不能處理的文件時,如asp.net 1.1 中的iis附加isapi篩選器如圖:

asp.net服務(wù)在注冊到iis的時候,會把每個擴展可以處理的文件擴展名注冊到iis里面(如:*.ascx、*.aspx等)。擴展啟動后,就根據(jù)定義好的方式來處理iis所不能處理的文件,然后把控制權(quán)跳轉(zhuǎn)到專門處理代碼的進(jìn)程中。讓這個進(jìn)程開始處理代碼,生成標(biāo)準(zhǔn)的html代碼,生成后把這些代碼加入到原有的html中,最后把完整的html返回給iis,iis再把內(nèi)容發(fā)送到客戶端。

    有上面對isapi的簡單描述,我們把httpmodule& httphandler分開討論,并且結(jié)合cs進(jìn)行具體的實現(xiàn)分析。

httpmodule:

httpmodule實現(xiàn)了isapi filter的功能,是通過對ihttpmodule接口的繼承來處理。下面打開cs中的communityservercomponents項目下的cshttpmodule.cs文件(放在httpmodule目錄)


//------------------------------------------------------------------------------
// <copyright company="telligent systems">
//     copyright (c) telligent systems corporation.  all rights reserved.
// </copyright>
//------------------------------------------------------------------------------

using system;
using system.io;
using system.web;
using communityserver.components;
using communityserver.configuration;

namespace communityserver
{

    // *********************************************************************
    //  cshttpmodule
    //
    /**//// <summary>
    /// this httpmodule encapsulates all the forums related events that occur
    /// during asp.net application start-up, errors, and end request.
    /// </summary>
    // ***********************************************************************/
    public class cshttpmodule : ihttpmodule
    {
        member variables and inherited properties / methods#region member variables and inherited properties / methods

        public string modulename
        {
            get { return "cshttpmodule"; }
        }   


        // *********************************************************************
        //  forumshttpmodule
        //
        /**//// <summary>
        /// initializes the httpmodule and performs the wireup of all application
        /// events.
        /// </summary>
        /// <param name="application">application the module is being run for</param>
        public void init(httpapplication application)
        {
            // wire-up application events
            //
            application.beginrequest += new eventhandler(this.application_beginrequest);
            application.authenticaterequest += new eventhandler(application_authenticaterequest);
            application.error += new eventhandler(this.application_onerror);
            application.authorizerequest += new eventhandler(this.application_authorizerequest);
           
            //settingsid = sitesettingsmanager.getsitesettings(application.context).settingsid;
            jobs.instance().start();
            //csexception ex = new csexception(csexceptiontype.applicationstart, "appication started " +  appdomain.currentdomain.friendlyname);
            //ex.log();
        }

        //int settingsid;
        public void dispose()
        {
            //csexception ex = new csexception(csexceptiontype.applicationstop, "application stopping " +  appdomain.currentdomain.friendlyname);
            //ex.log(settingsid);
            jobs.instance().stop();
        }

        installer#region installer

 


        #endregion


        #endregion

        application onerror#region application onerror
        private void application_onerror (object source, eventargs e)
        {
            httpapplication application = (httpapplication)source;
            httpcontext context = application.context;
           
            csexception csexception = context.server.getlasterror() as csexception;

            if(csexception == null)
                csexception = context.server.getlasterror().getbaseexception() as csexception;

            try
            {
                if (csexception != null)
                {
                    switch (csexception.exceptiontype)
                    {
                        case csexceptiontype.userinvalidcredentials:
                        case csexceptiontype.accessdenied:
                        case csexceptiontype.administrationaccessdenied:
                        case csexceptiontype.moderateaccessdenied:
                        case csexceptiontype.postdeleteaccessdenied:
                        case csexceptiontype.postproblem:
                        case csexceptiontype.useraccountbanned:
                        case csexceptiontype.resourcenotfound:
                        case csexceptiontype.userunknownloginerror:
                        case csexceptiontype.sectionnotfound:
                            csexception.log();
                            break;
                    }
                }
                else
                {
                    exception ex = context.server.getlasterror();
                    if(ex.innerexception != null)
                        ex = ex.innerexception;

                    csexception = new csexception(csexceptiontype.unknownerror, ex.message, context.server.getlasterror());

                    system.data.sqlclient.sqlexception sqlex = ex as system.data.sqlclient.sqlexception;
                    if(sqlex == null || sqlex.number != -2) //don't log time outs
                        csexception.log();
                }
            }
            catch{} //not much to do here, but we want to prevent infinite looping with our error handles

            csevents.csexception(csexception);
        }


        #endregion


        application authenticaterequest#region application authenticaterequest

        private void application_authenticaterequest(object source, eventargs e)
        {
            httpcontext context = httpcontext.current;
            provider p = null;
            extensionmodule module = null;

            // if the installer is making the request terminate early
            if (csconfiguration.getconfig().applocation.currentapplicationtype == applicationtype.installer) {
                return;
            }
           
            // only continue if we have a valid context
            //
            if ((context == null) || (context.user == null))
                return;

            try
            {
                // logic to handle various authentication types
                //
                switch(context.user.identity.gettype().name.tolower())
                {

                        // microsoft passport
                    case "passportidentity":
                        p = (provider) csconfiguration.getconfig().extensions["passportauthentication"];
                        module = extensionmodule.instance(p);
                        if(module != null)
                            module.processrequest();
                        else
                            goto default;
                        break;

                        // windows
                    case "windowsidentity":
                        p = (provider) csconfiguration.getconfig().extensions["windowsauthentication"];
                        module = extensionmodule.instance(p);
                        if(module != null)
                            module.processrequest();
                        else
                            goto default;
                        break;

                        // forms
                    case "formsidentity":
                        p = (provider) csconfiguration.getconfig().extensions["formsauthentication"];
                        module = extensionmodule.instance(p);
                        if(module != null)
                            module.processrequest();
                        else
                            goto default;
                        break;

                        // custom
                    case "customidentity":
                        p = (provider) csconfiguration.getconfig().extensions["customauthentication"];
                        module = extensionmodule.instance(p);
                        if(module != null)
                            module.processrequest();
                        else
                            goto default;
                        break;

                    default:
                        cscontext.current.username = context.user.identity.name;
                        break;

                }

            }
            catch( exception ex )
            {
                csexception forumex = new csexception( csexceptiontype.unknownerror, "error in authenticaterequest", ex );
                forumex.log();

                throw forumex;
            }

            //            // get the roles the user belongs to
            //            //
            //            roles roles = new roles();
            //            roles.getuserroles();
        }
        #endregion

        application authorizerequest#region application authorizerequest
        private void application_authorizerequest (object source, eventargs e) {


            if (csconfiguration.getconfig().applocation.currentapplicationtype == applicationtype.installer)
            {
                //cscontext.create(context);
                return;
            }


            httpapplication application = (httpapplication)source;
            httpcontext context = application.context;

            cscontext cscontext = cscontext.current;
            //bool enablebanneduserstologin = cscontext.current.sitesettings.enablebanneduserstologin;
           
//            // if the installer is making the request terminate early
//            if (cscontext.applicationtype == applicationtype.installer) {
//                return;
//            }

            //cscontext.user = cscontext.current.user;

            csevents.userknown(cscontext.user);

            validateapplicationstatus(cscontext);

            // track anonymous users
            //
            users.trackanonymoususers(context);

            // do we need to force the user to login?
            //
           
            if (context.request.isauthenticated)
            {
                string username = context.user.identity.name;
                if (username != null)
                {
                    string[] roles = communityserver.components.roles.getuserrolenames(username);
                    if (roles != null && roles.length > 0)
                    {
                        cscontext.rolescachekey = string.join(",",roles);
                    }
                }
            }
        }

        #endregion

        application beginrequest#region application beginrequest
        private void application_beginrequest(object source, eventargs e)
        {
            httpapplication application = (httpapplication)source;
            httpcontext context = application.context;

           
            csconfiguration config = csconfiguration.getconfig();
           
            // if the installer is making the request terminate early
            if (config.applocation.currentapplicationtype == applicationtype.installer)
            {
                //cscontext.create(context);
                return;
            }

            checkwwwstatus(config,context);

           

            cscontext.create(context, rewriteurl(context));

                                   
        }

        private void checkwwwstatus(csconfiguration config, httpcontext context)
        {
            if(config.wwwstatus == wwwstatus.ignore)
                return;

            const string withwww = "http://www.";
            const string nowww = "http://";
            string rawurl = context.request.url.tostring().tolower();
            bool iswww = rawurl.startswith(withwww);

           
            if(config.wwwstatus == wwwstatus.remove && iswww)
            {
                context.response.redirect(rawurl.replace(withwww, nowww));
            }
            else if(config.wwwstatus == wwwstatus.require && !iswww)
            {
                context.response.redirect(rawurl.replace(nowww, withwww));
            }
           
       
        }

        rewriteurl#region rewriteurl
        private bool rewriteurl(httpcontext context)
        {

            // we're now allowing each individual application to be turned on and off individually. so before we allow
            // a request to go through we need to check if this product is disabled and the path is for the disabled product,
            // if so we display the disabled product page.
            //
            // i'm also allowing the page request to go through if the page request is for an admin page. in the past if you
            // disabled the forums you were locked out, now with this check, even if you're not on the same machine but you're accessing
            // an admin path the request will be allowed to proceed, where the rest of the checks will ensure that the user has the
            // permission to access the specific url.

            // url rewriting
            //
            //rewriteurl(context);

            string newpath = null;
            string path = context.request.path;
            bool isrewritten = siteurls.rewriteurl(path,context.request.url.query,out newpath);

            //very wachky. the first call into rewritepath always fails with a 404.
            //calling rewritepath twice actually fixes the probelm as well. instead,
            //we use the second rewritepath overload and it seems to work 100%
            //of the time.
            if(isrewritten && newpath != null)
            {
                string qs = null;
                int index = newpath.indexof('?');
                if (index >= 0)
                {
                    qs = (index < (newpath.length - 1)) ? newpath.substring(index + 1) : string.empty;
                    newpath = newpath.substring(0, index);
                }
                context.rewritepath(newpath,null,qs);
            }

            return isrewritten;
        }

        #endregion

        private void validateapplicationstatus(cscontext cntx)
        {
            if(!cntx.user.isadministrator)
            {
                string disablepath = null;
                switch(cntx.config.applocation.currentapplicationtype)
                {
                    case applicationtype.forum:
                        if(cntx.sitesettings.forumsdisabled)
                            disablepath = "forumsdisabled.htm";
                        break;
                    case applicationtype.weblog:
                        if(cntx.sitesettings.blogsdisabled)
                            disablepath = "blogsdisabled.htm";
                        break;
                    case applicationtype.gallery:
                        if(cntx.sitesettings.galleriesdisabled)
                            disablepath = "galleriesdisabled.htm";
                        break;
                    case applicationtype.guestbook:
                        if(cntx.sitesettings.guestbookdisabled)
                            disablepath = "guestbookdisabled.htm";
                        break;
                    case applicationtype.document:                   //新增 ugoer
                        if(cntx.sitesettings.documentdisabled)
                            disablepath = "documentsdisabled.htm";
                        break;
                }

                if(disablepath != null)
                {

                    string errorpath = cntx.context.server.mappath(string.format("~/languages/{0}/errors/{1}",cntx.config.defaultlanguage,disablepath));
                    using(streamreader reader = new streamreader(errorpath))
                    {
                        string html = reader.readtoend();
                        reader.close();

                        cntx.context.response.write(html);
                        cntx.context.response.end();
                    }
                }
            }
        }

        #endregion


    }

}


在web.config中的配置:

        <httpmodules>
            <add name="communityserver" type="communityserver.cshttpmodule, communityserver.components" />
            <add name="profile" type="microsoft.scalablehosting.profile.profilemodule, memberrole, version=1.0.0.0, culture=neutral, publickeytoken=b7c773fb104e7562"/>
            <add name="rolemanager" type="microsoft.scalablehosting.security.rolemanagermodule, memberrole, version=1.0.0.0, culture=neutral, publickeytoken=b7c773fb104e7562" />
        </httpmodules>
 

cshttpmodule.cs   uml:

要實現(xiàn)httpmodule功能需要如下步驟:

1.編寫一個類,實現(xiàn)ihttpmodule接口

2.實現(xiàn)init 方法,并且注冊需要的方法

3.實現(xiàn)注冊的方法

4.實現(xiàn)dispose方法,如果需要手工為類做一些清除工作,可以添加dispose方法的實現(xiàn),但這不是必需的,通常可以不為dispose方法添加任何代碼。

5.在web.config文件中,注冊您編寫的類

到這里我們還需要了解一個asp.net的運行過程:

在圖中第二步可以看到當(dāng)請求開始的時候,馬上就進(jìn)入了httpmodule,在cs中由于實現(xiàn)了httpmodule的擴展cshttpmodule.cs類,因此當(dāng)一個web請求發(fā)出的時候(如:一個用戶訪問他的blog),cs系統(tǒng)首先調(diào)用cshttpmodule.cs類,并且進(jìn)入

public void init(httpapplication application)

該方法進(jìn)行初始化事件:

application.beginrequest += new eventhandler(this.application_beginrequest);

application.authenticaterequest += new eventhandler(application_authenticaterequest);

application.error += new eventhandler(this.application_onerror);

application.authorizerequest += new eventhandler(this.application_authorizerequest);

有事件就要有對應(yīng)的處理方法:

private void application_beginrequest(object source, eventargs e)

private void application_authenticaterequest(object source, eventargs e)

private void application_onerror (object source, eventargs e)

private void application_authorizerequest (object source, eventargs e)

事件被初始化后就等待系統(tǒng)的觸發(fā),請求進(jìn)入下一步此時系統(tǒng)觸發(fā)application_beginrequest事件,事件處理內(nèi)容如下:

private void application_beginrequest(object source, eventargs e)
        {
            httpapplication application = (httpapplication)source;
            httpcontext context = application.context;

           
            csconfiguration config = csconfiguration.getconfig();
           
            // if the installer is making the request terminate early
            if (config.applocation.currentapplicationtype == applicationtype.installer)
            {
                //cscontext.create(context);
                return;
            }

            checkwwwstatus(config,context);

           

            cscontext.create(context, rewriteurl(context));

        }

        private void checkwwwstatus(csconfiguration config, httpcontext context)
        {
            if(config.wwwstatus == wwwstatus.ignore)
                return;

            const string withwww = "http://www.";
            const string nowww = "http://";
            string rawurl = context.request.url.tostring().tolower();
            bool iswww = rawurl.startswith(withwww);

           
            if(config.wwwstatus == wwwstatus.remove && iswww)
            {
                context.response.redirect(rawurl.replace(withwww, nowww));
            }
            else if(config.wwwstatus == wwwstatus.require && !iswww)
            {
                context.response.redirect(rawurl.replace(nowww, withwww));
            }
            
        }

        rewriteurl#region rewriteurl
        private bool rewriteurl(httpcontext context)
        {

            // we're now allowing each individual application to be turned on and off individually. so before we allow
            // a request to go through we need to check if this product is disabled and the path is for the disabled product,
            // if so we display the disabled product page.
            //
            // i'm also allowing the page request to go through if the page request is for an admin page. in the past if you
            // disabled the forums you were locked out, now with this check, even if you're not on the same machine but you're accessing
            // an admin path the request will be allowed to proceed, where the rest of the checks will ensure that the user has the
            // permission to access the specific url.

            // url rewriting
            //
            //rewriteurl(context);

            string newpath = null;
            string path = context.request.path;
            bool isrewritten = siteurls.rewriteurl(path,context.request.url.query,out newpath);

            //very wachky. the first call into rewritepath always fails with a 404.
            //calling rewritepath twice actually fixes the probelm as well. instead,
            //we use the second rewritepath overload and it seems to work 100%
            //of the time.
            if(isrewritten && newpath != null)
            {
                string qs = null;
                int index = newpath.indexof('?');
                if (index >= 0)
                {
                    qs = (index < (newpath.length - 1)) ? newpath.substring(index + 1) : string.empty;
                    newpath = newpath.substring(0, index);
                }
                context.rewritepath(newpath,null,qs);
            }

            return isrewritten;
        }

        #endregion

這個事件主要做兩個事情

a:為發(fā)出請求的用戶初始化一個context,初始化context用到了線程中本地數(shù)據(jù)槽(localdatastoreslot),把當(dāng)前用戶請求的上下文(contextb)保存在為此請求開辟的內(nèi)存中。

b:判斷是否需要重寫 url(檢查是否需要重寫的過程是對siteurls.config文件中正則表達(dá)式和對應(yīng)url處理的過程),如果需要重寫url,就執(zhí)行asp.net級別上的rewritepath方法獲得新的路徑,新的路徑才是真正的請求信息所在的路徑。這個專題不是講url rewrite,所以只要明白url在這里就進(jìn)行rewrite就可以了,具體的后面專題會敘述。

處理完application_beginrequest 后進(jìn)程繼向下執(zhí)行,隨后觸發(fā)了application_authenticaterequest(如果有朋友不明白這個執(zhí)行過程,可以通過調(diào)試中設(shè)置多個斷點捕獲事件執(zhí)行的順序。如果你還不會調(diào)試,可以留言偷偷的告訴我,嘿嘿。),application_authenticaterequest事件初始化一個context的identity,其實cs提供了很多的identity支持,包括microsoft passport,但是目前的版本中使用的是默認(rèn)值system.web.security.formsidentity。具體代碼如下:

private void application_authenticaterequest(object source, eventargs e)
        {
            httpcontext context = httpcontext.current;
            provider p = null;
            extensionmodule module = null;

            // if the installer is making the request terminate early
            if (csconfiguration.getconfig().applocation.currentapplicationtype == applicationtype.installer) {
                return;
            }
           
            // only continue if we have a valid context
            //
            if ((context == null) || (context.user == null))
                return;

            try
            {
                // logic to handle various authentication types
                //
                switch(context.user.identity.gettype().name.tolower())
                {

                        // microsoft passport
                    case "passportidentity":
                        p = (provider) csconfiguration.getconfig().extensions["passportauthentication"];
                        module = extensionmodule.instance(p);
                        if(module != null)
                            module.processrequest();
                        else
                            goto default;
                        break;

                        // windows
                    case "windowsidentity":
                        p = (provider) csconfiguration.getconfig().extensions["windowsauthentication"];
                        module = extensionmodule.instance(p);
                        if(module != null)
                            module.processrequest();
                        else
                            goto default;
                        break;

                        // forms
                    case "formsidentity":
                        p = (provider) csconfiguration.getconfig().extensions["formsauthentication"];
                        module = extensionmodule.instance(p);
                        if(module != null)
                            module.processrequest();
                        else
                            goto default;
                        break;

                        // custom
                    case "customidentity":
                        p = (provider) csconfiguration.getconfig().extensions["customauthentication"];
                        module = extensionmodule.instance(p);
                        if(module != null)
                            module.processrequest();
                        else
                            goto default;
                        break;

                    default:
                        cscontext.current.username = context.user.identity.name;
                        break;

                }

            }
            catch( exception ex )
            {
                csexception forumex = new csexception( csexceptiontype.unknownerror, "error in authenticaterequest", ex );
                forumex.log();

                throw forumex;
            }

            //            // get the roles the user belongs to
            //            //
            //            roles roles = new roles();
            //            roles.getuserroles();
        }

再下來是application_authorizerequest事件被觸發(fā),事件代碼如下:

private void application_authorizerequest (object source, eventargs e) {

            if (csconfiguration.getconfig().applocation.currentapplicationtype == applicationtype.installer)
            {
                //cscontext.create(context);
                return;
            }


            httpapplication application = (httpapplication)source;
            httpcontext context = application.context;

            cscontext cscontext = cscontext.current;
            //bool enablebanneduserstologin = cscontext.current.sitesettings.enablebanneduserstologin;
           
//            // if the installer is making the request terminate early
//            if (cscontext.applicationtype == applicationtype.installer) {
//                return;
//            }

            //cscontext.user = cscontext.current.user;

            csevents.userknown(cscontext.user);

            validateapplicationstatus(cscontext);

            // track anonymous users
            //
            users.trackanonymoususers(context);

            // do we need to force the user to login?
            //
       注冊會員,創(chuàng)建你的web開發(fā)資料庫,

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 彭泽县| 平舆县| 清原| 赫章县| 洮南市| 左云县| 昌黎县| 旅游| 历史| 平舆县| 陇川县| 龙南县| 大英县| 清流县| 渭南市| 交城县| 浠水县| 五峰| 广宗县| 蒙山县| 新晃| 溧阳市| 资中县| 柳州市| 西昌市| 四会市| 宜阳县| 清丰县| 沙雅县| 泸溪县| 辽中县| 碌曲县| 桐柏县| 小金县| 和林格尔县| 平凉市| 崇礼县| 西盟| 宜兰县| 景洪市| 三原县|