目前虚拟主机商提供将多个域名绑定到站点根目录,但是不提供类似cpanel那样可以将域名绑定到站点的子目录。 而当你手上有多个域名,网站空间和流量又有闲置的时候,是很希望 将 这些资源利用起来,而且要做到降低做站的成本。而网络上流传的多域名绑到子目录多为判断HTTP_HOST再使用Asp的 Response.Redirect或者php的header方法重订向到子目录去。这种方法在地址的请求上发生了变化,大家都知道Redirect的定 向是很不友好的,在服务器端控制自动跳转会令访问者感到不安。 所以我需要的是对这个域名下面的所有请求都转接到对应的子目录里去 比如 http://www.xaradio.com/default.aspx 实际访问的是 http://www.3pub.com/xaradio/default.aspx http://www.xaradio.com/album.aspx?id=722 实际访问的是 http://www.3pub.com/xaradio/album.aspx?id=722 http://www.xaradio.com/*.aspx 实际要访问到http://www.3pub.com/xaradio/*.aspx 而绑定到该站点根目录的其他域名和地址仍然不受影响 如: http://www.3pub.com/ 和 http://3pub.com/ http://www.3pub.com/default.aspx 和 http://3pub.com/default.aspx http://www.aspxboy.com/484/default.aspx 该文章详细的描述了在Asp.Net中使用HttpModule和HttpHander来重写Url,读懂他特别是 http://www.aspxboy.com/484/archive.aspx#ekaa 节将是我们下面工作的前提朋友们可以下载该文章附带的代码研究。 如果您对HttpModule的编成非常熟悉那么可以向下进行了 一。 先把配置文件从web.config内移出为了不让web.config变的非常臃肿,我们将配置文件从web.config内移出 假设我们的多域名绑定配置文件为“MulitDomain.config“ 将RewriterConfiguration.cs的public static RewriterConfiguration GetConfig()方法 修改如下: /// 从XML配置文件中返回重写信息 /// /// RewriterConfiguration public static RewriterConfiguration GetConfig() { RewriterConfiguration config = (RewriterConfiguration) BoovooCache.Get(CacheKey); if(config == null) { // 2005-08-18 wu meibo update the config file to SiteUrls.config // HttpContext.Current.Cache.Insert("RewriterConfig", ConfigurationSettings.GetConfig("RewriterConfig")); ///************************************************************************************ /// /// Author:活靶子,huobazi /// Date:2005-08-18 /// /// Description:将配置文件移到单独的文件内,更新以下代码,原代码(上一行)停止工作 /// ///************************************************************************************ string filePath = String.Empty; if(HttpContext.Current != null) { filePath = HttpContext.Current.Server.MapPath("~/MulitDomain.config"); } else { filePath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "MulitDomain.config"; } XmlSerializer ser = new XmlSerializer(typeof(RewriterConfiguration)); FileStream fileReader = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); StreamReader reader = new StreamReader(fileReader); config = (ser.Deserialize(reader)) as RewriterConfiguration; reader.Close(); fileReader.Close(); if (File.Exists(filePath)) { CacheDependency dep = new CacheDependency(filePath); BoovooCache.Max(CacheKey,config,dep); BoovooCache.ReSetFactor(config.CacheFactor); } } return config; }二。做一些修补 RewriterModule.cs内 public virtual void Init(HttpApplication app) { ///********************************************************************************** /// Author:活靶子,huobazi /// Date:2005-08-18 /// Description:增加BeginRequest,在内增加防止黑客可能利用的某些Url漏洞攻击的代码 ///********************************************************************************** app.BeginRequest += new EventHandler(this.RewriterModule_BeginRequest); // 警告!此代码不适用于Windows身份验证! // 如果使用Windows身份验证, // 请改为 app.BeginRequest app.AuthorizeRequest += new EventHandler(this.RewriterModule_AuthorizeRequest); } protected virtual void RewriterModule_BeginRequest(object o , EventArgs e) { HttpApplication app = ((HttpApplication)(o)); HttpServerUtility Server = app.Server; HttpRequest Request = app.Request; ///************************************************************ /// Author:活靶子,huobazi /// Date:2005-08-18 /// Description:修补黑客可能采用".."的方法进入其他目录的问题 ///************************************************************ string strURL = Server.UrlDecode(Request.RawUrl); if (strURL.IndexOf("..") != -1) { throw new HttpException(404, "Not Found"); } ///********************************************************************************** /// Author:活靶子,huobazi /// Date:2005-08-18 /// Description:修补"规范化"问题 see:Path.GetFullPath(Request.PhysicalPath) != Request.PhysicalPath) { throw new HttpException(404, "Not Found"); } }三。开始匹配域名 protected void Rewrite(string requestedPath, System.Web.HttpApplication app) { string host = app.Context.Request.Url.Host.ToString().ToLower();//如果匹配则需要重写,那将请求重写到SendTo定义的目录内的该文件 string lookFor = "^" + rules[i].LookFor + "$"; //string lookFor = "^" + Rewriter.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].LookFor + requestedPath) + "$"; Regex re = new Regex(lookFor, RegexOptions.IgnoreCase); if (re.IsMatch(host)) { string sendToUrl = Rewriter.ResolveUrl(app.Context.Request.ApplicationPath, rules[i].SendTo + requestedPath); app.Context.Trace.Write("RewriterModule", "Rewriting URL to " + sendToUrl); Rewriter.RewriteUrl(app.Context, sendToUrl); break; } } app.Context.Trace.Write("RewriterModule", "Exiting ModuleRewriter"); }四。写规则文件 MulitDomain.config的匹配规则如下: <?xml version="1.0" encoding="utf-8" ?> <RewriterConfig> <Rules> <RewriterRule> <LookFor>www/.xaradio/.com</LookFor> <SendTo>~/xaradio</SendTo> </RewriterRule> <RewriterRule> <LookFor>xaradio/.com</LookFor> <SendTo>~/xaradio</SendTo> </RewriterRule> </Rules> </RewriterConfig>
|