Exemplo n.º 1
0
        /// <summary>
        /// Creates a server configuration from a CLI config instance
        /// </summary>
        /// <returns>The server configuration.</returns>
        /// <param name="config">The CLI config instance.</param>
        public static ServerConfig ValidateConfig(CLIServerConfiguration config)
        {
            var cfg = CreateServerConfig(config);

            // Set up the module context
            var ctx = LoaderContext.StartContext();

            cfg.LoaderContext = ctx;

            // Expose our configuration to allow modules to call back,
            // beware that these values should never be reported to the client
            // as there might be proxies in front which will make them useless
            // to clients not running on the local machine
            if (config.ListenHttp)
            {
                var parsedip = ParseUtil.ParseIPAddress(config.HttpAddress);
                var ip       = parsedip == IPAddress.Any ? "127.0.0.1" : parsedip.ToString();
                Environment.SetEnvironmentVariable("CEEN_SELF_HTTP_URL", "http://" + ip + ":" + config.HttpPort);
            }
            if (config.ListenHttps)
            {
                var parsedip = ParseUtil.ParseIPAddress(config.HttpsAddress);
                var ip       = parsedip == IPAddress.Any ? "127.0.0.1" : parsedip.ToString();
                Environment.SetEnvironmentVariable("CEEN_SELF_HTTPS_URL", "http://" + ip + ":" + config.HttpsPort);
            }

            if (config.AutoLoadAssemblies)
            {
                // Workaround for unittests not providing EntryAssembly
                var callingasm = Assembly.GetEntryAssembly();
                var callingdir = callingasm == null ? null : Path.GetDirectoryName(callingasm.Location);

                var paths = (config.Assemblypath ?? string.Empty)
                            .Split(new char[] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries)
                            .Union(new[] { config.Basepath, callingdir })
                            .Where(x => !string.IsNullOrWhiteSpace(x) && Directory.Exists(x))
                            .Distinct();

                foreach (var p in paths)
                {
                    foreach (var file in Directory.GetFiles(p, "*.*", SearchOption.TopDirectoryOnly))
                    {
                        if (file.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || file.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
                        {
                            try { Assembly.LoadFrom(file); }
                            catch { }
                        }
                    }
                }

                var ceenpath = Path.GetDirectoryName(typeof(CLIServerConfiguration).Assembly.Location);
                if (Directory.Exists(ceenpath))
                {
                    foreach (var dll in Directory.GetFiles(ceenpath, "Ceen.*.dll", SearchOption.TopDirectoryOnly))
                    {
                        try { Assembly.LoadFrom(dll); }
                        catch { }
                    }
                }
            }

            if (config.Loggers != null)
            {
                foreach (var logger in config.Loggers)
                {
                    var inst = CreateInstance(logger.Classname, logger.ConstructorArguments, typeof(ILogger));
                    if (logger.Options != null)
                    {
                        SetProperties(inst, logger.Options);
                    }

                    if (inst is IWithSetup mse)
                    {
                        mse.AfterConfigure();
                    }

                    cfg.AddLogger((ILogger)inst);
                }
            }

            if (config.Modules != null)
            {
                foreach (var module in config.Modules)
                {
                    object handler;
                    var    moduletype = ResolveType(module.Classname);
                    handler = CreateInstance(moduletype, module.ConstructorArguments, typeof(IModule));

                    if (module.Options != null)
                    {
                        SetProperties(handler, module.Options);
                    }

                    if (handler is IWithSetup mse)
                    {
                        mse.AfterConfigure();
                    }


                    cfg.AddModule((IModule)handler);
                }
            }

            if (config.PostProcessors != null)
            {
                foreach (var postProcessor in config.PostProcessors)
                {
                    var inst = CreateInstance(postProcessor.Classname, postProcessor.ConstructorArguments, typeof(IPostProcessor));
                    if (postProcessor.Options != null)
                    {
                        SetProperties(inst, postProcessor.Options);
                    }

                    if (inst is IWithSetup mse)
                    {
                        mse.AfterConfigure();
                    }

                    cfg.AddPostProcessor((IPostProcessor)inst);
                }
            }

            if (config.Routes != null)
            {
                Ceen.Mvc.ManualRoutingController wirecontroller       = null;
                Ceen.Mvc.ControllerRouterConfig  wirecontrollerconfig = null;

                foreach (var route in config.Routes)
                {
                    // If we have a wired controller, and a non-wire item
                    // add it now to ensure the order is maintained
                    if (wirecontroller != null && !(route is WiredRouteDefinition))
                    {
                        cfg.AddRoute(wirecontroller.ToRoute(wirecontrollerconfig));
                        wirecontroller = null;
                    }

                    // Check for wireups
                    if (route is WiredRouteDefinition wired)
                    {
                        // Make a new manual router, if none is present or if we add one
                        if (wirecontroller == null || (wired.RoutePrefix == null))
                        {
                            // Add any previous wireup to the routes
                            if (wirecontroller != null)
                            {
                                cfg.AddRoute(wirecontroller.ToRoute(wirecontrollerconfig));
                            }

                            wirecontrollerconfig = new Ceen.Mvc.ControllerRouterConfig();
                            if (route.Options != null)
                            {
                                SetProperties(wirecontrollerconfig, route.Options);
                            }
                            wirecontroller = new Ceen.Mvc.ManualRoutingController();
                        }

                        if (wired.Verbs == null)
                        {
                            var itemtype = ResolveType(wired.Classname);
                            wirecontroller.WireController(itemtype, wired.RoutePrefix, wirecontrollerconfig);
                        }
                        else
                        {
                            var ix         = wired.Classname.LastIndexOf('.');
                            var classname  = wired.Classname.Substring(0, ix);
                            var methodname = wired.Classname.Substring(ix + 1);

                            var itemtype      = ResolveType(classname);
                            var argumenttypes = wired.ConstructorArguments.Select(x => ResolveType(x)).ToArray();
                            if (argumenttypes.Any(x => x == null))
                            {
                                throw new Exception($"Cannot resolve type argument {argumenttypes.Select((a, b) => a == null ? wired.ConstructorArguments[b] : null).Where(x => x != null).First()}");
                            }

                            wirecontroller.Wire(itemtype, wired.Verbs + " " + wired.RoutePrefix, methodname, argumenttypes);
                        }
                    }
                    // Check if this is a module
                    else if (route.RoutePrefix != null)
                    {
                        object handler;
                        var    moduletype = ResolveType(route.Classname);
                        if (typeof(Ceen.Httpd.Handler.FileHandler).IsAssignableFrom(moduletype))
                        {
                            Func <IHttpRequest, string, string> mimehandler = null;
                            if (config.MimeTypes != null && config.MimeTypes.Count > 0)
                            {
                                string default_mimetype;
                                config.MimeTypes.TryGetValue("*", out default_mimetype);
                                if (string.IsNullOrWhiteSpace(default_mimetype))
                                {
                                    default_mimetype = null;
                                }

                                if (config.IgnoreDefaultMimeTypes)
                                {
                                    mimehandler = (req, mappedpath) =>
                                    {
                                        var    ext = Path.GetExtension(mappedpath).ToLowerInvariant();
                                        string mime;
                                        config.MimeTypes.TryGetValue(ext, out mime);
                                        if (default_mimetype != null && string.IsNullOrWhiteSpace(mime))
                                        {
                                            return(default_mimetype);
                                        }

                                        return(mime);
                                    };
                                }
                                else
                                {
                                    mimehandler = (req, mappedpath) =>
                                    {
                                        var    ext = Path.GetExtension(mappedpath).ToLowerInvariant();
                                        string mime;
                                        config.MimeTypes.TryGetValue(ext, out mime);
                                        if (!string.IsNullOrWhiteSpace(mime))
                                        {
                                            return(mime);
                                        }
                                        else if (default_mimetype != null && string.IsNullOrWhiteSpace(mime))
                                        {
                                            return(default_mimetype);
                                        }
                                        else
                                        {
                                            return(Ceen.Httpd.Handler.FileHandler.DefaultMimeTypes(mappedpath));
                                        }
                                    };
                                }
                            }
                            else if (config.IgnoreDefaultMimeTypes)
                            {
                                mimehandler = (req, path) => null;
                            }

                            handler = Activator.CreateInstance(
                                moduletype,
                                ExpandEnvironmentVariables(route.ConstructorArguments.First()),
                                mimehandler
                                );

                            if (config.IndexDocuments.Count != 0)
                            {
                                if (route.Options.ContainsKey(nameof(Handler.FileHandler.IndexDocuments)))
                                {
                                    throw new Exception($"Cannot use both the `Index` option and {nameof(Handler.FileHandler.IndexDocuments)} in the configuration for {moduletype.FullName}");
                                }
                                route.Options[nameof(Handler.FileHandler.IndexDocuments)] = string.Join(", ", config.IndexDocuments.Select(x => $"\"{x}\""));
                            }
                        }
                        else
                        {
                            handler = CreateInstance(moduletype, route.ConstructorArguments, typeof(IHttpModule));
                        }

                        if (route.Options != null)
                        {
                            SetProperties(handler, route.Options);
                        }

                        if (handler is IWithSetup mse)
                        {
                            mse.AfterConfigure();
                        }

                        if (string.IsNullOrWhiteSpace(route.RoutePrefix))
                        {
                            cfg.AddRoute((IHttpModule)handler);
                        }
                        else
                        {
                            cfg.AddRoute(route.RoutePrefix, (IHttpModule)handler);
                        }
                    }
                    // Otherwise it is automatic routing of an assembly
                    else
                    {
                        var assembly = Assembly.Load(route.Assembly);
                        if (assembly == null)
                        {
                            throw new Exception($"Failed to load assembly {route.Assembly}");
                        }

                        Type defaulttype = null;
                        if (!string.IsNullOrWhiteSpace(route.Classname))
                        {
                            defaulttype = assembly.GetType(route.Classname, false);
                            if (defaulttype == null)
                            {
                                throw new Exception($"Failed to find class {route.Classname} in {route.Assembly}");
                            }
                        }

                        var rt = new Ceen.Mvc.ControllerRouterConfig(defaulttype);
                        if (route.Options != null)
                        {
                            SetProperties(rt, route.Options);
                        }

                        cfg.AddRoute(new Ceen.Mvc.ControllerRouter(rt, assembly));
                    }
                }

                // If we have a wired controller, add it
                if (wirecontroller != null)
                {
                    cfg.AddRoute(wirecontroller.ToRoute(wirecontrollerconfig));
                }
            }

            ctx.Freeze();
            return(cfg);
        }
Exemplo n.º 2
0
 /// <summary>
 /// Creates a route instance for a manual routing controller
 /// </summary>
 /// <param name="self">The manual routing controller</param>
 /// <param name="config">The config to use</param>
 /// <returns>The controller</returns>
 public static Ceen.Mvc.ControllerRouter ToRoute(this Ceen.Mvc.ManualRoutingController self, Ceen.Mvc.ControllerRouterConfig config = null)
 => new Mvc.ControllerRouter(
     config ?? new Mvc.ControllerRouterConfig(),
     self
     );