public bool Start(bool bgThread) { if (started) { throw new InvalidOperationException("The server is already started."); } if (vpathToHost == null) { throw new InvalidOperationException("SetApplications must be called first."); } if (single_app) { VPathToHost v = (VPathToHost)vpathToHost [0]; v.AppHost = AppHost; // Link the host in the application domain with a request broker in the *same* domain // Not needed for SingleApplication and mod_mono v.RequestBroker = webSource.CreateRequestBroker(); AppHost.RequestBroker = v.RequestBroker; } listen_socket = webSource.CreateSocket(); listen_socket.Listen(500); listen_socket.Blocking = false; runner = new Thread(new ThreadStart(RunServer)); runner.IsBackground = bgThread; runner.Start(); stop = false; return(true); }
VPathToHost GetOrCreateApplication(string vhost, int port, string filepath, string virt) { VPathToHost vapp = null; string vdir = Path.GetDirectoryName(virt); string pdir = Path.GetDirectoryName(filepath); DirectoryInfo vinfo = new DirectoryInfo(vdir); DirectoryInfo pinfo = new DirectoryInfo(pdir); string final_pdir = null; string final_vdir = null; while (vinfo != null && pinfo != null) { if (final_pdir == null && CheckDirectory(pinfo)) { final_pdir = pinfo.ToString(); final_vdir = vinfo.ToString(); break; } if (pinfo.Name != vinfo.Name) { final_vdir = vinfo.ToString(); break; } pinfo = pinfo.Parent; vinfo = vinfo.Parent; } if (final_pdir == null) { final_pdir = pinfo.ToString(); } if (final_vdir == null) { final_vdir = vinfo.ToString(); } //Console.Error.WriteLine ("final_pdir: {0} final_vdir: {1}", final_pdir, final_vdir); vapp = server.GetApplicationForPath(vhost, port, virt, false); if (vapp == null) { // Don't know why this breaks mod-mono-server2.exe, but not mod-mono-server.exe //final_pdir = "file://" + final_pdir; if (final_vdir [0] != '/') { final_vdir = "/" + final_vdir; } server.AddApplication(vhost, port, final_vdir, final_pdir); vapp = server.GetApplicationForPath(vhost, port, virt, false); } return(vapp); }
public VPathToHost GetApplicationForPath(string vhost, int vport, string vpath, string realPath) { VPathToHost host = GetApplicationForPath_mapping( vhost, vport, vpath, realPath); return(host == null?GetApplicationForPath_existing( vhost, vport, vpath) : host); }
void RunInternal(object state) { RequestData rdata = initial.RequestData; initial.FreeBuffer(); string vhost = null; // TODO: read the headers in InitialWorkerRequest int port = ((IPEndPoint)localEP).Port; VPathToHost vapp = server.GetApplicationForPath(vhost, port, rdata.Path, true); XSPApplicationHost host = null; if (vapp != null) { host = (XSPApplicationHost)vapp.AppHost; } if (host == null) { byte [] nf = HttpErrors.NotFound(rdata.Path); Write(nf, 0, nf.Length); Close(); return; } broker = (XSPRequestBroker)vapp.RequestBroker; requestId = broker.RegisterRequest(this); #if MONO if (ssl != null) { SslServerStream s = (stream as SslServerStream); ssl.KeySize = s.CipherStrength; ssl.SecretKeySize = s.KeyExchangeStrength; } #endif try { string redirect; vapp.Redirect(rdata.Path, out redirect); host.ProcessRequest(requestId, localEP.Address.Address, localEP.Port, remoteEP.Address.Address, remoteEP.Port, rdata.Verb, rdata.Path, rdata.QueryString, rdata.Protocol, rdata.InputBuffer, redirect, sock.Handle, ssl); } catch (FileNotFoundException fnf) { // We print this one, as it might be a sign of a bad deployment // once we require the .exe and Mono.WebServer in bin or the GAC. Console.Error.WriteLine(fnf); } catch (IOException) { // This is ok (including EndOfStreamException) } catch (Exception e) { Console.Error.WriteLine(e); } }
public void DestroyHost(IApplicationHost host) { // Called when the host appdomain is being unloaded for (int i = vpathToHost.Count - 1; i >= 0; i--) { VPathToHost v = (VPathToHost)vpathToHost [i]; if (v.TryClearHost(host)) { break; } } }
private void CreateHost(VPathToHost v) { lock (v) { if (v.AppHost == null) { v.CreateHost(this, web_source); if (HostCreated != null) { HostCreated(v.vhost, v.vport, v.vpath, v.AppHost); } } } }
public VPathToHost GetApplicationForPath(string vhost, int port, string path, bool defaultToRoot) { if (single_app) { return((VPathToHost)vpathToHost [0]); } VPathToHost bestMatch = null; int bestMatchLength = 0; for (int i = vpathToHost.Count - 1; i >= 0; i--) { VPathToHost v = (VPathToHost)vpathToHost [i]; int matchLength = v.vpath.Length; if (matchLength <= bestMatchLength || !v.Match(vhost, port, path)) { continue; } bestMatchLength = matchLength; bestMatch = v; } if (bestMatch != null) { lock (bestMatch) { if (bestMatch.AppHost == null) { bestMatch.CreateHost(this, webSource); } } return(bestMatch); } if (defaultToRoot) { return(GetApplicationForPath(vhost, port, "/", false)); } if (verbose) { Console.WriteLine("No application defined for: {0}:{1}{2}", vhost, port, path); } return(null); }
public VPathToHost GetApplicationForPath(string vhost, int port, string path, bool defaultToRoot) { if (SingleApplication) { return(vpathToHost [0]); } VPathToHost bestMatch = null; int bestMatchLength = 0; for (int i = vpathToHost.Count - 1; i >= 0; i--) { var v = vpathToHost [i]; int matchLength = v.vpath.Length; if (matchLength <= bestMatchLength || !v.Match(vhost, port, path)) { continue; } bestMatchLength = matchLength; bestMatch = v; } if (bestMatch != null) { lock (bestMatch) { if (bestMatch.AppHost == null) { bestMatch.CreateHost(this, webSource); } } return(bestMatch); } if (defaultToRoot) { return(GetApplicationForPath(vhost, port, "/", false)); } if (Verbose) Logger.Write(LogLevel.Error, "No application defined for: {0}:{1}{2}", vhost, port, path); }
private VPathToHost GetApplicationForPath_existing(string vhost, int vport, string vpath) { VPathToHost bestMatch = null; int bestMatchLength = 0; // Checks for the matching vhost with the longest name. // For example, if the request is for // "/foo/bar/test.aspx", and hosts exist for "/", "/foo/", // "/foo/bar/", "/foo/bar/" should be used. for (int i = vpathToHost.Count - 1; i > -1; i--) { VPathToHost v = (VPathToHost)vpathToHost [i]; int matchLength = v.vpath.Length; if (matchLength <= bestMatchLength || !v.Match(vhost, vport, vpath)) { continue; } bestMatchLength = matchLength; bestMatch = v; } // Create the host and return the best match, if found. if (bestMatch != null) { CreateHost(bestMatch); return(bestMatch); } if (verbose) { Console.WriteLine( "No application defined for: {0}:{1}{2}", vhost, vport, vpath); } return(null); }
void InnerRun(object state) { requestId = -1; broker = null; RequestReader rr = new RequestReader(client); if (rr.ShuttingDown) { Close(); server.Stop(); return; } string vhost = rr.Request.GetRequestHeader("Host"); int port = -1; if (vhost != null) { int colon = vhost.IndexOf(':'); if (colon != -1) { port = Int32.Parse(vhost.Substring(colon + 1)); vhost = vhost.Substring(0, colon); } else { port = 80; } } string vServerName = rr.Request.GetVirtualServerName(); if (vServerName == null) { vServerName = vhost; } VPathToHost vapp = null; string vpath = rr.GetUriPath(); string path = rr.GetPhysicalPath(); if (path == null) { vapp = server.GetApplicationForPath(vServerName, port, vpath, false); } else { vapp = GetOrCreateApplication(vServerName, port, path, vpath); } if (vapp == null) { rr.NotFound(); Stream.Close(); Stream = null; return; } ModMonoApplicationHost host = (ModMonoApplicationHost)vapp.AppHost; if (host == null) { rr.NotFound(); Stream.Close(); Stream = null; return; } modRequest = rr.Request; if (!server.SingleApplication) { broker = (ModMonoRequestBroker)vapp.RequestBroker; broker.UnregisterRequestEvent += new UnregisterRequestEventHandler(OnUnregisterRequest); requestId = broker.RegisterRequest(this); } host.ProcessRequest(requestId, modRequest.GetHttpVerbName(), modRequest.GetQueryString(), modRequest.GetUri(), modRequest.GetProtocol(), modRequest.GetLocalAddress(), modRequest.GetServerPort(), modRequest.GetRemoteAddress(), modRequest.GetRemotePort(), modRequest.GetRemoteName(), modRequest.GetAllHeaders(), modRequest.GetAllHeaderValues(), (requestId == -1) ? this : null); }
private VPathToHost GetApplicationForPath_mapping(string vhost, int vport, string vpath, string realPath) { // If we can't automap, abort. if (!auto_map || realPath == null) { return(null); } #if NET_2_0 List <VPathToHost> hosts = new List <VPathToHost> (vpathToHost); #else ArrayList hosts = new ArrayList(vpathToHost); #endif char sep = Path.DirectorySeparatorChar; string [] parts = vpath.Split('/'); int length = parts.Length; DirectoryInfo dir = new DirectoryInfo(realPath); while (true) { // Remove any extra blank parts from the path. while (length > 0 && parts [length - 1].Length == 0) { length--; } // If we run out of directories, there is // nothing left to map. if (dir == null || length < 0) { return(null); } // We can't map to a non-existent directory. If // we find one, move up a level and try again. if (!dir.Exists) { length--; dir = dir.Parent; continue; } // Get the directory name with the trailing // slash. realPath = dir.FullName; if (realPath [realPath.Length - 1] != sep) { realPath += sep; } // Search through existing hosts. If their real // path is longer than our real path, we have an // application we can't use. If their path is // the same as ours, return that host. for (int i = hosts.Count - 1; i > 0; i--) { #if NET_2_0 VPathToHost h = hosts [i]; #else VPathToHost h = hosts [i] as VPathToHost; #endif if (!h.realPath.StartsWith(realPath)) { hosts.RemoveAt(i); } else if (realPath == h.realPath) { CreateHost(h); return(h); } } // If the paths differ, we've reached the end of // the map and must escape so it can be built. if (length == 0 || !parts [length - 1].Equals( dir.Name)) { break; } // Check that if the directory contains both a // "Web.Config" file and a "Bin" directory. If // so, it is most likely an application. bool webConfigFound = false; bool binFound = false; foreach (DirectoryInfo info in dir.GetDirectories()) #if NET_2_0 { if (info.Name.Equals("bin", StringComparison.InvariantCultureIgnoreCase)) { #else { if (info.Name.ToLower() == "bin") { #endif binFound = true; break; } } foreach (FileInfo info in dir.GetFiles()) #if NET_2_0 if (info.Name.Equals("web.config", StringComparison.InvariantCultureIgnoreCase)) { #else if (info.Name.ToLower() == "Web.Config") { #endif webConfigFound = true; break; } } if (binFound && webConfigFound) { break; } // Move up a level and try again. length--; dir = dir.Parent; } // We must now have a valid directory and path. string vPath = string.Join("/", parts, 0, length) + "/"; // For now, don't care about host or port. It is safe to // assume that if two hosts have an identical root // directory, they are the same application. lock (vpathToHost) { AddApplication(null, -1, vPath, realPath); VPathToHost host = vpathToHost [ vpathToHost.Count - 1] as VPathToHost; CreateHost(host); return(host); } }