コード例 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="T:Ceen.Httpd.Cli.UnixSpawn.SpawnedServer"/> class.
        /// </summary>
        /// <param name="usessl">If set to <c>true</c> usessl.</param>
        /// <param name="configfile">Configfile.</param>
        /// <param name="storage">Storage.</param>
        public SpawnedServer(bool usessl, string configfile, IStorageCreator storage)
        {
            var config = ConfigParser.ValidateConfig(ConfigParser.ParseTextFile(configfile));

            config.Storage = storage ?? new MemoryStorageCreator();

            try
            {
                m_pollhandler = new SockRock.KqueueHandler();
            }
            catch (Exception e1)
            {
                try
                {
                    m_pollhandler = new SockRock.EpollHandler();
                }
                catch (Exception e2)
                {
                    throw new PlatformNotSupportedException("Unable to create kqueue or epoll instance", new AggregateException(e1, e2));
                }
            }

            m_pollhandler.WaitForShutdownAsync.ContinueWith(x => {
                Program.ConsoleOutput("The poll handler crashed, stopping this instance");
                this.Stop(TimeSpan.FromSeconds(-5));
            }, TaskContinuationOptions.NotOnRanToCompletion);

            base.Setup(usessl, config);
        }
コード例 #2
0
        /// <summary>
        /// Creates a new indirect runner
        /// </summary>
        /// <param name="path">The path to the config file.</param>
        /// <param name="useSSL">If set to <c>true</c> use ssl.</param>
        /// <param name="storage">The storage interface to use.</param>
        /// <param name="token">A cancellation token to use.</param>
        public IndirectRunner(string path, bool useSSL, IStorageCreator storage, CancellationToken token)
        {
            m_path    = path;
            m_useSSL  = useSSL;
            m_storage = storage;
            m_token   = token;

            m_task = MonitorForRestartAsync();
        }
コード例 #3
0
        /// <summary>
        /// Creates a new indirect runner
        /// </summary>
        /// <param name="path">The path to the config file.</param>
        /// <param name="useSSL">If set to <c>true</c> use ssl.</param>
        /// <param name="storage">The storage interface to use.</param>
        /// <param name="token">A cancellation token to use.</param>
        public IndirectRunner(string path, bool useSSL, IStorageCreator storage, CancellationToken token)
        {
            m_path    = path;
            m_useSSL  = useSSL;
            m_storage = storage;
            m_token   = token;

            // Make sure we have an instance before continuing
            Instance = new SpawnRemoteInstance(m_path, m_useSSL, m_storage, m_token);

            m_task = MonitorForRestartAsync();
        }
コード例 #4
0
            /// <summary>
            /// Initializes a new instance of the <see cref="T:Ceen.Httpd.Cli.Runner.InProcessRunner"/> class.
            /// </summary>
            /// <param name="usessl">If set to <c>true</c> use ssl.</param>
            /// <param name="configfile">The config file.</param>
            /// <param name="storage">The storage to use</param>
            /// <param name="token">The cancellation token to use</param>
            public InProcessWrapper(bool usessl, string configfile, IStorageCreator storage, CancellationToken token)
            {
                var config = ConfigParser.ValidateConfig(ConfigParser.ParseTextFile(configfile));

                config.Storage = storage ?? new MemoryStorageCreator();

                base.Setup(usessl, config);

                if (token.CanBeCanceled)
                {
                    token.Register(() => this.Stop());
                }
            }
コード例 #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="T:Ceen.Httpd.Cli.UnixSpawn.SpawnedServer"/> class.
        /// </summary>
        /// <param name="usessl">If set to <c>true</c> usessl.</param>
        /// <param name="configfile">Configfile.</param>
        /// <param name="storage">Storage.</param>
        public SpawnedServer(bool usessl, string configfile, IStorageCreator storage)
        {
            //// Mono version
            //var safeSocketHandleType = Type.GetType("System.Net.Sockets.SafeSocketHandle");
            //var safeSocketHandleConstructor = safeSocketHandleType?.GetConstructor(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, null, new Type[] { typeof(IntPtr), typeof(bool) }, null);
            //var socketConstructorSafeSocketHandle = safeSocketHandleType == null ? null : typeof(System.Net.Sockets.Socket).GetConstructor(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, null, new Type[] { typeof(AddressFamily), typeof(SocketType), typeof(ProtocolType), safeSocketHandleType }, null);

            //// .Net Core version
            //var safeCloseSocketType = Type.GetType("System.Net.Sockets.SafeCloseSocket");
            //var safeCloseSocketConstructor = safeCloseSocketType?.GetMethod("CreateSocket", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static, null, new Type[] { typeof(IntPtr) }, null);
            //var socketConstructorSafeCloseSocket = safeCloseSocketType == null ? null : typeof(System.Net.Sockets.Socket).GetConstructor(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, null, new Type[] { safeCloseSocketType }, null);

            //if (safeSocketHandleConstructor != null && socketConstructorSafeSocketHandle != null)
            //    m_createSocket = (handle) => (Socket)Activator.CreateInstance(typeof(Socket), AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp, Activator.CreateInstance(safeSocketHandleType, new IntPtr(handle), false));
            //else if (safeCloseSocketConstructor != null && socketConstructorSafeCloseSocket != null)
            //    m_createSocket = (handle) => (Socket)Activator.CreateInstance(typeof(Socket), safeCloseSocketConstructor.Invoke(null, new object[] { new IntPtr(handle) }));
            //else
            //throw new Exception("Unable to find a method to create sockets from handles ....");

            var config = ConfigParser.ValidateConfig(ConfigParser.ParseTextFile(configfile));

            config.Storage = storage ?? new MemoryStorageCreator();

            try
            {
                m_pollhandler = new SockRock.KqueueHandler();
            }
            catch (Exception e1)
            {
                try
                {
                    m_pollhandler = new SockRock.EpollHandler();
                }
                catch (Exception e2)
                {
                    throw new PlatformNotSupportedException("Unable to create kqueue or epoll instance", new AggregateException(e1, e2));
                }
            }

            base.Setup(usessl, config);
        }
