Beispiel #1
0
        private void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }
            _disposed = true;
            if (disposing)
            {
                // shutdown the environment
                if (_env != null)
                {
                    try {
                        _env.Deinitialize();
                    } catch (Exception e) {
                        _log.ErrorExceptionMethodCall(e, "Destroy");
                    }
                }

                // stop transports
                if (_transports != null)
                {
                    foreach (Http.HttpTransport transport in _transports)
                    {
                        if (transport != null)
                        {
                            try {
                                transport.Shutdown();
                            } catch (Exception e) {
                                _log.ErrorExceptionMethodCall(e, "Destroy");
                            }
                        }
                    }
                    _transports.Clear();
                }
            }
            _host       = null;
            _env        = null;
            _transports = null;
        }
Beispiel #2
0
        /// <summary>
        /// Create a new host with provided configuration and an Inversion of Control container.
        /// </summary>
        /// <remarks>
        /// The IoC container is also injected into default activator, so that <see cref="IDreamService"/> instances
        /// can be resolved from the container. The host configuration is provided to the container as a typed parameter.
        /// </remarks>
        /// <param name="config">Host configuration.</param>
        /// <param name="container">IoC Container.</param>
        public DreamHost(XDoc config, IContainer container) {
            if(config == null) {
                throw new ArgumentNullException("config");
            }

            // read host settings
            string appDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName);
            int limit = config["connect-limit"].AsInt ?? 0;
            int httpPort = config["http-port"].AsInt ?? DEFAULT_PORT;
            AuthenticationSchemes authenticationScheme = AuthenticationSchemes.Anonymous;
            string authShemes = config["authentication-shemes"].AsText;
            if(!String.IsNullOrEmpty(authShemes)) {
                try {
                    authenticationScheme = (AuthenticationSchemes)Enum.Parse(typeof(AuthenticationSchemes), authShemes, true);
                } catch(Exception e) {
                    _log.Warn(String.Format("invalid authetication scheme specified :{0}", authShemes), e);
                }
            }

            // get the authtoken for whitelisting dream.in.* query args
            _dreamInParamAuthtoken = config["dream.in.authtoken"].AsText;
            if(!string.IsNullOrEmpty(_dreamInParamAuthtoken)) {
                _log.Debug("Host is configured in dream.in param authorizing mode");
            }

            // read ip-addresses
            var addresses = new List<string>();
            foreach(XDoc ip in config["host|ip"]) {
                addresses.Add(ip.AsText);
            }
            if(addresses.Count == 0) {

                // if no addresses were supplied listen to all
                addresses.Add("*:" + httpPort);
            }

            // use default servername
            XUri publicUri = config["uri.public"].AsUri;
            if(publicUri == null) {

                // backwards compatibility
                publicUri = config["server-name"].AsUri;
                if(publicUri == null) {
                    foreach(IPAddress addr in Dns.GetHostAddresses(Dns.GetHostName())) {
                        if(addr.AddressFamily == AddressFamily.InterNetwork) {
                            XUri.TryParse("http://" + addr, out publicUri);
                        }
                    }
                    if(publicUri == null) {
                        // failed to get an address out of dns, fall back to localhost
                        XUri.TryParse("http://localhost", out publicUri);
                    }
                }
                publicUri = publicUri.AtPath(config["server-path"].AsText ?? config["path-prefix"].AsText ?? string.Empty);
            }

            // create environment and initialize it
            _env = new DreamHostService(container);
            try {

                // initialize environment
                string apikey = config["apikey"].AsText ?? StringUtil.CreateAlphaNumericKey(32);
                XDoc serviceConfig = new XDoc("config");
                var storageType = config["storage/@type"].AsText ?? "local";
                if("s3".EqualsInvariant(storageType)) {
                    serviceConfig.Add(config["storage"]);
                } else {
                    serviceConfig.Elem("storage-dir", config["storage-dir"].AsText ?? config["service-dir"].AsText ?? appDirectory);
                }
                serviceConfig.Elem("apikey", apikey);
                serviceConfig.Elem("uri.public", publicUri);
                serviceConfig.Elem("connect-limit", limit);
                serviceConfig.Elem("guid", config["guid"].AsText);
                serviceConfig.AddAll(config["components"]);
                var memorize = config["memorize-aliases"];
                if(!memorize.IsEmpty) {
                    serviceConfig.Elem("memorize-aliases", memorize.AsBool);
                }
                _env.Initialize(serviceConfig);

                // initialize host plug
                _host = _env.Self.With("apikey", apikey);

                // load assemblies in 'services' folder
                string servicesFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "services");
                if(Directory.Exists(servicesFolder)) {

                    // Note (arnec): Deprecated, but the suggested alternative really doesn't apply since we don't want to
                    // load services into a separate appdomain.
#pragma warning disable 618,612
                    AppDomain.CurrentDomain.AppendPrivatePath("services");
#pragma warning restore 618,612
                    foreach(string file in Directory.GetFiles(servicesFolder, "*.dll")) {

                        // register assembly blueprints
                        DreamMessage response = _host.At("load").With("name", Path.GetFileNameWithoutExtension(file)).Post(new Result<DreamMessage>(TimeSpan.MaxValue)).Wait();
                        if(!response.IsSuccessful) {
                            _log.WarnFormat("DreamHost: ERROR: assembly '{0}' failed to load", file);
                        }
                    }
                }

                // add acccess-points
                AddListener(new XUri(String.Format("http://{0}:{1}/", "localhost", httpPort)), authenticationScheme);

                // check if user prescribed a set of IP addresses to use
                if(addresses != null) {

                    // listen to custom addresses (don't use the supplied port info, we expect that to be part of the address)
                    foreach(string address in addresses) {
                        if(!StringUtil.EqualsInvariantIgnoreCase(address, "localhost")) {
                            AddListener(new XUri(String.Format("http://{0}/", address)), authenticationScheme);
                        }
                    }
                } else {

                    // add listeners for all known IP addresses
                    foreach(IPAddress address in Dns.GetHostAddresses(Dns.GetHostName())) {
                        XUri uri = MakeUri(address, httpPort);
                        if(uri != null) {
                            AddListener(uri, authenticationScheme);
                            try {
                                foreach(string alias in Dns.GetHostEntry(address).Aliases) {
                                    AddListener(new XUri(String.Format("http://{0}:{1}/", alias, httpPort)), authenticationScheme);
                                }
                            } catch { }
                        }
                    }
                }
            } catch(Exception e) {
                if((e is HttpListenerException) && e.Message.EqualsInvariant("Access is denied")) {
                    _log.ErrorExceptionMethodCall(e, "ctor", "insufficient privileges to create HttpListener, make sure the application runs with Administrator rights");
                } else {
                    _log.ErrorExceptionMethodCall(e, "ctor");
                }
                try {
                    _env.Deinitialize();
                } catch { }
                throw;
            }
        }
