using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Rewrite; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using StardewModdingAPI.Web.Framework; using StardewModdingAPI.Web.Framework.ConfigModels; namespace StardewModdingAPI.Web { /// The web app startup configuration. internal class Startup { /********* ** Accessors *********/ /// The web app configuration. public IConfigurationRoot Configuration { get; } /********* ** Public methods *********/ /// Construct an instance. /// The hosting environment. public Startup(IHostingEnvironment env) { this.Configuration = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddEnvironmentVariables() .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables() .Build(); } /// The method called by the runtime to add services to the container. /// The service injection container. public void ConfigureServices(IServiceCollection services) { services .Configure(this.Configuration.GetSection("ModUpdateCheck")) .AddMemoryCache() .AddMvc() .ConfigureApplicationPartManager(manager => manager.FeatureProviders.Add(new InternalControllerFeatureProvider())) .AddJsonOptions(options => { options.SerializerSettings.Formatting = Formatting.Indented; options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; }); } /// The method called by the runtime to configure the HTTP request pipeline. /// The application builder. /// The hosting environment. /// The logger factory. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(this.Configuration.GetSection("Logging")); loggerFactory.AddDebug(); app .UseRewriter(new RewriteOptions().Add(new RewriteSubdomainRule())) // convert subdomain.smapi.io => smapi.io/subdomain for routing .UseMvc(route => { route.MapRoute( name: "API", template: "api/{version}/{controller}/{action?}", defaults: new { action = "GetAsync" }, constraints: new { // version regex from SMAPI's SemanticVersion implementation version = @"^v(?>(?0|[1-9]\d*))\.(?>(?0|[1-9]\d*))(?>(?:\.(?0|[1-9]\d*))?)(?:-(?(?>[a-z0-9]+[\-\.]?)+))?$" } ); }); } } }