コード例 #6
0
            /// <summary>
            /// Setup this instance
            /// </summary>
            /// <param name="usessl">If set to <c>true</c> usessl.</param>
            /// <param name="path">Path to the configuration file.</param>
            /// <param name="storage">The storage instance or null.</param>
            public void SetupFromFile(bool usessl, string path, IStorageCreator storage)
            {
                var config = ConfigParser.ValidateConfig(ConfigParser.ParseTextFile(path));

                if (storage != null)
                {
                    // Inject a wrapper to support async via callbacks
                    if (System.AppDomain.CurrentDomain.IsDefaultAppDomain())
                    {
                        config.Storage = storage;
                    }
                    else
                    {
                        config.Storage = new StorageCreatorAccessor(storage);
                    }
                }
                else
                {
                    config.Storage = new MemoryStorageCreator();
                }

                base.Setup(usessl, config);
            }
コード例 #7
0
 protected override IWrappedRunner CreateRunner(string path, bool useSSL, IStorageCreator storage, CancellationToken token)
 {
     return(new InProcessWrapper(useSSL, path, storage, token));
 }
コード例 #8
0
 /// <summary>
 /// Setup this instance
 /// </summary>
 /// <param name="usessl">If set to <c>true</c> usessl.</param>
 /// <param name="configfile">Path to the configuration file</param>
 /// <param name="storage">The storage instance or null</param>
 public void SetupFromFile(bool usessl, string configfile, IStorageCreator storage)
 {
     m_setupFromFile.Invoke(m_wrapped, new object[] { usessl, configfile, storage });
 }
コード例 #9
0
ファイル: HttpContext.cs プロジェクト: hc4/ceenhttpd
 /// <summary>
 /// Initializes a new instance of the <see cref="T:Ceen.Httpd.HttpContext"/> class.
 /// </summary>
 /// <param name="request">The HTTP request.</param>
 /// <param name="response">The HTTP response.</param>
 /// <param name="storage">The storage instance</param>
 public HttpContext(HttpRequest request, HttpResponse response, IStorageCreator storage)
 {
     this.Request  = request;
     this.Response = response;
     this.Storage  = storage;
 }
コード例 #10
0
ファイル: SpawnRemoteInstance.cs プロジェクト: hc4/ceenhttpd
 /// <summary>
 /// Creates a new runner instance
 /// </summary>
 /// <returns>The runner instance.</returns>
 /// <param name="path">The path to the config file.</param>
 /// <param name="useSSL">If set to <c>true</c> use ssl.</param>
 /// <param name="storage">The storage interface to use.</param>
 /// <param name="token">A cancellation token to use.</param>
 protected override IWrappedRunner CreateRunner(string path, bool useSSL, IStorageCreator storage, CancellationToken token)
 {
     return(new SpawnRemoteInstance(path, useSSL, storage, token));
 }