Beispiel #3
0
        /// <summary>
        /// Create a new host with provided configuration and an Inversion of Control container.
        /// </summary>
        /// <remarks>
        /// The IoC container is also injected into default activator, so that <see cref="IDreamService"/> instances
        /// can be resolved from the container. The host configuration is provided to the container as a typed parameter.
        /// </remarks>
        /// <param name="config">Host configuration.</param>
        /// <param name="container">IoC Container.</param>
        public DreamHost(XDoc config, IContainer container)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            // read host settings
            string appDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName);
            int    limit        = config["connect-limit"].AsInt ?? 0;
            int    httpPort     = config["http-port"].AsInt ?? DEFAULT_PORT;
            AuthenticationSchemes authenticationScheme = AuthenticationSchemes.Anonymous;
            string authShemes = config["authentication-shemes"].AsText;

            if (!String.IsNullOrEmpty(authShemes))
            {
                try {
                    authenticationScheme = (AuthenticationSchemes)Enum.Parse(typeof(AuthenticationSchemes), authShemes, true);
                } catch (Exception e) {
                    _log.Warn(String.Format("invalid authetication scheme specified :{0}", authShemes), e);
                }
            }

            // get the authtoken for whitelisting dream.in.* query args
            _dreamInParamAuthtoken = config["dream.in.authtoken"].AsText;
            if (!string.IsNullOrEmpty(_dreamInParamAuthtoken))
            {
                _log.Debug("Host is configured in dream.in param authorizing mode");
            }

            // read ip-addresses
            var addresses = new List <string>();

            foreach (XDoc ip in config["host|ip"])
            {
                addresses.Add(ip.AsText);
            }
            if (addresses.Count == 0)
            {
                // if no addresses were supplied listen to all
                addresses.Add("*:" + httpPort);
            }

            // use default servername
            XUri publicUri = config["uri.public"].AsUri;

            if (publicUri == null)
            {
                // backwards compatibility
                publicUri = config["server-name"].AsUri;
                if (publicUri == null)
                {
                    foreach (IPAddress addr in Dns.GetHostAddresses(Dns.GetHostName()))
                    {
                        if (addr.AddressFamily == AddressFamily.InterNetwork)
                        {
                            XUri.TryParse("http://" + addr, out publicUri);
                        }
                    }
                    if (publicUri == null)
                    {
                        // failed to get an address out of dns, fall back to localhost
                        XUri.TryParse("http://localhost", out publicUri);
                    }
                }
                publicUri = publicUri.AtPath(config["server-path"].AsText ?? config["path-prefix"].AsText ?? string.Empty);
            }

            // create environment and initialize it
            _env = new DreamHostService(container);
            try {
                // initialize environment
                string apikey        = config["apikey"].AsText ?? StringUtil.CreateAlphaNumericKey(32);
                XDoc   serviceConfig = new XDoc("config");
                var    storageType   = config["storage/@type"].AsText ?? "local";
                if ("s3".EqualsInvariant(storageType))
                {
                    serviceConfig.Add(config["storage"]);
                }
                else
                {
                    serviceConfig.Elem("storage-dir", config["storage-dir"].AsText ?? config["service-dir"].AsText ?? appDirectory);
                }
                serviceConfig.Elem("apikey", apikey);
                serviceConfig.Elem("uri.public", publicUri);
                serviceConfig.Elem("connect-limit", limit);
                serviceConfig.Elem("guid", config["guid"].AsText);
                serviceConfig.AddAll(config["components"]);
                var memorize = config["memorize-aliases"];
                if (!memorize.IsEmpty)
                {
                    serviceConfig.Elem("memorize-aliases", memorize.AsBool);
                }
                _env.Initialize(serviceConfig);

                // initialize host plug
                _host = _env.Self.With("apikey", apikey);

                // load assemblies in 'services' folder
                string servicesFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "services");
                if (Directory.Exists(servicesFolder))
                {
                    // Note (arnec): Deprecated, but the suggested alternative really doesn't apply since we don't want to
                    // load services into a separate appdomain.
#pragma warning disable 618,612
                    AppDomain.CurrentDomain.AppendPrivatePath("services");
#pragma warning restore 618,612
                    foreach (string file in Directory.GetFiles(servicesFolder, "*.dll"))
                    {
                        // register assembly blueprints
                        DreamMessage response = _host.At("load").With("name", Path.GetFileNameWithoutExtension(file)).Post(new Result <DreamMessage>(TimeSpan.MaxValue)).Wait();
                        if (!response.IsSuccessful)
                        {
                            _log.WarnFormat("DreamHost: ERROR: assembly '{0}' failed to load", file);
                        }
                    }
                }

                // add acccess-points
                AddListener(new XUri(String.Format("http://{0}:{1}/", "localhost", httpPort)), authenticationScheme);

                // check if user prescribed a set of IP addresses to use
                if (addresses != null)
                {
                    // listen to custom addresses (don't use the supplied port info, we expect that to be part of the address)
                    foreach (string address in addresses)
                    {
                        if (!StringUtil.EqualsInvariantIgnoreCase(address, "localhost"))
                        {
                            AddListener(new XUri(String.Format("http://{0}/", address)), authenticationScheme);
                        }
                    }
                }
                else
                {
                    // add listeners for all known IP addresses
                    foreach (IPAddress address in Dns.GetHostAddresses(Dns.GetHostName()))
                    {
                        XUri uri = MakeUri(address, httpPort);
                        if (uri != null)
                        {
                            AddListener(uri, authenticationScheme);
                            try {
                                foreach (string alias in Dns.GetHostEntry(address).Aliases)
                                {
                                    AddListener(new XUri(String.Format("http://{0}:{1}/", alias, httpPort)), authenticationScheme);
                                }
                            } catch { }
                        }
                    }
                }
            } catch (Exception e) {
                if ((e is HttpListenerException) && e.Message.EqualsInvariant("Access is denied"))
                {
                    _log.ErrorExceptionMethodCall(e, "ctor", "insufficient privileges to create HttpListener, make sure the application runs with Administrator rights");
                }
                else
                {
                    _log.ErrorExceptionMethodCall(e, "ctor");
                }
                try {
                    _env.Deinitialize();
                } catch { }
                throw;
            }
        }