当前位置: 主页 > 日志 > ISAPI/ADSI >

利用ISAPI Filter“域名重写”实现完整的URL转发

// by redice 2009.8.21
// http://www.redicecn.cn
// 想写点东西...

背景知识:域名解析中“传统URL转发”是不完整的,只能转发到特定的URL,而不能转发到特定URL下的其它目录和文件。

示例一:
我们将域名bbs.taoyard.com做“传统URL转发”到http://www.taoyard.com/bbs。这样我们通过访问http://bbs.taoyard.com 就能访问到
http://www.taoyard.com/bbs的页面。但是我们不能通过http://bbs.taoyard.com/index.asp?boardid=1 
来访问 http://www.taoyard.com/bbs/index.asp?boardid=1。因为“传统URL”转发只能转发到特定URL,而不能转发到其下的目录和文件。

示例二:
公益组织“慈善厨房”的国际域名是www.yellowrivercharity.com,它们的虚拟主机是国外的,这家IDC的虚拟主机不支持绑定多个域名(只能绑定一个域名,呵呵,不知道用的什么服务器)。现在“慈善厨房”又申请了一个cn域名:test.soupkitchen.cn。他们想实现通过两个域名能访问到同样的内容,而且Web服务器必须要使用国外的那台虚拟主机。

“慈善厨房”将域名test.soupkitchen.cn做URL转发到www.yellowrivercharity.com,这样通过test.soupkitchen.cn可以访问到www.yellowrivercharity.com了。他们在中国对外公布了很多以test.soupkitchen.cn为域名的子网页,
例如 http://test.soupkitchen.cn/chinese/about(chn).asp,但是由于test.soupkitchen.cn不能转发www.yellowrivercharity.com下的子目录和子网页,因此那些地址都是无效的。



如何解决上面的问题呢?
我们需要一种能实现完整URL转发的机制。我想到了使用ISAPI Filter“域名重写”实现完整的URL转发。
(“域名重写”这个词可是我创造的,哈哈)。

 实现其实很简单,只需要3步:(我们需要准备一个虚拟主机,新建一个呗,就叫“慈善厨房”吧)
(1)在Win2003 IIS 6.0下新建一个虚拟主机,称为“慈善厨房”,将域名test.soupkitchen.cn绑定其上。
(2)test.soupkitchen.cn做域名解析到202.117.112.10(上面“慈善厨房”虚拟主机使用的IP)。
(3)核心:安装“域名重写”的ISAPI Filter插件。

ok,这样就成功了。前两步都很简单。关键是第三步,我们要编写一个ISAPI Filter实现“域名重写”。

熟悉Filter的人都知道,在SF_NOTIFY_URL_MAP事件处理过程中,我们可以很方便地获取到host,url,querystring这些信息,
这三个信息也就组成了一个完整的URL。只要我们将host替换成www.yellowrivercharity.com,然后使用ServerSupportFunction向
客户端发送"302 Redirect" URL重定向(重定向到我们新合成的完整URL),这样我们就实现了“域名重写”。

核心代码如下:

DWORD CSurFilter::OnUrlMap(CHttpFilterContext* pCtxt,
    PHTTP_FILTER_URL_MAP pMapInfo)
{
    CString csNewFullUrl// 新的完整地址

    char szHost[256]={0};
    CString csHost;
    DWORD dwLen=255;
    // 取得host
    if(pCtxt->GetServerVariable("HTTP_HOST",szHost,&dwLen))
    {
        csHost=szHost;
        csHost.MakeLower();
        this->ODS("host=%s ",szHost);

        // 检查是否为需要重写的域名
        if(csHost==this->csOldDomain//csOldDomain为原域名,从配置文件中读取
        {
            csNewFullUrl="Location: ";
            csNewFullUrl+="http://"+this->csNewDomain//csNewDomain为新域名,从配置文件中读取
            // 取得url
            this->ODS("url=%s ",pMapInfo->pszURL);
            csNewFullUrl+=pMapInfo->pszURL;

            char szQueryString[256]={0};
            dwLen=255;
            // 取得QueryString
            if(pCtxt->GetServerVariable("QUERY_STRING",szQueryString,&dwLen))
            {
                if(strlen(szQueryString)>0)
                {
                    this->ODS("querystring=%s ",szQueryString);
                    csNewFullUrl+="?";
                    csNewFullUrl+=szQueryString;
                }
            }
            
            this->ODS("NewFullUrl=%s ",csNewFullUrl);

            csNewFullUrl+=" ";

            // URL 重定向
            pCtxt->ServerSupportFunction(SF_REQ_SEND_RESPONSE_HEADER, 
                    (LPVOID"302 Redirect", 
                    (DWORD *csNewFullUrl.GetBuffer(0),0);

        }
    }
    else
        this->ODS("获取host信息失败! ");


    return SF_STATUS_REQ_NEXT_NOTIFICATION;
}


通过上面三步设置,我们现在就可以通过“http://test.soupkitchen.cn/子目录/子页面"”
访问到“www.yellowrivercharity.com/子目录/子页面”了。这样就实现了完整的URL转发。

[日志信息]

该日志于 2009-08-21 14:44 由 redice 发表在 redice's Blog ,你除了可以发表评论外,还可以转载 “利用ISAPI Filter“域名重写”实现完整的URL转发” 日志到你的网站或博客,但是请保留源地址及作者信息,谢谢!!    (尊重他人劳动,你我共同努力)
   
验证(必填):   点击我更换验证码

redice's Blog  is powered by DedeCms |  Theme by Monkeii.Lee |  网站地图 |  本服务器由西安鲲之鹏网络信息技术有限公司友情提供

返回顶部