コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
            }
        }
コード例 #5
0
 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;
         }
     }
 }
コード例 #6
0
 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);
             }
         }
     }
 }
コード例 #7
0
        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);
        }
コード例 #8
0
        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); }
コード例 #9
0
        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);
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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);
            }
        }