Example #1
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory, IWebHostEnvironment hostingEnvironment)
        {
            // Log hosting environment
            {
                ILogger logger = loggerFactory.CreateLogger("Startup");
                logger.LogInformation("Using content root: {0}", hostingEnvironment.ContentRootPath);
                logger.LogInformation("Using web root: {0}", hostingEnvironment.WebRootPath);
            }

            // Startup checks
            if (!app.RunStartupChecks())
            {
                return;
            }

            // HTTP pipeline configuration
            app.UseHttps();
            app.UseMiddleware <SiteUrlDetectionService.Middleware>();

            app.UseRouting();
            app.UseAuthentication();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();

                app.UseWhen(
                    ctx => ctx.Request.Path.StartsWithSegments("/build") ||
                    ctx.Request.Path.StartsWithSegments("/sw-es5.js") ||
                    ctx.Request.Path.StartsWithSegments("/sw-es2017.js") ||
                    ctx.Request.Path.StartsWithSegments("/__webpack_hmr"),
                    spaApp => {
                    spaApp.UseSpa(spa => {
                        const int port = 8080;

                        Process.Start(new ProcessStartInfo {
                            FileName         = "node.exe",
                            Arguments        = $"dev-server.js --port={port}",
                            WorkingDirectory = hostingEnvironment.ContentRootPath,
                            UseShellExecute  = true,
                            WindowStyle      = ProcessWindowStyle.Minimized
                        });

                        spa.UseProxyToSpaDevelopmentServer($"http://localhost:{port}/");
                    });
                }
                    );
            }
            else
            {
                app.UseExceptionHandler("/");
            }

            app.UseResponseCompression();

            app.UseSimpleUrlRemap("/browserconfig.xml", "/images/tiles/manifest-microsoft.xml");
            app.UseSimpleUrlRemap("/sw-es5.js", "/build/es5/sw-es5.js");
            app.UseSimpleUrlRemap("/sw-es2017.js", "/build/es2017/sw-es2017.js");

            app.AddWildcardPatternRewrite("/build");

            app.UseStaticFiles(new StaticFileOptions {
                ContentTypeProvider = new FileExtensionContentTypeProvider {
                    // TODO: Remove when https://github.com/aspnet/AspNetCore/issues/2442 is done
                    Mappings = { [".webmanifest"] = "application/manifest+json" }
                },
                OnPrepareResponse = context => {
                    // Enable aggressive caching behavior - but be sure that requests from service workers must be properly addressed
                    const int expireTimeInDays = 7 * 4;

                    ResponseHeaders headers = context.Context.Response.GetTypedHeaders();
                    headers.Expires         = DateTimeOffset.Now.AddDays(expireTimeInDays);
                    headers.CacheControl    = new CacheControlHeaderValue {
                        MaxAge         = TimeSpan.FromDays(expireTimeInDays),
                        MustRevalidate = true,
                        Public         = true,
                        MaxStale       = true,
                        MaxStaleLimit  = TimeSpan.FromSeconds(5)
                    };
                }
            });

            // Let's encrypt support
            app.UseRouter(r => {
                r.MapGet(".well-known/acme-challenge/{id}", async(request, response, routeData) => {
                    string id = routeData.Values["id"] as string;
                    if (id != Path.GetFileName(id))
                    {
                        return; // Prevent injection attack
                    }

                    string file = Path.Combine(env.WebRootPath, ".well-known", "acme-challenge", id);
                    await response.SendFileAsync(file);
                });
            });

            // Hangfire
            app.UseHangfireServer();
            app.UseHangfireDashboard("/_internal/jobs", new DashboardOptions {
                AppPath = "/",
                DisplayStorageConnectionString = false,
                Authorization = new IDashboardAuthorizationFilter[] {
                    new DiagnosticsHangfireDashboardAuthorizationFilter(),
                }
            });

            // SPA bootstrapper
            app.UseEndpoints(endpoints => {
                // SignalR hub
                endpoints.MapHub <AppOwnerHub>("/extern/connect/app-owner");

                // MVC api controllers
                endpoints.MapControllers();

                // If we still reached this at this point the ko-template was not found:
                // Trigger an failure instead of sending the app bootstrapper which causes all kinds of havoc.
                endpoints.MapFailedRoute("ko-templates/{*.}");
                endpoints.MapFailedRoute("build/{*.}");

                // Any non-matched web api calls should fail as well
                endpoints.MapFailedRoute("api/{*.}");

                // We only match one controller since we will want
                // all requests to go to the controller which renders
                // the initial view / SPA bootstrapper.
                endpoints.MapFallbackToController("{*.}", "Index", "Home");
            });

            // Configure recurring jobs
            AppInsightsJobFilterAttribute.Register(app.ApplicationServices.GetService <TelemetryClient>());
            RecurringJob.AddOrUpdate <MonthlyDigestInvocationJob>(x => x.Execute(), Cron.Daily(10));
        }