コード例 #11
0
ファイル: SpawnRemoteInstance.cs プロジェクト: hc4/ceenhttpd
        /// <summary>
        /// Initializes a new instance of the <see cref="T:Ceen.Httpd.Cli.SubProcess.SpawnRemoteInstance"/> class.
        /// </summary>
        /// <param name="path">The path to the config file</param>
        /// <param name="usessl">If set to <c>true</c> use ssl.</param>
        public SpawnRemoteInstance(string path, bool usessl, IStorageCreator storage, CancellationToken token)
        {
            m_path    = path;
            m_useSSL  = usessl;
            m_storage = storage;

            var prefix = m_hiddenSocketPath ? "\0" : string.Empty;
            var sockid = string.Format("ceen-socket-{0}", new Random().Next().ToString("x8"));

            if (m_hiddenSocketPath)
            {
                m_socketpath = sockid;
            }
            else
            {
                var pathPrefix = Environment.GetEnvironmentVariable("CEEN_SOCKET_FOLDER");
                if (string.IsNullOrWhiteSpace(pathPrefix))
                {
                    pathPrefix = System.IO.Path.GetTempPath();
                }

                m_socketpath = System.IO.Path.GetFullPath(System.IO.Path.Combine(pathPrefix, sockid));
            }

            // Setup a socket server, start the child, and stop the server
            using ((SystemHelper.IsCurrentOSPosix && !m_hiddenSocketPath) ? new DeleteFilesHelper(m_socketpath, m_socketpath + "_fd") : null)
                using (var serveripcsocket = SystemHelper.IsCurrentOSPosix ? new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP) : null)
                    using (var serverfdsocket = SystemHelper.IsCurrentOSPosix ? new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP) : null)
                    {
                        if (SystemHelper.IsCurrentOSPosix)
                        {
                            serveripcsocket.Bind(new SockRock.UnixEndPoint(prefix + m_socketpath));
                            serveripcsocket.Listen(1);

                            serverfdsocket.Bind(new SockRock.UnixEndPoint(prefix + m_socketpath + "_fd"));
                            serverfdsocket.Listen(1);
                        }

                        // Launch the child process
                        m_proc = StartRemoteProcess();

                        // TODO: Consider some multiplexer to allow multiple outputs without mixing the contents
                        var tasks = Task.WhenAll(
                            m_proc.StandardOutput.BaseStream.CopyToAsync(Console.OpenStandardOutput()),
                            m_proc.StandardError.BaseStream.CopyToAsync(Console.OpenStandardError()),
                            Console.OpenStandardInput().CopyToAsync(m_proc.StandardInput.BaseStream)
                            );

                        if (SystemHelper.IsCurrentOSPosix)
                        {
                            var ct = new CancellationTokenSource();

                            // Prepare cancellation after 5 seconds
                            Task.Delay(5000, ct.Token).ContinueWith(_ =>
                            {
                                serveripcsocket.Dispose();
                                serverfdsocket.Dispose();
                            });

                            // Get the first connection
                            m_ipcSocket = serveripcsocket.Accept();
                            m_fdSocket  = serverfdsocket.Accept();

                            // Stop the timer
                            ct.Cancel();
                        }

                        //and then don't listen anymore
                    }


            var ipc = new InterProcessConnection(new NetworkStream(m_ipcSocket, true));

            m_peer = new RPCPeer(
                ipc,
                typeof(IStorageEntry),
                typeof(IStorageCreator)
                );

            // We pass these by reference
            m_peer.TypeSerializer.RegisterSerializationAction(typeof(IStorageEntry), SerializationAction.Reference);
            m_peer.TypeSerializer.RegisterSerializationAction(typeof(IStorageCreator), SerializationAction.Reference);

            // Set up special handling for serializing an endpoint instance
            m_peer.TypeSerializer.RegisterEndPointSerializers();
            m_peer.TypeSerializer.RegisterIPEndPointSerializers();

            m_main = Task.Run(async() => {
                try
                {
                    using (m_fdSocket)
                        using (m_ipcSocket)
                            await ipc.RunMainLoopAsync(false);
                }
                finally
                {
                    Program.DebugConsoleOutput("{0}: Finished main loop, no longer connected to: {1}", System.Diagnostics.Process.GetCurrentProcess().Id, m_proc.Id);
                    m_proc.WaitForExit((int)TimeSpan.FromMinutes(1).TotalMilliseconds);
                    if (!m_proc.HasExited)
                    {
                        m_proc.Kill();
                    }
                    Program.DebugConsoleOutput("{0}: Target now stopped: {1}", System.Diagnostics.Process.GetCurrentProcess().Id, m_proc.Id);
                }
            });

            if (token.CanBeCanceled)
            {
                token.Register(() => this.Stop());
            }

            // Register the storage item, since it is a different concrete class (i.e. not the interface)
            if (storage != null)
            {
                m_peer.TypeSerializer.RegisterSerializationAction(storage.GetType(), SerializationAction.Reference);
                m_peer.RegisterLocalObjectOnRemote(storage, typeof(IStorageCreator)).Wait();
            }

            m_peer.AddAutomaticProxy(typeof(SpawnedServer), typeof(ISpawnedServerProxy));
            m_proxy = m_peer.CreateAsync <ISpawnedServerProxy>(typeof(SpawnedServer), usessl, path, storage).Result;

            if (SystemHelper.IsCurrentOSPosix)
            {
                // Prepare the file descriptor socket
                m_fdSocketTypeSerializer = new TypeSerializer(false, false);
                SetupDescriptorSocket().Wait();
            }
        }
コード例 #12
0
 protected abstract IWrappedRunner CreateRunner(string path, bool useSSL, IStorageCreator storage, System.Threading.CancellationToken token);
コード例 #13
0
 public void AddStorage(IStorageCreator storage)
 {
     this.storage = storage;
 }