// // VPathToHost.cs // // Authors: // Gonzalo Paniagua Javier (gonzalo@ximian.com) // Lluis Sanchez Gual (lluis@ximian.com) // // Copyright (c) Copyright 2002-2007 Novell, Inc // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Web.Hosting; using System.Globalization; namespace Mono.WebServer { public class VPathToHost { public readonly string vhost; public readonly int vport; public readonly string vpath; public string realPath; public readonly bool haveWildcard; public IApplicationHost AppHost; public IRequestBroker RequestBroker; public VPathToHost (string vhost, int vport, string vpath, string realPath) { this.vhost = (vhost != null) ? vhost.ToLower (CultureInfo.InvariantCulture) : null; this.vport = vport; this.vpath = vpath; if (String.IsNullOrEmpty (vpath) || vpath [0] != '/') throw new ArgumentException ("Virtual path must begin with '/': " + vpath, "vpath"); this.realPath = realPath; AppHost = null; if (vhost != null && this.vhost.Length != 0 && this.vhost [0] == '*') { haveWildcard = true; if (this.vhost.Length > 2 && this.vhost [1] == '.') this.vhost = this.vhost.Substring (2); } } public bool TryClearHost (IApplicationHost host) { if (AppHost == host) { AppHost = null; return true; } return false; } public void UnloadHost () { if (AppHost != null) AppHost.Unload (); AppHost = null; } public bool Redirect (string path, out string redirect) { redirect = null; if (path.Length == vpath.Length - 1) { redirect = vpath; return true; } return false; } public bool Match (string vhost, int vport, string vpath) { if (vport != -1 && this.vport != -1 && vport != this.vport) return false; if (vpath == null) return false; if (vhost != null && this.vhost != null && this.vhost != "*") { int length = this.vhost.Length; string lwrvhost = vhost.ToLower (CultureInfo.InvariantCulture); if (haveWildcard) { if (length > vhost.Length) return false; if (length == vhost.Length && this.vhost != lwrvhost) return false; if (vhost [vhost.Length - length - 1] != '.') return false; if (!lwrvhost.EndsWith (this.vhost)) return false; } else if (this.vhost != lwrvhost) { return false; } } int local = vpath.Length; int vlength = this.vpath.Length; if (vlength > local) { // Check for /xxx requests to be redirected to /xxx/ if (this.vpath [vlength - 1] != '/') return false; return (vlength - 1 == local && this.vpath.Substring (0, vlength - 1) == vpath); } return (vpath.StartsWith (this.vpath)); } public void CreateHost (ApplicationServer server, WebSource webSource) { string v = vpath; if (v != "/" && v.EndsWith ("/")) { v = v.Substring (0, v.Length - 1); } AppHost = ApplicationHost.CreateApplicationHost (webSource.GetApplicationHostType(), v, realPath) as IApplicationHost; AppHost.Server = server; if (!server.SingleApplication) { // Link the host in the application domain with a request broker in the main domain RequestBroker = webSource.CreateRequestBroker (); AppHost.RequestBroker = RequestBroker; } } } }