Example #2
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IHostingEnvironment hostingEnvironment)
        {
            // Log hosting environment
            {
                ILogger logger = loggerFactory.CreateLogger("Startup");
                logger.LogInformation("Using content root: {0}", hostingEnvironment.ContentRootPath);
                logger.LogInformation("Using web root: {0}", hostingEnvironment.WebRootPath);
            }

            // Startup checks
            if (!app.RunStartupChecks())
            {
                return;
            }

            // HTTP pipeline configuration
            app.UseHttps();
            app.UseMiddleware <SiteUrlDetectionService.Middleware>();

            app.UseAuthentication();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
                {
                    HotModuleReplacement = true
                });
            }
            else
            {
                app.UseExceptionHandler("/");
            }

            app.UseSignalR(builder =>
            {
                builder.MapHub <AppOwnerHub>("/extern/connect/app-owner");
            });

            app.UseResponseCompression();

            app.UseSimpleUrlRemap("/browserconfig.xml", "/images/tiles/manifest-microsoft.xml");
            app.UseSimpleUrlRemap("/sw-es5.js", "/build/es5/sw-es5.js");
            app.UseSimpleUrlRemap("/sw-es2017.js", "/build/es2017/sw-es2017.js");

            app.AddWildcardPatternRewrite("/build");

            app.UseStaticFiles(new StaticFileOptions
            {
                ContentTypeProvider = new FileExtensionContentTypeProvider
                {
                    Mappings = { [".webmanifest"] = "application/manifest+json" }
                },
                OnPrepareResponse = context =>
                {
                    // Enable aggressive caching behavior - but be sure that requests from service workers must be properly addressed
                    const int expireTimeInDays = 7 * 4;

                    ResponseHeaders headers = context.Context.Response.GetTypedHeaders();
                    headers.Expires         = DateTimeOffset.Now.AddDays(expireTimeInDays);
                    headers.CacheControl    = new CacheControlHeaderValue
                    {
                        MaxAge         = TimeSpan.FromDays(expireTimeInDays),
                        MustRevalidate = true,
                        Public         = true,
                        MaxStale       = true,
                        MaxStaleLimit  = TimeSpan.FromSeconds(5)
                    };
                }
            });

            // Let's encrypt support
            app.UseRouter(r =>
            {
                r.MapGet(".well-known/acme-challenge/{id}", async(request, response, routeData) =>
                {
                    string id = routeData.Values["id"] as string;
                    if (id != Path.GetFileName(id))
                    {
                        return; // Prevent injection attack
                    }

                    string file = Path.Combine(env.WebRootPath, ".well-known", "acme-challenge", id);
                    await response.SendFileAsync(file);
                });
            });

            // Hangfire
            app.UseHangfireServer();
            app.UseHangfireDashboard("/_internal/jobs", new DashboardOptions
            {
                AppPath = "/",
                DisplayStorageConnectionString = false,
                Authorization = new IDashboardAuthorizationFilter[] {
                    new DiagnosticsHangfireDashboardAuthorizationFilter(),
                }
            });

            // SPA bootstrapper
            app.UseMvc(routes =>
            {
                // If we still reached this at this point the ko-template was not found:
                // Trigger an failure instead of sending the app bootstrapper which causes all kinds of havoc.
                routes.MapFailedRoute("ko-templates/{*.}");
                routes.MapFailedRoute("build/{*.}");

                // Any non-matched web api calls should fail as well
                routes.MapFailedRoute("api/{*.}");

                // We only match one controller since we will want
                // all requests to go to the controller which renders
                // the initial view / SPA bootstrapper.
                routes.MapRoute(
                    name: "default",
                    template: "{*.}",
                    defaults: new
                {
                    controller = "Home",
                    action     = "Index"
                });
            });

            // Configure recurring jobs
            AppInsightsJobFilterAttribute.Register(app.ApplicationServices.GetService <TelemetryClient>());
            RecurringJob.AddOrUpdate <MonthlyDigestInvocationJob>(x => x.Execute(), Cron.Daily(10));
        }