예제 #1
0
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (false && env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler(configure =>
                {
                    configure.Run(async context =>
                    {
                        context.Response.StatusCode          = (int)HttpStatusCode.InternalServerError;
                        context.Response.ContentType         = "text/plain";
                        IExceptionHandlerPathFeature feature = context.Features.Get <IExceptionHandlerPathFeature>();
                        Exception exception = feature?.Error;

                        if (exception != null)
                        {
                            await context.Response.WriteAsync("### Exception ###\n");
                            await context.Response.WriteAsync($"{nameof(Exception.Message)}:{exception.Message}\n");
                            await context.Response.WriteAsync($"{nameof(Exception.Source)}:{exception.Source}\n");
                            await context.Response.WriteAsync($"{nameof(Exception.StackTrace)}\n{exception.StackTrace}");
                            while (exception.InnerException != null)
                            {
                                exception = exception.InnerException;
                                await context.Response.WriteAsync("\n### InnerException ###\n");
                                await context.Response.WriteAsync($"{nameof(Exception.Message)}:{exception.Message}\n");
                                await context.Response.WriteAsync($"{nameof(Exception.Source)}:{exception.Source}");
                            }
                        }
                    });
                });
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.Map("/{**action}", async context =>
                {
                    string action = context.Request.Path;

                    if (string.IsNullOrEmpty(action))
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                        context.Response.Headers.Add(X_ERROR_MESSAGE, nameof(action));
                        return;
                    }

                    if ('\\' == Path.DirectorySeparatorChar)
                    {
                        action = action.Replace('/', Path.DirectorySeparatorChar);
                    }

                    if (action.StartsWith(Path.DirectorySeparatorChar))
                    {
                        action = action.Remove(0, 1);
                    }

                    action = Path.Combine(AppContext.BaseDirectory, "actions", $"{action}.xml");

                    if (!File.Exists(action))
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                        context.Response.Headers.Add(X_ERROR_MESSAGE, action);
                        return;
                    }

                    XmlDocument xml = new XmlDocument();
                    xml.Load(action);

                    XmlNode root = xml.SelectSingleNode("actions");

                    if (root?.HasChildNodes != true)
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                        context.Response.Headers.Add(X_ERROR_MESSAGE, action);
                        return;
                    }

                    object data = null;

                    foreach (XmlNode act in root.ChildNodes)
                    {
                        string plugin = act.Attributes[nameof(plugin)]?.Value;
                        if (string.IsNullOrEmpty(plugin))
                        {
                            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                            context.Response.Headers.Add(X_ERROR_MESSAGE, nameof(plugin));
                            return;
                        }

                        string invoke = act.Attributes[nameof(invoke)]?.Value;
                        if (string.IsNullOrEmpty(invoke))
                        {
                            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                            context.Response.Headers.Add(X_ERROR_MESSAGE, nameof(invoke));
                            return;
                        }

                        if (!plugin.StartsWith(IPlugin.NAMESPACE))
                        {
                            plugin = $"{IPlugin.NAMESPACE}.{plugin}";
                        }

                        string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins", plugin, $"{plugin}.dll");

                        if (!File.Exists(file))
                        {
                            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                            context.Response.Headers.Add(X_ERROR_MESSAGE, file);
                            return;
                        }

                        PluginLoadContext loader = new PluginLoadContext(file);
                        Assembly assembly        = loader.LoadFromAssemblyName(new AssemblyName(plugin));

                        if (assembly == null)
                        {
                            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                            context.Response.Headers.Add(X_ERROR_MESSAGE, plugin);
                            return;
                        }


                        invoke = $"{plugin}.{invoke}";

                        IPlugin instance = assembly.CreateInstance(invoke) as IPlugin;

                        if (instance == null)
                        {
                            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                            context.Response.Headers.Add(X_ERROR_MESSAGE, invoke);
                            return;
                        }

                        int result = await instance.ExecuteAsync(context, act, data, x => { data = x; }).ConfigureAwait(true);

                        loader?.Unload();

                        if (result != 0)
                        {
                            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                            context.Response.Headers.Add(X_ERROR_MESSAGE, $"{invoke}:{result}");
                            return;
                        }
                    }
                    ;
                });
            });
        }