commit 7ddfc9cde4ca67b403d8c527f8fa8b77fbb4cee4 Author: Chris Ross Date: Thu Mar 13 10:57:15 2014 -0700 Initial import from Katana. diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..bdaa5ba982 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,50 @@ +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain + +*.jpg binary +*.png binary +*.gif binary + +*.cs text=auto diff=csharp +*.vb text=auto +*.resx text=auto +*.c text=auto +*.cpp text=auto +*.cxx text=auto +*.h text=auto +*.hxx text=auto +*.py text=auto +*.rb text=auto +*.java text=auto +*.html text=auto +*.htm text=auto +*.css text=auto +*.scss text=auto +*.sass text=auto +*.less text=auto +*.js text=auto +*.lisp text=auto +*.clj text=auto +*.sql text=auto +*.php text=auto +*.lua text=auto +*.m text=auto +*.asm text=auto +*.erl text=auto +*.fs text=auto +*.fsx text=auto +*.hs text=auto + +*.csproj text=auto +*.vbproj text=auto +*.fsproj text=auto +*.dbproj text=auto +*.sln text=auto eol=crlf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..8bc217058d --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +[Oo]bj/ +[Bb]in/ +TestResults/ +.nuget/ +_ReSharper.*/ +packages/ +artifacts/ +PublishProfiles/ +*.user +*.suo +*.cache +*.docstates +_ReSharper.* +nuget.exe +*net45.csproj +*k10.csproj +*.psess +*.vsp +*.pidb +*.userprefs +*DS_Store +*.ncrunchsolution +*.*sdf +*.ipch \ No newline at end of file diff --git a/DiagnosticsPages.sln b/DiagnosticsPages.sln new file mode 100644 index 0000000000..2865030cad --- /dev/null +++ b/DiagnosticsPages.sln @@ -0,0 +1,64 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.30203.2 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Diagnostics.net45", "src\Microsoft.AspNet.Diagnostics\Microsoft.AspNet.Diagnostics.net45.csproj", "{092C4ACA-9F4C-4EDB-8B92-8E9FDF49E74A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Diagnostics.k10", "src\Microsoft.AspNet.Diagnostics\Microsoft.AspNet.Diagnostics.k10.csproj", "{CBE6B125-407F-403E-9E95-4D0836DEE706}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{509A6F36-AD80-4A18-B5B1-717D38DFF29D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{ACAA0157-A8C4-4152-93DE-90CCDF304087}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WelcomePageSample.net45", "samples\WelcomePageSample\WelcomePageSample.net45.csproj", "{7385EBB2-36DD-4EF7-AF9E-3C4348991C64}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WelcomePageSample.k10", "samples\WelcomePageSample\WelcomePageSample.k10.csproj", "{E2B98257-E434-439E-B61F-A3576F18FD34}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ErrorPageSample.k10", "samples\ErrorPageSample\ErrorPageSample.k10.csproj", "{FA5E49FF-4715-4241-9829-6E720AE5AA1D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ErrorPageSample.net45", "samples\ErrorPageSample\ErrorPageSample.net45.csproj", "{1E44DE4A-BAB3-4383-B63F-63D8416AAC60}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {092C4ACA-9F4C-4EDB-8B92-8E9FDF49E74A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {092C4ACA-9F4C-4EDB-8B92-8E9FDF49E74A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {092C4ACA-9F4C-4EDB-8B92-8E9FDF49E74A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {092C4ACA-9F4C-4EDB-8B92-8E9FDF49E74A}.Release|Any CPU.Build.0 = Release|Any CPU + {CBE6B125-407F-403E-9E95-4D0836DEE706}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CBE6B125-407F-403E-9E95-4D0836DEE706}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CBE6B125-407F-403E-9E95-4D0836DEE706}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CBE6B125-407F-403E-9E95-4D0836DEE706}.Release|Any CPU.Build.0 = Release|Any CPU + {7385EBB2-36DD-4EF7-AF9E-3C4348991C64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7385EBB2-36DD-4EF7-AF9E-3C4348991C64}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7385EBB2-36DD-4EF7-AF9E-3C4348991C64}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7385EBB2-36DD-4EF7-AF9E-3C4348991C64}.Release|Any CPU.Build.0 = Release|Any CPU + {E2B98257-E434-439E-B61F-A3576F18FD34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E2B98257-E434-439E-B61F-A3576F18FD34}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E2B98257-E434-439E-B61F-A3576F18FD34}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E2B98257-E434-439E-B61F-A3576F18FD34}.Release|Any CPU.Build.0 = Release|Any CPU + {FA5E49FF-4715-4241-9829-6E720AE5AA1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA5E49FF-4715-4241-9829-6E720AE5AA1D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA5E49FF-4715-4241-9829-6E720AE5AA1D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA5E49FF-4715-4241-9829-6E720AE5AA1D}.Release|Any CPU.Build.0 = Release|Any CPU + {1E44DE4A-BAB3-4383-B63F-63D8416AAC60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1E44DE4A-BAB3-4383-B63F-63D8416AAC60}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1E44DE4A-BAB3-4383-B63F-63D8416AAC60}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1E44DE4A-BAB3-4383-B63F-63D8416AAC60}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {092C4ACA-9F4C-4EDB-8B92-8E9FDF49E74A} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D} + {CBE6B125-407F-403E-9E95-4D0836DEE706} = {509A6F36-AD80-4A18-B5B1-717D38DFF29D} + {7385EBB2-36DD-4EF7-AF9E-3C4348991C64} = {ACAA0157-A8C4-4152-93DE-90CCDF304087} + {E2B98257-E434-439E-B61F-A3576F18FD34} = {ACAA0157-A8C4-4152-93DE-90CCDF304087} + {FA5E49FF-4715-4241-9829-6E720AE5AA1D} = {ACAA0157-A8C4-4152-93DE-90CCDF304087} + {1E44DE4A-BAB3-4383-B63F-63D8416AAC60} = {ACAA0157-A8C4-4152-93DE-90CCDF304087} + EndGlobalSection +EndGlobal diff --git a/NuGet.Config b/NuGet.Config new file mode 100644 index 0000000000..a059188b09 --- /dev/null +++ b/NuGet.Config @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/build.cmd b/build.cmd new file mode 100644 index 0000000000..7045ee1f84 --- /dev/null +++ b/build.cmd @@ -0,0 +1,23 @@ +@echo off +cd %~dp0 + +SETLOCAL +SET CACHED_NUGET=%LocalAppData%\NuGet\NuGet.exe + +IF EXIST %CACHED_NUGET% goto copynuget +echo Downloading latest version of NuGet.exe... +IF NOT EXIST %LocalAppData%\NuGet md %LocalAppData%\NuGet +@powershell -NoProfile -ExecutionPolicy unrestricted -Command "$ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest 'https://www.nuget.org/nuget.exe' -OutFile '%CACHED_NUGET%'" + +:copynuget +IF EXIST .nuget\nuget.exe goto restore +md .nuget +copy %CACHED_NUGET% .nuget\nuget.exe > nul + +:restore +IF EXIST packages\KoreBuild goto run +.nuget\NuGet.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre +.nuget\NuGet.exe install Sake -version 0.2 -o packages -ExcludeVersion + +:run +packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %* diff --git a/global.json b/global.json new file mode 100644 index 0000000000..840c36f6ad --- /dev/null +++ b/global.json @@ -0,0 +1,3 @@ +{ + "sources": ["src"] +} \ No newline at end of file diff --git a/makefile.shade b/makefile.shade new file mode 100644 index 0000000000..6357ea2841 --- /dev/null +++ b/makefile.shade @@ -0,0 +1,7 @@ + +var VERSION='0.1' +var FULL_VERSION='0.1' +var AUTHORS='Microsoft' + +use-standard-lifecycle +k-standard-goals diff --git a/samples/ErrorPageSample/Program.cs b/samples/ErrorPageSample/Program.cs new file mode 100644 index 0000000000..a4c76acea0 --- /dev/null +++ b/samples/ErrorPageSample/Program.cs @@ -0,0 +1,28 @@ +using System; +#if NET45 +using System.Diagnostics; +using Microsoft.Owin.Hosting; +#endif + +namespace ErrorPageSample +{ + public class Program + { + const string baseUrl = "http://localhost:9001/"; + + public static void Main() + { +#if NET45 + using (WebApp.Start(new StartOptions(baseUrl))) + { + Console.WriteLine("Listening at {0}", baseUrl); + Process.Start(baseUrl); + Console.WriteLine("Press any key to exit"); + Console.ReadKey(); + } +#else + Console.WriteLine("Hello World"); +#endif + } + } +} \ No newline at end of file diff --git a/samples/ErrorPageSample/Startup.cs b/samples/ErrorPageSample/Startup.cs new file mode 100644 index 0000000000..d39eb7874c --- /dev/null +++ b/samples/ErrorPageSample/Startup.cs @@ -0,0 +1,27 @@ +#if NET45 +using System; +using Microsoft.AspNet; +using Microsoft.AspNet.Abstractions; +using Owin; + +namespace ErrorPageSample +{ + public class Startup + { + public void Configuration(IAppBuilder app) + { + // Temporary bridge from katana to Owin + app.UseBuilder(ConfigurePK); + } + + private void ConfigurePK(IBuilder builder) + { + builder.UseErrorPage(); + builder.Run(context => + { + throw new Exception("Demonstration exception"); + }); + } + } +} +#endif \ No newline at end of file diff --git a/samples/ErrorPageSample/project.json b/samples/ErrorPageSample/project.json new file mode 100644 index 0000000000..f38335b51e --- /dev/null +++ b/samples/ErrorPageSample/project.json @@ -0,0 +1,39 @@ +{ + "version": "0.1-alpha-*", + "dependencies": { + "Microsoft.AspNet.Diagnostics": "", + "Microsoft.AspNet.HttpFeature": "0.1-alpha-*", + "Microsoft.AspNet.Abstractions": "0.1-alpha-*" + }, + "configurations": { + "net45": { + "dependencies": { + "Owin": "1.0", + "Microsoft.Owin": "2.1.0", + "Microsoft.Owin.Hosting": "2.1.0", + "Microsoft.Owin.Host.HttpListener": "2.1.0", + "Microsoft.AspNet.AppBuilderSupport": "0.1-alpha-*" + } + }, + "k10": { + "dependencies": { + "System.Console": "4.0.0.0", + "System.Collections": "4.0.0.0", + "System.Diagnostics.Debug": "4.0.10.0", + "System.Diagnostics.Tools": "4.0.0.0", + "System.Globalization": "4.0.10.0", + "System.IO": "4.0.0.0", + "System.IO.FileSystem": "4.0.0.0", + "System.IO.FileSystem.Primitives": "4.0.0.0", + "System.Linq": "4.0.0.0", + "System.Reflection": "4.0.10.0", + "System.Resources.ResourceManager": "4.0.0.0", + "System.Runtime": "4.0.20.0", + "System.Runtime.Extensions": "4.0.10.0", + "System.Runtime.InteropServices": "4.0.10.0", + "System.Text.Encoding": "4.0.10.0", + "System.Threading.Tasks": "4.0.0.0" + } + } + } +} \ No newline at end of file diff --git a/samples/WelcomePageSample/Program.cs b/samples/WelcomePageSample/Program.cs new file mode 100644 index 0000000000..0360e87f60 --- /dev/null +++ b/samples/WelcomePageSample/Program.cs @@ -0,0 +1,28 @@ +using System; +#if NET45 +using System.Diagnostics; +using Microsoft.Owin.Hosting; +#endif + +namespace WelcomePageSample +{ + public class Program + { + const string baseUrl = "http://localhost:9001/"; + + public static void Main() + { +#if NET45 + using (WebApp.Start(new StartOptions(baseUrl))) + { + Console.WriteLine("Listening at {0}", baseUrl); + Process.Start(baseUrl); + Console.WriteLine("Press any key to exit"); + Console.ReadKey(); + } +#else + Console.WriteLine("Hello World"); +#endif + } + } +} \ No newline at end of file diff --git a/samples/WelcomePageSample/Startup.cs b/samples/WelcomePageSample/Startup.cs new file mode 100644 index 0000000000..0b08dfb71b --- /dev/null +++ b/samples/WelcomePageSample/Startup.cs @@ -0,0 +1,22 @@ +#if NET45 +using Microsoft.AspNet; +using Microsoft.AspNet.Abstractions; +using Owin; + +namespace WelcomePageSample +{ + public class Startup + { + public void Configuration(IAppBuilder app) + { + // Temporary bridge from katana to Owin + app.UseBuilder(ConfigurePK); + } + + private void ConfigurePK(IBuilder builder) + { + builder.UseWelcomePage(); + } + } +} +#endif \ No newline at end of file diff --git a/samples/WelcomePageSample/project.json b/samples/WelcomePageSample/project.json new file mode 100644 index 0000000000..f38335b51e --- /dev/null +++ b/samples/WelcomePageSample/project.json @@ -0,0 +1,39 @@ +{ + "version": "0.1-alpha-*", + "dependencies": { + "Microsoft.AspNet.Diagnostics": "", + "Microsoft.AspNet.HttpFeature": "0.1-alpha-*", + "Microsoft.AspNet.Abstractions": "0.1-alpha-*" + }, + "configurations": { + "net45": { + "dependencies": { + "Owin": "1.0", + "Microsoft.Owin": "2.1.0", + "Microsoft.Owin.Hosting": "2.1.0", + "Microsoft.Owin.Host.HttpListener": "2.1.0", + "Microsoft.AspNet.AppBuilderSupport": "0.1-alpha-*" + } + }, + "k10": { + "dependencies": { + "System.Console": "4.0.0.0", + "System.Collections": "4.0.0.0", + "System.Diagnostics.Debug": "4.0.10.0", + "System.Diagnostics.Tools": "4.0.0.0", + "System.Globalization": "4.0.10.0", + "System.IO": "4.0.0.0", + "System.IO.FileSystem": "4.0.0.0", + "System.IO.FileSystem.Primitives": "4.0.0.0", + "System.Linq": "4.0.0.0", + "System.Reflection": "4.0.10.0", + "System.Resources.ResourceManager": "4.0.0.0", + "System.Runtime": "4.0.20.0", + "System.Runtime.Extensions": "4.0.10.0", + "System.Runtime.InteropServices": "4.0.10.0", + "System.Text.Encoding": "4.0.10.0", + "System.Threading.Tasks": "4.0.0.0" + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Diagnostics/Constants.cs b/src/Microsoft.AspNet.Diagnostics/Constants.cs new file mode 100644 index 0000000000..468b5aa908 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Constants.cs @@ -0,0 +1,24 @@ +// +// Copyright 2011-2013 Microsoft Open Technologies, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +namespace Microsoft.AspNet.Diagnostics +{ + internal static class Constants + { + internal const string HostAppMode = "host.AppMode"; + internal const string DevMode = "development"; + } +} diff --git a/src/Microsoft.AspNet.Diagnostics/DiagnosticsPageExtensions.cs b/src/Microsoft.AspNet.Diagnostics/DiagnosticsPageExtensions.cs new file mode 100644 index 0000000000..a68c2ca0a2 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/DiagnosticsPageExtensions.cs @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +#if DEBUG +using System; +using Microsoft.AspNet.Abstractions; +using Microsoft.AspNet.Diagnostics; + +namespace Microsoft.AspNet +{ + /// + /// IBuilder extensions for the DiagnosticsPageMiddleware. + /// + public static class DiagnosticsPageExtensions + { + /// + /// Adds the DiagnosticsPageMiddleware to the pipeline with the given options. + /// + /// + /// + /// + public static IBuilder UseDiagnosticsPage(this IBuilder builder, DiagnosticsPageOptions options) + { + if (builder == null) + { + throw new ArgumentNullException("builder"); + } + + return builder.Use(next => new DiagnosticsPageMiddleware(next, options).Invoke); + } + + /// + /// Adds the DiagnosticsPageMiddleware to the pipeline with the given path. + /// + /// + /// + /// + public static IBuilder UseDiagnosticsPage(this IBuilder builder, PathString path) + { + return UseDiagnosticsPage(builder, new DiagnosticsPageOptions { Path = path }); + } + + /// + /// Adds the DiagnosticsPageMiddleware to the pipeline. + /// + /// + /// + public static IBuilder UseDiagnosticsPage(this IBuilder builder) + { + return UseDiagnosticsPage(builder, new DiagnosticsPageOptions()); + } + } +} +#endif \ No newline at end of file diff --git a/src/Microsoft.AspNet.Diagnostics/DiagnosticsPageMiddleware.cs b/src/Microsoft.AspNet.Diagnostics/DiagnosticsPageMiddleware.cs new file mode 100644 index 0000000000..7c71a0d745 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/DiagnosticsPageMiddleware.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +#if DEBUG +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNet.Diagnostics.Views; +using Microsoft.AspNet.Abstractions; + +namespace Microsoft.AspNet.Diagnostics +{ + /// + /// A human readable page with basic debugging actions. + /// + public class DiagnosticsPageMiddleware + { + private readonly RequestDelegate _next; + private readonly DiagnosticsPageOptions _options; + + /// + /// Initializes a new instance of the class + /// + /// + /// + public DiagnosticsPageMiddleware(RequestDelegate next, DiagnosticsPageOptions options) + { + _next = next; + _options = options; + } + + /// + /// Process an individual request. + /// + /// + /// + public Task Invoke(HttpContext context) + { + if (!_options.Path.HasValue || _options.Path == context.Request.Path) + { + var page = new DiagnosticsPage(); + page.Execute(context); + return Task.FromResult(0); + } + return _next(context); + } + } +} +#endif \ No newline at end of file diff --git a/src/Microsoft.AspNet.Diagnostics/DiagnosticsPageOptions.cs b/src/Microsoft.AspNet.Diagnostics/DiagnosticsPageOptions.cs new file mode 100644 index 0000000000..3ba61f8ee0 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/DiagnosticsPageOptions.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +#if DEBUG + +using Microsoft.AspNet.Abstractions; + +namespace Microsoft.AspNet.Diagnostics +{ + /// + /// Options for the DiagnosticsPageMiddleware + /// + public class DiagnosticsPageOptions + { + /// + /// Specifies which requests paths will be responded to. Exact matches only. Leave null to handle all requests. + /// + public PathString Path { get; set; } + } +} +#endif \ No newline at end of file diff --git a/src/Microsoft.AspNet.Diagnostics/ErrorPageExtensions.cs b/src/Microsoft.AspNet.Diagnostics/ErrorPageExtensions.cs new file mode 100644 index 0000000000..4f3576538a --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/ErrorPageExtensions.cs @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Abstractions; +using Microsoft.AspNet.Diagnostics; + +namespace Microsoft.AspNet +{ + /// + /// IBuilder extension methods for the ErrorPageMiddleware. + /// + public static class ErrorPageExtensions + { + /// + /// Captures synchronous and asynchronous exceptions from the pipeline and generates HTML error responses. + /// Full error details are only displayed by default if 'host.AppMode' is set to 'development' in the IBuilder.Properties. + /// + /// + /// + public static IBuilder UseErrorPage(this IBuilder builder) + { + if (builder == null) + { + throw new ArgumentNullException("builder"); + } + + return builder.UseErrorPage(new ErrorPageOptions()); + } + + /// + /// Captures synchronous and asynchronous exceptions from the pipeline and generates HTML error responses. + /// Full error details are only displayed by default if 'host.AppMode' is set to 'development' in the IBuilder.Properties. + /// + /// + /// + /// + public static IBuilder UseErrorPage(this IBuilder builder, ErrorPageOptions options) + { + if (builder == null) + { + throw new ArgumentNullException("builder"); + } + /* TODO: Development, Staging, or Production + string appMode = new AppProperties(builder.Properties).Get(Constants.HostAppMode); + bool isDevMode = string.Equals(Constants.DevMode, appMode, StringComparison.Ordinal);*/ + bool isDevMode = true; + return builder.Use(next => new ErrorPageMiddleware(next, options, isDevMode).Invoke); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Diagnostics/ErrorPageMiddleware.cs b/src/Microsoft.AspNet.Diagnostics/ErrorPageMiddleware.cs new file mode 100644 index 0000000000..10f9fdecac --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/ErrorPageMiddleware.cs @@ -0,0 +1,200 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNet.Diagnostics.Views; +using Microsoft.AspNet.Abstractions; + +namespace Microsoft.AspNet.Diagnostics +{ + /// + /// Captures synchronous and asynchronous exceptions from the pipeline and generates HTML error responses. + /// + public class ErrorPageMiddleware + { + private readonly RequestDelegate _next; + private readonly ErrorPageOptions _options; + + /// + /// Initializes a new instance of the class + /// + /// + /// + /// + public ErrorPageMiddleware(RequestDelegate next, ErrorPageOptions options, bool isDevMode) + { + if (next == null) + { + throw new ArgumentNullException("next"); + } + if (options == null) + { + throw new ArgumentNullException("options"); + } + if (isDevMode) + { + options.SetDefaultVisibility(isVisible: true); + } + _next = next; + _options = options; + } + + /// + /// Process an individual request. + /// + /// + /// + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "For diagnostics")] + public async Task Invoke(HttpContext context) + { + try + { + await _next(context); + } + catch (Exception ex) + { + try + { + DisplayException(context, ex); + return; + } + catch (Exception) + { + // If there's a Exception while generating the error page, re-throw the original exception. + } + throw; + } + } + + // Assumes the response headers have not been sent. If they have, still attempt to write to the body. + private void DisplayException(HttpContext context, Exception ex) + { + var request = context.Request; + + ErrorPageModel model = new ErrorPageModel() + { + Options = _options, + }; + + if (_options.ShowExceptionDetails) + { + model.ErrorDetails = GetErrorDetails(ex, _options.ShowSourceCode).Reverse(); + } + if (_options.ShowQuery) + { + model.Query = request.Query; + }/* TODO: + if (_options.ShowCookies) + { + model.Cookies = request.Cookies; + }*/ + if (_options.ShowHeaders) + { + model.Headers = request.Headers; + }/* TODO: + if (_options.ShowEnvironment) + { + model.Environment = context; + }*/ + + var errorPage = new ErrorPage() { Model = model }; + errorPage.Execute(context); + } + + private IEnumerable GetErrorDetails(Exception ex, bool showSource) + { + for (Exception scan = ex; scan != null; scan = scan.InnerException) + { + yield return new ErrorDetails + { + Error = scan, + StackFrames = StackFrames(scan, showSource) + }; + } + } + + private IEnumerable StackFrames(Exception ex, bool showSource) + { + var stackTrace = ex.StackTrace; + if (!string.IsNullOrEmpty(stackTrace)) + { + var heap = new Chunk { Text = stackTrace + Environment.NewLine, End = stackTrace.Length + 2 }; + for (Chunk line = heap.Advance(Environment.NewLine); line.HasValue; line = heap.Advance(Environment.NewLine)) + { + yield return StackFrame(line, showSource); + } + } + } + + private StackFrame StackFrame(Chunk line, bool showSource) + { + line.Advance(" at "); + string function = line.Advance(" in ").ToString(); + string file = line.Advance(":line ").ToString(); + int lineNumber = line.ToInt32(); + + return string.IsNullOrEmpty(file) + ? LoadFrame(line.ToString(), string.Empty, 0, showSource) + : LoadFrame(function, file, lineNumber, showSource); + } + + private StackFrame LoadFrame(string function, string file, int lineNumber, bool showSource) + { + var frame = new StackFrame { Function = function, File = file, Line = lineNumber }; + if (showSource && File.Exists(file)) + { + IEnumerable code = File.ReadLines(file); + frame.PreContextLine = Math.Max(lineNumber - _options.SourceCodeLineCount, 1); + frame.PreContextCode = code.Skip(frame.PreContextLine - 1).Take(lineNumber - frame.PreContextLine).ToArray(); + frame.ContextCode = code.Skip(lineNumber - 1).FirstOrDefault(); + frame.PostContextCode = code.Skip(lineNumber).Take(_options.SourceCodeLineCount).ToArray(); + } + return frame; + } + + internal class Chunk + { + public string Text { get; set; } + public int Start { get; set; } + public int End { get; set; } + + public bool HasValue + { + get { return Text != null; } + } + + public Chunk Advance(string delimiter) + { + int indexOf = HasValue ? Text.IndexOf(delimiter, Start, End - Start, StringComparison.Ordinal) : -1; + if (indexOf < 0) + { + return new Chunk(); + } + + var chunk = new Chunk { Text = Text, Start = Start, End = indexOf }; + Start = indexOf + delimiter.Length; + return chunk; + } + + public override string ToString() + { + return HasValue ? Text.Substring(Start, End - Start) : string.Empty; + } + + public int ToInt32() + { + int value; + return HasValue && Int32.TryParse( + Text.Substring(Start, End - Start), + NumberStyles.Integer, + CultureInfo.InvariantCulture, + out value) ? value : 0; + } + } + } +} diff --git a/src/Microsoft.AspNet.Diagnostics/ErrorPageOptions.cs b/src/Microsoft.AspNet.Diagnostics/ErrorPageOptions.cs new file mode 100644 index 0000000000..fd38bf0aee --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/ErrorPageOptions.cs @@ -0,0 +1,117 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Diagnostics +{ + /// + /// Options for the ErrorPageMiddleware + /// + public class ErrorPageOptions + { + private bool _defaultVisibility; + + private bool? _showExceptionDetails; + private bool? _showSourceCode; + private bool? _showQuery; + private bool? _showCookies; + private bool? _showHeaders; + private bool? _showEnvironment; + + /// + /// Create an instance with the default options settings. + /// + public ErrorPageOptions() + { + SourceCodeLineCount = 6; + } + + /// + /// Returns a new instance of ErrorPageOptions with all visibility options enabled by default. + /// + public static ErrorPageOptions ShowAll + { + get + { + // We don't use a static instance because it's mutable. + return new ErrorPageOptions() + { + ShowExceptionDetails = true, + ShowSourceCode = true, + ShowQuery = true, + ShowCookies = true, + ShowHeaders = true, + ShowEnvironment = true, + }; + } + } + + /// + /// Enables the display of exception types, messages, and stack traces. + /// + public bool ShowExceptionDetails + { + get { return _showExceptionDetails ?? _defaultVisibility; } + set { _showExceptionDetails = value; } + } + + /// + /// Enabled the display of local source code around exception stack frames. + /// + public bool ShowSourceCode + { + get { return _showSourceCode ?? _defaultVisibility; } + set { _showSourceCode = value; } + } + + /// + /// Determines how many lines of code to include before and after the line of code + /// present in an exception's stack frame. Only applies when symbols are available and + /// source code referenced by the exception stack trace is present on the server. + /// + public int SourceCodeLineCount { get; set; } + + /// + /// Enables the enumeration of any parsed query values. + /// + public bool ShowQuery + { + get { return _showQuery ?? _defaultVisibility; } + set { _showQuery = value; } + } + + /// + /// Enables the enumeration of any parsed request cookies. + /// + public bool ShowCookies + { + get { return _showCookies ?? _defaultVisibility; } + set { _showCookies = value; } + } + + /// + /// Enables the enumeration of the request headers. + /// + public bool ShowHeaders + { + get { return _showHeaders ?? _defaultVisibility; } + set { _showHeaders = value; } + } + + /// + /// Enables the enumeration of the OWIN environment values. + /// + public bool ShowEnvironment + { + get { return _showEnvironment ?? _defaultVisibility; } + set { _showEnvironment = value; } + } + + /// + /// Sets the default visibility for options not otherwise specified. + /// + /// + public void SetDefaultVisibility(bool isVisible) + { + _defaultVisibility = isVisible; + } + } +} diff --git a/src/Microsoft.AspNet.Diagnostics/Resources.Designer.cs b/src/Microsoft.AspNet.Diagnostics/Resources.Designer.cs new file mode 100644 index 0000000000..c0b4db6534 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Resources.Designer.cs @@ -0,0 +1,315 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.33440 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.AspNet.Diagnostics { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.AspNet.Diagnostics.Resources", System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof(Resources)).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to You are seeing this page because DiagnosticsPageMiddleware was added to your web application.. + /// + internal static string DiagnosticsPageHtml_Information { + get { + return ResourceManager.GetString("DiagnosticsPageHtml_Information", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Test Error Message. + /// + internal static string DiagnosticsPageHtml_TestErrorMessage { + get { + return ResourceManager.GetString("DiagnosticsPageHtml_TestErrorMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Test Error Page. + /// + internal static string DiagnosticsPageHtml_TestErrorSection { + get { + return ResourceManager.GetString("DiagnosticsPageHtml_TestErrorSection", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Diagnostics Page. + /// + internal static string DiagnosticsPageHtml_Title { + get { + return ResourceManager.GetString("DiagnosticsPageHtml_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cookies. + /// + internal static string ErrorPageHtml_CookiesButton { + get { + return ResourceManager.GetString("ErrorPageHtml_CookiesButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enable development mode or ErrorPageOptions.ShowExceptionDetails for additional information.. + /// + internal static string ErrorPageHtml_EnableShowExceptions { + get { + return ResourceManager.GetString("ErrorPageHtml_EnableShowExceptions", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Environment. + /// + internal static string ErrorPageHtml_EnvironmentButton { + get { + return ResourceManager.GetString("ErrorPageHtml_EnvironmentButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Headers. + /// + internal static string ErrorPageHtml_HeadersButton { + get { + return ResourceManager.GetString("ErrorPageHtml_HeadersButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No cookie data.. + /// + internal static string ErrorPageHtml_NoCookieData { + get { + return ResourceManager.GetString("ErrorPageHtml_NoCookieData", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No header data.. + /// + internal static string ErrorPageHtml_NoHeaderData { + get { + return ResourceManager.GetString("ErrorPageHtml_NoHeaderData", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No QueryString data.. + /// + internal static string ErrorPageHtml_NoQueryStringData { + get { + return ResourceManager.GetString("ErrorPageHtml_NoQueryStringData", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Query. + /// + internal static string ErrorPageHtml_QueryButton { + get { + return ResourceManager.GetString("ErrorPageHtml_QueryButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stack. + /// + internal static string ErrorPageHtml_StackButton { + get { + return ResourceManager.GetString("ErrorPageHtml_StackButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Internal Server Error. + /// + internal static string ErrorPageHtml_Title { + get { + return ResourceManager.GetString("ErrorPageHtml_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An unhandled exception occurred while processing the request.. + /// + internal static string ErrorPageHtml_UnhandledException { + get { + return ResourceManager.GetString("ErrorPageHtml_UnhandledException", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown location. + /// + internal static string ErrorPageHtml_UnknownLocation { + get { + return ResourceManager.GetString("ErrorPageHtml_UnknownLocation", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Value. + /// + internal static string ErrorPageHtml_ValueColumn { + get { + return ResourceManager.GetString("ErrorPageHtml_ValueColumn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Variable. + /// + internal static string ErrorPageHtml_VariableColumn { + get { + return ResourceManager.GetString("ErrorPageHtml_VariableColumn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The path must start with a '/'.. + /// + internal static string Exception_PathMustStartWithSlash { + get { + return ResourceManager.GetString("Exception_PathMustStartWithSlash", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Welcome. + /// + internal static string WelcomeHeader { + get { + return ResourceManager.GetString("WelcomeHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Learn more about the Microsoft OWIN components. + /// + internal static string WelcomeLearnMicrosoftOwin { + get { + return ResourceManager.GetString("WelcomeLearnMicrosoftOwin", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Learn more about OWIN. + /// + internal static string WelcomeLearnOwin { + get { + return ResourceManager.GetString("WelcomeLearnOwin", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Browser. + /// + internal static string WelcomePageImageText_Browser { + get { + return ResourceManager.GetString("WelcomePageImageText_Browser", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Learn More. + /// + internal static string WelcomePageImageText_LearnMore { + get { + return ResourceManager.GetString("WelcomePageImageText_LearnMore", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Light Bulb. + /// + internal static string WelcomePageImageText_LightBulb { + get { + return ResourceManager.GetString("WelcomePageImageText_LightBulb", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Skyline. + /// + internal static string WelcomePageImageText_Skyline { + get { + return ResourceManager.GetString("WelcomePageImageText_Skyline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Your OWIN application has been successfully started. + /// + internal static string WelcomeStarted { + get { + return ResourceManager.GetString("WelcomeStarted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Your OWIN application has been successfully started.. + /// + internal static string WelcomeTitle { + get { + return ResourceManager.GetString("WelcomeTitle", resourceCulture); + } + } + } +} diff --git a/src/Microsoft.AspNet.Diagnostics/Resources.resx b/src/Microsoft.AspNet.Diagnostics/Resources.resx new file mode 100644 index 0000000000..b58d66477f --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Resources.resx @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + You are seeing this page because DiagnosticsPageMiddleware was added to your web application. + + + Test Error Message + + + Test Error Page + + + Diagnostics Page + + + Cookies + as in http request cookies + + + Enable development mode or ErrorPageOptions.ShowExceptionDetails for additional information. + + + Environment + as in OWIN environment dictionary + + + Headers + as in http request headers + + + No cookie data. + + + No header data. + + + No QueryString data. + + + Query + as in a request url query string + + + Stack + as in an exception's call stack + + + Internal Server Error + + + An unhandled exception occurred while processing the request. + + + Unknown location + when a stack source code location is not known + + + Value + as in dictionary value + + + Variable + as in dictionary key + + + The path must start with a '/'. + + + Welcome + + + Learn more about the Microsoft OWIN components + + + Learn more about OWIN + + + Browser + + + Learn More + + + Light Bulb + + + Skyline + + + Your OWIN application has been successfully started + + + Your OWIN application has been successfully started. + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Diagnostics/Views/BaseView.cs b/src/Microsoft.AspNet.Diagnostics/Views/BaseView.cs new file mode 100644 index 0000000000..bfcd2c93ee --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Views/BaseView.cs @@ -0,0 +1,442 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using Microsoft.AspNet.Abstractions; +using System; +using System.Globalization; +using System.IO; +using System.Net; + +namespace Microsoft.AspNet.Diagnostics.Views +{ + /// + /// Infrastructure + /// + public abstract class BaseView + { + /// + /// The request context + /// + protected HttpContext Context { get; private set; } + + /// + /// The request + /// + protected HttpRequest Request { get; private set; } + + /// + /// The response + /// + protected HttpResponse Response { get; private set; } + + /// + /// The output stream + /// + protected StreamWriter Output { get; private set; } + + /// + /// Execute an individual request + /// + /// + public void Execute(HttpContext context) + { + Context = context; + Request = Context.Request; + Response = Context.Response; + Output = new StreamWriter(Response.Body); + Execute(); + Output.Dispose(); + } + + /// + /// Execute an individual request + /// + public abstract void Execute(); + + /// + /// Write the given value directly to the output + /// + /// + protected void WriteLiteral(string value) + { + Output.Write(value); + } + + /// + /// + /// + /// + /// + /// + /// + /// + protected void WriteAttribute( + string name, + Tuple leader, + Tuple trailer, + Tuple, Tuple, bool> part1) + { + if (name == null) + { + throw new ArgumentNullException("name"); + } + if (leader == null) + { + throw new ArgumentNullException("leader"); + } + if (trailer == null) + { + throw new ArgumentNullException("trailer"); + } + if (part1 == null) + { + throw new ArgumentNullException("part1"); + } + WriteLiteral(leader.Item1); + WriteLiteral(part1.Item1.Item1); + Write(part1.Item2.Item1); + WriteLiteral(trailer.Item1); + } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected void WriteAttribute( + string name, + Tuple leader, + Tuple trailer, + Tuple, Tuple, bool> part1, + Tuple, Tuple, bool> part2) + { + if (name == null) + { + throw new ArgumentNullException("name"); + } + if (leader == null) + { + throw new ArgumentNullException("leader"); + } + if (trailer == null) + { + throw new ArgumentNullException("trailer"); + } + if (part1 == null) + { + throw new ArgumentNullException("part1"); + } + if (part2 == null) + { + throw new ArgumentNullException("part2"); + } + WriteLiteral(leader.Item1); + WriteLiteral(part1.Item1.Item1); + Write(part1.Item2.Item1); + WriteLiteral(part2.Item1.Item1); + Write(part2.Item2.Item1); + WriteLiteral(trailer.Item1); + } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected void WriteAttribute( + string name, + Tuple leader, + Tuple trailer, + Tuple, Tuple, bool> part1, + Tuple, Tuple, bool> part2, + Tuple, Tuple, bool> part3) + { + if (name == null) + { + throw new ArgumentNullException("name"); + } + if (leader == null) + { + throw new ArgumentNullException("leader"); + } + if (trailer == null) + { + throw new ArgumentNullException("trailer"); + } + if (part1 == null) + { + throw new ArgumentNullException("part1"); + } + if (part2 == null) + { + throw new ArgumentNullException("part2"); + } + if (part3 == null) + { + throw new ArgumentNullException("part3"); + } + WriteLiteral(leader.Item1); + WriteLiteral(part1.Item1.Item1); + Write(part1.Item2.Item1); + WriteLiteral(part2.Item1.Item1); + Write(part2.Item2.Item1); + WriteLiteral(part3.Item1.Item1); + Write(part3.Item2.Item1); + WriteLiteral(trailer.Item1); + } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected void WriteAttribute( + string name, + Tuple leader, + Tuple trailer, + Tuple, Tuple, bool> part1, + Tuple, Tuple, bool> part2, + Tuple, Tuple, bool> part3, + Tuple, Tuple, bool> part4) + { + if (name == null) + { + throw new ArgumentNullException("name"); + } + if (leader == null) + { + throw new ArgumentNullException("leader"); + } + if (trailer == null) + { + throw new ArgumentNullException("trailer"); + } + if (part1 == null) + { + throw new ArgumentNullException("part1"); + } + if (part2 == null) + { + throw new ArgumentNullException("part2"); + } + if (part3 == null) + { + throw new ArgumentNullException("part3"); + } + if (part4 == null) + { + throw new ArgumentNullException("part4"); + } + WriteLiteral(leader.Item1); + WriteLiteral(part1.Item1.Item1); + Write(part1.Item2.Item1); + WriteLiteral(part2.Item1.Item1); + Write(part2.Item2.Item1); + WriteLiteral(part3.Item1.Item1); + Write(part3.Item2.Item1); + WriteLiteral(part4.Item1.Item1); + Write(part4.Item2.Item1); + WriteLiteral(trailer.Item1); + } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected void WriteAttribute( + string name, + Tuple leader, + Tuple trailer, + Tuple, Tuple, bool> part1, + Tuple, Tuple, bool> part2, + Tuple, Tuple, bool> part3, + Tuple, Tuple, bool> part4, + Tuple, Tuple, bool> part5) + { + if (name == null) + { + throw new ArgumentNullException("name"); + } + if (leader == null) + { + throw new ArgumentNullException("leader"); + } + if (trailer == null) + { + throw new ArgumentNullException("trailer"); + } + if (part1 == null) + { + throw new ArgumentNullException("part1"); + } + if (part2 == null) + { + throw new ArgumentNullException("part2"); + } + if (part3 == null) + { + throw new ArgumentNullException("part3"); + } + if (part4 == null) + { + throw new ArgumentNullException("part4"); + } + if (part5 == null) + { + throw new ArgumentNullException("part5"); + } + WriteLiteral(leader.Item1); + WriteLiteral(part1.Item1.Item1); + Write(part1.Item2.Item1); + WriteLiteral(part2.Item1.Item1); + Write(part2.Item2.Item1); + WriteLiteral(part3.Item1.Item1); + Write(part3.Item2.Item1); + WriteLiteral(part4.Item1.Item1); + Write(part4.Item2.Item1); + WriteLiteral(part5.Item1.Item1); + Write(part5.Item2.Item1); + WriteLiteral(trailer.Item1); + } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + protected void WriteAttribute( + string name, + Tuple leader, + Tuple trailer, + Tuple, Tuple, bool> part1, + Tuple, Tuple, bool> part2, + Tuple, Tuple, bool> part3, + Tuple, Tuple, bool> part4, + Tuple, Tuple, bool> part5, + Tuple, Tuple, bool> part6) + { + if (name == null) + { + throw new ArgumentNullException("name"); + } + if (leader == null) + { + throw new ArgumentNullException("leader"); + } + if (trailer == null) + { + throw new ArgumentNullException("trailer"); + } + if (part1 == null) + { + throw new ArgumentNullException("part1"); + } + if (part2 == null) + { + throw new ArgumentNullException("part2"); + } + if (part3 == null) + { + throw new ArgumentNullException("part3"); + } + if (part4 == null) + { + throw new ArgumentNullException("part4"); + } + if (part5 == null) + { + throw new ArgumentNullException("part5"); + } + if (part6 == null) + { + throw new ArgumentNullException("part6"); + } + WriteLiteral(leader.Item1); + WriteLiteral(part1.Item1.Item1); + Write(part1.Item2.Item1); + WriteLiteral(part2.Item1.Item1); + Write(part2.Item2.Item1); + WriteLiteral(part3.Item1.Item1); + Write(part3.Item2.Item1); + WriteLiteral(part4.Item1.Item1); + Write(part4.Item2.Item1); + WriteLiteral(part5.Item1.Item1); + Write(part5.Item2.Item1); + WriteLiteral(part6.Item1.Item1); + Write(part6.Item2.Item1); + WriteLiteral(trailer.Item1); + } + + /// + /// Html encode and write + /// + /// + private void WriteEncoded(string value) + { + Output.Write(WebUtility.HtmlEncode(value)); + } + + /// + /// Convert to string and html encode + /// + /// + protected void Write(object value) + { + WriteEncoded(Convert.ToString(value, CultureInfo.InvariantCulture)); + } + + /// + /// Html encode and write + /// + /// + protected void Write(string value) + { + WriteEncoded(value); + } + } +} diff --git a/src/Microsoft.AspNet.Diagnostics/Views/DiagnosticsPage.cs b/src/Microsoft.AspNet.Diagnostics/Views/DiagnosticsPage.cs new file mode 100644 index 0000000000..cd293e7b86 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Views/DiagnosticsPage.cs @@ -0,0 +1,133 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.18213 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.AspNet.Diagnostics.Views { + + #line 1 "DiagnosticsPage.cshtml" + using System; + + #line default + #line hidden + + #line 2 "DiagnosticsPage.cshtml" + using System.Globalization; + + #line default + #line hidden + + + public class DiagnosticsPage : Microsoft.AspNet.Diagnostics.Views.BaseView { + +#line hidden + + public DiagnosticsPage() { + } + + public override void Execute() { + + #line 3 "DiagnosticsPage.cshtml" + + Response.ContentType = "text/html"; + string error = Request.Query.Get("error"); + if (!string.IsNullOrWhiteSpace(error)) + { + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "User requested error '{0}'", error)); + } + + + #line default + #line hidden +WriteLiteral("\r\n\r\n\r\n\r\n\r\n \r\n "); + + + #line 16 "DiagnosticsPage.cshtml" + Write(Resources.DiagnosticsPageHtml_Title); + + + #line default + #line hidden +WriteLiteral("\r\n\r\n\r\n \r\n

"); + + + #line 20 "DiagnosticsPage.cshtml" + Write(Resources.DiagnosticsPageHtml_Title); + + + #line default + #line hidden +WriteLiteral("

\r\n

"); + + + #line 21 "DiagnosticsPage.cshtml" + Write(Resources.DiagnosticsPageHtml_Information); + + + #line default + #line hidden +WriteLiteral("

\r\n \r\n \r\n

"); + + + #line 24 "DiagnosticsPage.cshtml" + Write(Resources.DiagnosticsPageHtml_TestErrorSection); + + + #line default + #line hidden +WriteLiteral("

\r\n

(Request.PathBase + + #line default + #line hidden +, 774), false) + + #line 25 "DiagnosticsPage.cshtml" +, Tuple.Create(Tuple.Create("", 791), Tuple.Create(Request.Path + + #line default + #line hidden +, 791), false) +, Tuple.Create(Tuple.Create("", 804), Tuple.Create("?error=", 804), true) + + #line 25 "DiagnosticsPage.cshtml" +, Tuple.Create(Tuple.Create("", 811), Tuple.Create(Resources.DiagnosticsPageHtml_TestErrorMessage + + #line default + #line hidden +, 811), false) +); + +WriteLiteral(">throw InvalidOperationException

\r\n \r\n\r\n\r\n"); + + } + } +} + diff --git a/src/Microsoft.AspNet.Diagnostics/Views/DiagnosticsPage.cshtml b/src/Microsoft.AspNet.Diagnostics/Views/DiagnosticsPage.cshtml new file mode 100644 index 0000000000..55b1d06f52 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Views/DiagnosticsPage.cshtml @@ -0,0 +1,28 @@ +@using System +@using System.Globalization +@{ + Response.ContentType = "text/html"; + string error = Request.Query.Get("error"); + if (!string.IsNullOrWhiteSpace(error)) + { + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "User requested error '{0}'", error)); + } +} + + + + + + @Resources.DiagnosticsPageHtml_Title + + +
+

@Resources.DiagnosticsPageHtml_Title

+

@Resources.DiagnosticsPageHtml_Information

+
+
+

@Resources.DiagnosticsPageHtml_TestErrorSection

+

throw InvalidOperationException

+
+ + diff --git a/src/Microsoft.AspNet.Diagnostics/Views/DiagnosticsPage.tt b/src/Microsoft.AspNet.Diagnostics/Views/DiagnosticsPage.tt new file mode 100644 index 0000000000..643ca3bb50 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Views/DiagnosticsPage.tt @@ -0,0 +1,26 @@ +<#@ template debug="false" hostspecific="true" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Web.Razor" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Web.Razor" #> +<#@ import namespace="System.Web.Razor.Text" #> +<#@ output extension=".cs" #> +<# +var host = new RazorEngineHost(new CSharpRazorCodeLanguage()); +host.DefaultBaseClass = "Microsoft.Owin.Diagnostics.Views.BaseView"; +var engine = new RazorTemplateEngine(host); +var path = Host.ResolvePath("DiagnosticsPage.cshtml"); + +var code = engine.GenerateCode( + new System.IO.StreamReader(path), + "DiagnosticsPage", + "Microsoft.Owin.Diagnostics.Views", + @"DiagnosticsPage.cshtml"); + +var provider = new Microsoft.CSharp.CSharpCodeProvider(); +var writer = new System.IO.StringWriter(); +provider.GenerateCodeFromCompileUnit(code.GeneratedCode, writer, null); +#> +<#=writer.ToString()#> diff --git a/src/Microsoft.AspNet.Diagnostics/Views/ErrorDetails.cs b/src/Microsoft.AspNet.Diagnostics/Views/ErrorDetails.cs new file mode 100644 index 0000000000..b08261c64a --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Views/ErrorDetails.cs @@ -0,0 +1,39 @@ +// +// Copyright 2011-2013 Microsoft Open Technologies, Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Microsoft.AspNet.Diagnostics.Views +{ + /// + /// Contains details for individual exception messages. + /// + public class ErrorDetails + { + /// + /// An individual exception + /// + public Exception Error { get; set; } + + /// + /// The generated stack frames + /// + public IEnumerable StackFrames { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.cs b/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.cs new file mode 100644 index 0000000000..ed73f65b6c --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.cs @@ -0,0 +1,1649 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.33440 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.AspNet.Diagnostics.Views { + + #line 1 "ErrorPage.cshtml" + using System; + + #line default + #line hidden + + #line 2 "ErrorPage.cshtml" + using System.Globalization; + + #line default + #line hidden + + #line 3 "ErrorPage.cshtml" + using System.Linq; + + #line default + #line hidden + + #line 4 "ErrorPage.cshtml" + using Views; + + #line default + #line hidden + + + public class ErrorPage : Microsoft.AspNet.Diagnostics.Views.BaseView { + +#line hidden + + #line 6 "ErrorPage.cshtml" + + /// + /// + /// + public Views.ErrorPageModel Model { get; set; } + + #line default + #line hidden + + + public ErrorPage() { + } + + public override void Execute() { + + #line 12 "ErrorPage.cshtml" + + Response.StatusCode = 500; + // Response.ReasonPhrase = "Internal Server Error"; + Response.ContentType = "text/html"; + Response.ContentLength = null; // Clear any prior Content-Length + string location = string.Empty; + + + #line default + #line hidden +WriteLiteral("\r\n\r\n(System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName + + #line default + #line hidden +, 468), false) +); + +WriteLiteral(" xmlns=\"http://www.w3.org/1999/xhtml\""); + +WriteLiteral(">\r\n \r\n \r\n "); + + + #line 23 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_Title); + + + #line default + #line hidden +WriteLiteral("\r\n \r\n \r\n \r\n

"); + + + #line 29 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_UnhandledException); + + + #line default + #line hidden +WriteLiteral("

\r\n"); + + + #line 30 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 30 "ErrorPage.cshtml" + if (Model.Options.ShowExceptionDetails) + { + foreach (var errorDetail in Model.ErrorDetails) + { + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 34 "ErrorPage.cshtml" + Write(errorDetail.Error.GetType().Name); + + + #line default + #line hidden +WriteLiteral(": "); + + + #line 34 "ErrorPage.cshtml" + Write(errorDetail.Error.Message); + + + #line default + #line hidden +WriteLiteral("\r\n"); + + + #line 35 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 35 "ErrorPage.cshtml" + + StackFrame firstFrame = null; + firstFrame = errorDetail.StackFrames.FirstOrDefault(); + if (firstFrame != null) + { + location = firstFrame.Function; + }/* + else if (errorDetail.Error.TargetSite != null && errorDetail.Error.TargetSite.DeclaringType != null) + { + location = errorDetail.Error.TargetSite.DeclaringType.FullName + "." + errorDetail.Error.TargetSite.Name; + }*/ + + + #line default + #line hidden + + #line 46 "ErrorPage.cshtml" + + if (!string.IsNullOrEmpty(location) && firstFrame != null && !string.IsNullOrEmpty(firstFrame.File)) + { + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 49 "ErrorPage.cshtml" + Write(location); + + + #line default + #line hidden +WriteLiteral(" in (firstFrame.File + + #line default + #line hidden +, 1907), false) +); + +WriteLiteral(">"); + + + #line 49 "ErrorPage.cshtml" + Write(System.IO.Path.GetFileName(firstFrame.File)); + + + #line default + #line hidden +WriteLiteral(", line "); + + + #line 49 "ErrorPage.cshtml" + Write(firstFrame.Line); + + + #line default + #line hidden +WriteLiteral("

\r\n"); + + + #line 50 "ErrorPage.cshtml" + } + else if (!string.IsNullOrEmpty(location)) + { + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 53 "ErrorPage.cshtml" + Write(location); + + + #line default + #line hidden +WriteLiteral("

\r\n"); + + + #line 54 "ErrorPage.cshtml" + } + else + { + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 57 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_UnknownLocation); + + + #line default + #line hidden +WriteLiteral("

\r\n"); + + + #line 58 "ErrorPage.cshtml" + } + } + } + else + { + + + #line default + #line hidden +WriteLiteral("

"); + + + #line 63 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_EnableShowExceptions); + + + #line default + #line hidden +WriteLiteral("

\r\n"); + + + #line 64 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n"); + + + #line 66 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 66 "ErrorPage.cshtml" + if (Model.Options.ShowExceptionDetails) + { + + + #line default + #line hidden +WriteLiteral(" \r\n"); + +WriteLiteral(" "); + + + #line 69 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_StackButton); + + + #line default + #line hidden +WriteLiteral("\r\n \r\n"); + + + #line 71 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 72 "ErrorPage.cshtml" + if (Model.Options.ShowQuery) + { + + + #line default + #line hidden +WriteLiteral(" \r\n"); + +WriteLiteral(" "); + + + #line 75 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_QueryButton); + + + #line default + #line hidden +WriteLiteral("\r\n \r\n"); + + + #line 77 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 78 "ErrorPage.cshtml" + if (Model.Options.ShowCookies) + { + + + #line default + #line hidden +WriteLiteral(" \r\n"); + +WriteLiteral(" "); + + + #line 81 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_CookiesButton); + + + #line default + #line hidden +WriteLiteral("\r\n \r\n"); + + + #line 83 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 84 "ErrorPage.cshtml" + if (Model.Options.ShowHeaders) + { + + + #line default + #line hidden +WriteLiteral(" \r\n"); + +WriteLiteral(" "); + + + #line 87 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_HeadersButton); + + + #line default + #line hidden +WriteLiteral("\r\n \r\n"); + + + #line 89 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 90 "ErrorPage.cshtml" + if (Model.Options.ShowEnvironment) + { + + + #line default + #line hidden +WriteLiteral(" \r\n"); + +WriteLiteral(" "); + + + #line 93 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_EnvironmentButton); + + + #line default + #line hidden +WriteLiteral("\r\n \r\n"); + + + #line 95 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n"); + + + #line 97 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 97 "ErrorPage.cshtml" + if (Model.Options.ShowExceptionDetails) + { + + + #line default + #line hidden +WriteLiteral(" \r\n
    \r\n"); + + + #line 101 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 101 "ErrorPage.cshtml" + int tabIndex = 6; + + #line default + #line hidden +WriteLiteral("\r\n"); + + + #line 102 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 102 "ErrorPage.cshtml" + foreach (var errorDetail in Model.ErrorDetails) + { + + + #line default + #line hidden +WriteLiteral("
  • \r\n "); + + + #line 105 "ErrorPage.cshtml" + Write(errorDetail.Error.GetType().Name); + + + #line default + #line hidden +WriteLiteral(": "); + + + #line 105 "ErrorPage.cshtml" + Write(errorDetail.Error.Message); + + + #line default + #line hidden +WriteLiteral("\r\n
      \r\n"); + + + #line 107 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 107 "ErrorPage.cshtml" + foreach (var frame in errorDetail.StackFrames) + { + + + #line default + #line hidden +WriteLiteral(" (tabIndex + + #line default + #line hidden +, 4169), false) +); + +WriteLiteral(">\r\n"); + + + #line 110 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 110 "ErrorPage.cshtml" + tabIndex++; + + #line default + #line hidden +WriteLiteral("\r\n"); + + + #line 111 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 111 "ErrorPage.cshtml" + if (string.IsNullOrEmpty(frame.File)) + { + + + #line default + #line hidden +WriteLiteral("

      "); + + + #line 113 "ErrorPage.cshtml" + Write(frame.Function); + + + #line default + #line hidden +WriteLiteral("

      \r\n"); + + + #line 114 "ErrorPage.cshtml" + } + else + { + + + #line default + #line hidden +WriteLiteral("

      "); + + + #line 117 "ErrorPage.cshtml" + Write(frame.Function); + + + #line default + #line hidden +WriteLiteral(" in (frame.File + + #line default + #line hidden +, 4613), false) +); + +WriteLiteral(">"); + + + #line 117 "ErrorPage.cshtml" + Write(System.IO.Path.GetFileName(frame.File)); + + + #line default + #line hidden +WriteLiteral("

      \r\n"); + + + #line 118 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral("\r\n"); + + + #line 120 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 120 "ErrorPage.cshtml" + if (frame.Line != 0 && frame.ContextCode != null) + { + + + #line default + #line hidden +WriteLiteral(" \r\n"); + + + #line 123 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 123 "ErrorPage.cshtml" + if (frame.PreContextCode != null) + { + + + #line default + #line hidden +WriteLiteral(" (frame.PreContextLine + + #line default + #line hidden +, 5095), false) +); + +WriteLiteral(" class=\"collapsable\""); + +WriteLiteral(">\r\n"); + + + #line 126 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 126 "ErrorPage.cshtml" + foreach (var line in frame.PreContextCode) + { + + + #line default + #line hidden +WriteLiteral("
    • "); + + + #line 128 "ErrorPage.cshtml" + Write(line); + + + #line default + #line hidden +WriteLiteral("
    • \r\n"); + + + #line 129 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n"); + + + #line 131 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral("\r\n (frame.Line + + #line default + #line hidden +, 5592), false) +); + +WriteLiteral(" class=\"highlight\""); + +WriteLiteral(">\r\n
    • "); + + + #line 134 "ErrorPage.cshtml" + Write(frame.ContextCode); + + + #line default + #line hidden +WriteLiteral("
    • \r\n\r\n"); + + + #line 136 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 136 "ErrorPage.cshtml" + if (frame.PostContextCode != null) + { + + + #line default + #line hidden +WriteLiteral(" (frame.Line + 1 + + #line default + #line hidden +, 5909), false) +); + +WriteLiteral(" class=\"collapsable\""); + +WriteLiteral(">\r\n"); + + + #line 139 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 139 "ErrorPage.cshtml" + foreach (var line in frame.PostContextCode) + { + + + #line default + #line hidden +WriteLiteral("
    • "); + + + #line 141 "ErrorPage.cshtml" + Write(line); + + + #line default + #line hidden +WriteLiteral("
    • \r\n"); + + + #line 142 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n"); + + + #line 144 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n"); + + + #line 146 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n"); + + + #line 148 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral("
    \r\n
  • \r\n"); + + + #line 151 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral("
\r\n \r\n"); + + + #line 154 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 155 "ErrorPage.cshtml" + if (Model.Options.ShowQuery) + { + + + #line default + #line hidden +WriteLiteral(" \r\n"); + + + #line 158 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 158 "ErrorPage.cshtml" + if (Model.Query.Any()) + { + + + #line default + #line hidden +WriteLiteral(" \r\n \r\n " + +" \r\n \r\n \r\n \r\n \r\n " + +" \r\n"); + + + #line 168 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 168 "ErrorPage.cshtml" + foreach (var kv in Model.Query.OrderBy(kv => kv.Key)) + { + foreach (var v in kv.Value) + { + + + #line default + #line hidden +WriteLiteral(" \r\n " + +" \r\n \r\n \r\n"); + + + #line 176 "ErrorPage.cshtml" + } + } + + + #line default + #line hidden +WriteLiteral(" \r\n
"); + + + #line 163 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_VariableColumn); + + + #line default + #line hidden +WriteLiteral(""); + + + #line 164 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_ValueColumn); + + + #line default + #line hidden +WriteLiteral("
"); + + + #line 173 "ErrorPage.cshtml" + Write(kv.Key); + + + #line default + #line hidden +WriteLiteral(""); + + + #line 174 "ErrorPage.cshtml" + Write(v); + + + #line default + #line hidden +WriteLiteral("
\r\n"); + + + #line 180 "ErrorPage.cshtml" + } + else + { + + + #line default + #line hidden +WriteLiteral("

"); + + + #line 183 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_NoQueryStringData); + + + #line default + #line hidden +WriteLiteral("

\r\n"); + + + #line 184 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n"); + + + #line 186 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 187 "ErrorPage.cshtml" + if (Model.Options.ShowCookies) + { + /* + + #line default + #line hidden +WriteLiteral(" \r\n"); + + + #line 190 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 190 "ErrorPage.cshtml" + if (Model.Cookies.Any()) + { + + + #line default + #line hidden +WriteLiteral(" \r\n \r\n " + +" \r\n \r\n \r\n \r\n \r\n " + +" \r\n"); + + + #line 200 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 200 "ErrorPage.cshtml" + foreach (var kv in Model.Cookies.OrderBy(kv => kv.Key)) + { + + + #line default + #line hidden +WriteLiteral(" \r\n \r\n \r\n \r\n"); + + + #line 206 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n
"); + + + #line 195 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_VariableColumn); + + + #line default + #line hidden +WriteLiteral(""); + + + #line 196 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_ValueColumn); + + + #line default + #line hidden +WriteLiteral("
"); + + + #line 203 "ErrorPage.cshtml" + Write(kv.Key); + + + #line default + #line hidden +WriteLiteral(""); + + + #line 204 "ErrorPage.cshtml" + Write(kv.Value); + + + #line default + #line hidden +WriteLiteral("
\r\n"); + + + #line 209 "ErrorPage.cshtml" + } + else + { + + + #line default + #line hidden +WriteLiteral("

"); + + + #line 212 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_NoCookieData); + + + #line default + #line hidden +WriteLiteral("

\r\n"); + + + #line 213 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n"); + */ + + #line 215 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 216 "ErrorPage.cshtml" + if (Model.Options.ShowHeaders) + { + + + #line default + #line hidden +WriteLiteral(" \r\n"); + + + #line 219 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 219 "ErrorPage.cshtml" + if (Model.Headers.Any()) + { + + + #line default + #line hidden +WriteLiteral(" \r\n \r\n " + +" \r\n \r\n \r\n \r\n \r\n " + +" \r\n"); + + + #line 229 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 229 "ErrorPage.cshtml" + foreach (var kv in Model.Headers.OrderBy(kv => kv.Key)) + { + foreach (var v in kv.Value) + { + + + #line default + #line hidden +WriteLiteral(" \r\n " + +" \r\n \r\n \r\n"); + + + #line 237 "ErrorPage.cshtml" + } + } + + + #line default + #line hidden +WriteLiteral(" \r\n
"); + + + #line 224 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_VariableColumn); + + + #line default + #line hidden +WriteLiteral(""); + + + #line 225 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_ValueColumn); + + + #line default + #line hidden +WriteLiteral("
"); + + + #line 234 "ErrorPage.cshtml" + Write(kv.Key); + + + #line default + #line hidden +WriteLiteral(""); + + + #line 235 "ErrorPage.cshtml" + Write(v); + + + #line default + #line hidden +WriteLiteral("
\r\n"); + + + #line 241 "ErrorPage.cshtml" + } + else + { + + + #line default + #line hidden +WriteLiteral("

"); + + + #line 244 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_NoHeaderData); + + + #line default + #line hidden +WriteLiteral("

\r\n"); + + + #line 245 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n"); + + + #line 247 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" "); + + + #line 248 "ErrorPage.cshtml" + if (Model.Options.ShowEnvironment) + { + /* + + #line default + #line hidden +WriteLiteral(" \r\n \r\n \r\n " + +"\r\n \r\n \r\n \r\n \r\n " + +" \r\n"); + + + #line 259 "ErrorPage.cshtml" + + + #line default + #line hidden + + #line 259 "ErrorPage.cshtml" + foreach (var kv in Model.Environment.OrderBy(kv => kv.Key)) + { + + + #line default + #line hidden +WriteLiteral(" \r\n \r\n \r\n \r\n"); + + + #line 265 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n
"); + + + #line 254 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_VariableColumn); + + + #line default + #line hidden +WriteLiteral(""); + + + #line 255 "ErrorPage.cshtml" + Write(Resources.ErrorPageHtml_ValueColumn); + + + #line default + #line hidden +WriteLiteral("
"); + + + #line 262 "ErrorPage.cshtml" + Write(kv.Key); + + + #line default + #line hidden +WriteLiteral(""); + + + #line 263 "ErrorPage.cshtml" + Write(kv.Value); + + + #line default + #line hidden +WriteLiteral("
\r\n \r\n"); + + */ + #line 269 "ErrorPage.cshtml" + } + + + #line default + #line hidden +WriteLiteral(" \r\n \r\n //\r\n \r\n \r\n\r\n"); + + } + } +} + diff --git a/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.cshtml b/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.cshtml new file mode 100644 index 0000000000..d280bf966e --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.cshtml @@ -0,0 +1,281 @@ +@using System +@using System.Globalization +@using System.Linq +@using Views +@functions +{ + /// + /// + /// + public Views.ErrorPageModel Model { get; set; } +} +@{ + Response.StatusCode = 500; + // TODO: Response.ReasonPhrase = "Internal Server Error"; + Response.ContentType = "text/html"; + Response.ContentLength = null; // Clear any prior Content-Length + string location = string.Empty; +} + + + + + @Resources.ErrorPageHtml_Title + + + +

@Resources.ErrorPageHtml_UnhandledException

+ @if (Model.Options.ShowExceptionDetails) + { + foreach (var errorDetail in Model.ErrorDetails) + { +

@errorDetail.Error.GetType().Name: @errorDetail.Error.Message

+ { + StackFrame firstFrame = null; + firstFrame = errorDetail.StackFrames.FirstOrDefault(); + if (firstFrame != null) + { + location = firstFrame.Function; + }/* TODO: TargetSite is not defined + else if (errorDetail.Error.TargetSite != null && errorDetail.Error.TargetSite.DeclaringType != null) + { + location = errorDetail.Error.TargetSite.DeclaringType.FullName + "." + errorDetail.Error.TargetSite.Name; + }*/ + } + if (!string.IsNullOrEmpty(location) && firstFrame != null && !string.IsNullOrEmpty(firstFrame.File)) + { +

@location in @System.IO.Path.GetFileName(firstFrame.File), line @firstFrame.Line

+ } + else if (!string.IsNullOrEmpty(location)) + { +

@location

+ } + else + { +

@Resources.ErrorPageHtml_UnknownLocation

+ } + } + } + else + { +

@Resources.ErrorPageHtml_EnableShowExceptions

+ } + + @if (Model.Options.ShowExceptionDetails) + { +
+
    + @{ int tabIndex = 6; } + @foreach (var errorDetail in Model.ErrorDetails) + { +
  • +

    @errorDetail.Error.GetType().Name: @errorDetail.Error.Message

    +
      + @foreach (var frame in errorDetail.StackFrames) + { +
    • + @{ tabIndex++; } + @if (string.IsNullOrEmpty(frame.File)) + { +

      @frame.Function

      + } + else + { +

      @frame.Function in @System.IO.Path.GetFileName(frame.File)

      + } + + @if (frame.Line != 0 && frame.ContextCode != null) + { +
      + @if (frame.PreContextCode != null) + { +
        + @foreach (var line in frame.PreContextCode) + { +
      1. @line
      2. + } +
      + } + +
        +
      1. @frame.ContextCode
      + + @if (frame.PostContextCode != null) + { +
        + @foreach (var line in frame.PostContextCode) + { +
      1. @line
      2. + } +
      + } +
      + } +
    • + } +
    +
  • + } +
+
+ } + @if (Model.Options.ShowQuery) + { +
+ @if (Model.Query.Any()) + { + + + + + + + + + @foreach (var kv in Model.Query.OrderBy(kv => kv.Key)) + { + foreach (var v in kv.Value) + { + + + + + } + } + +
@Resources.ErrorPageHtml_VariableColumn@Resources.ErrorPageHtml_ValueColumn
@kv.Key@v
+ } + else + { +

@Resources.ErrorPageHtml_NoQueryStringData

+ } +
+ } + @if (Model.Options.ShowCookies) + { + /* TODO: +
+ @if (Model.Cookies.Any()) + { + + + + + + + + + @foreach (var kv in Model.Cookies.OrderBy(kv => kv.Key)) + { + + + + + } + +
@Resources.ErrorPageHtml_VariableColumn@Resources.ErrorPageHtml_ValueColumn
@kv.Key@kv.Value
+ } + else + { +

@Resources.ErrorPageHtml_NoCookieData

+ } +
+ */ + } + @if (Model.Options.ShowHeaders) + { +
+ @if (Model.Headers.Any()) + { + + + + + + + + + @foreach (var kv in Model.Headers.OrderBy(kv => kv.Key)) + { + foreach (var v in kv.Value) + { + + + + + } + } + +
@Resources.ErrorPageHtml_VariableColumn@Resources.ErrorPageHtml_ValueColumn
@kv.Key@v
+ } + else + { +

@Resources.ErrorPageHtml_NoHeaderData

+ } +
+ } + @if (Model.Options.ShowEnvironment) + { + /* TODO: +
+ + + + + + + + + @foreach (var kv in Model.Environment.OrderBy(kv => kv.Key)) + { + + + + + } + +
@Resources.ErrorPageHtml_VariableColumn@Resources.ErrorPageHtml_ValueColumn
@kv.Key@kv.Value
+
+ */ + } + + + + diff --git a/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.css b/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.css new file mode 100644 index 0000000000..d54619f7f7 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.css @@ -0,0 +1,172 @@ +body { + font-family: 'Segoe UI',Tahoma,Arial,Helvetica,sans-serif; + font-size: .813em; + line-height: 1.4em; + color: #222; +} + +h1, h2, h3, h4, h5 { + /*font-family: 'Segoe UI',Tahoma,Arial,Helvetica,sans-serif;*/ + font-weight: 100; +} + +h1 { + color: #44525e; + margin: 15px 0 15px 0; +} + +h2 { + margin: 10px 5px 0 0; +} + +h3 { + color: #363636; + margin: 5px 5px 0 0; +} + +code { + font-family: consolas, "Courier New", courier, monospace; +} + +body .titleerror { + padding: 3px; +} + +body .location { + margin: 3px 0 10px 30px; +} + +#header { + font-size: 18px; + padding-left: 0px; + padding-right: 0px; + padding-top: 15px; + padding-bottom: 15px; + border-top: 1px #ddd solid; + border-bottom: 1px #ddd solid; + margin-bottom: 0px; +} + +#header li { + display: inline; + margin: 5px; + padding: 5px; + color: #a0a0a0; +} + +#header li:hover { + background: #A9E4F9; + color: #fff; +} + +#header li.selected { + background: #44C5F2; + color: #fff; +} + +#stackpage ul { + list-style: none; + padding-left: 0; + margin: 0; + /*border-bottom: 1px #ddd solid;*/ +} + +#stackpage .stackerror { + padding: 5px; + border-bottom: 1px #ddd solid; +} + +#stackpage .stackerror:hover { + background-color: #f0f0f0; +} + +#stackpage .frame:hover { + background-color: #f0f0f0; + text-decoration: none; +} + +#stackpage .frame { + padding: 2px; + margin: 0 0 0 30px; + border-bottom: 1px #ddd solid; +} + +#stackpage .frame h3 { + padding: 5px; + margin: 0; +} + +#stackpage .source { + padding: 0px; +} + +#stackpage .source ol li { + font-family: consolas, "Courier New", courier, monospace; + white-space: pre; +} + +#stackpage .source ol.highlight li { + /*color: #e22;*/ + /*font-weight: bold;*/ +} + +#stackpage .source ol.highlight li span { + /*color: #000;*/ +} + +#stackpage .frame:hover .source ol.highlight li span { + color: #fff; + background: #B20000; +} + +#stackpage .source ol.collapsable li { + color: #888; +} + +#stackpage .source ol.collapsable li span { + color: #606060; +} + +.page table { + border-collapse: separate; + border-spacing: 0; + margin: 0 0 20px; +} + +.page th { + vertical-align: bottom; + padding: 10px 5px 5px 5px; + font-weight: 400; + color: #a0a0a0; + text-align: left; +} + +.page td { + padding: 3px 10px; +} + +.page th, .page td { + border-right: 1px #ddd solid; + border-bottom: 1px #ddd solid; + border-left: 1px transparent solid; + border-top: 1px transparent solid; + box-sizing: border-box; +} + +.page th:last-child, .page td:last-child { + border-right: 1px transparent solid; +} + +.page td.length { + text-align: right; +} + +a { + color: #1ba1e2; + text-decoration: none; +} + +a:hover { + color: #13709e; + text-decoration: underline; +} diff --git a/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.js b/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.js new file mode 100644 index 0000000000..f00df0918c --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.js @@ -0,0 +1,36 @@ + +(function ($) { + $('.collapsable').hide(); + $('.page').hide(); + $('#stackpage').show(); + + $('.frame').click(function () { + $(this).children('.source').children('.collapsable').toggle('fast'); + }); + + $('.frame').keypress(function (e) { + if (e.which == 13) { + $(this).children('.source').children('.collapsable').toggle('fast'); + } + }); + + $('#header li').click(function () { + + var unselected = $('#header .selected').removeClass('selected').attr('id'); + var selected = $(this).addClass('selected').attr('id'); + + $('#' + unselected + 'page').hide(); + $('#' + selected + 'page').show('fast'); + }); + + $('#header li').keypress(function (e) { + if (e.which == 13) { + var unselected = $('#header .selected').removeClass('selected').attr('id'); + var selected = $(this).addClass('selected').attr('id'); + + $('#' + unselected + 'page').hide(); + $('#' + selected + 'page').show('fast'); + } + }); + +})(jQuery); diff --git a/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.tt b/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.tt new file mode 100644 index 0000000000..ca629b1435 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Views/ErrorPage.tt @@ -0,0 +1,51 @@ +<#@ template debug="false" hostspecific="true" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Web.Razor" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Globalization" #> +<#@ import namespace="System.IO" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Web.Razor" #> +<#@ import namespace="System.Web.Razor.Text" #> +<#@ output extension=".cs" #> +<# +var host = new RazorEngineHost(new CSharpRazorCodeLanguage()); +host.DefaultBaseClass = "Microsoft.Owin.Diagnostics.Views.BaseView"; +var engine = new RazorTemplateEngine(host); +var path = Host.ResolvePath("ErrorPage.cshtml"); + +var code = engine.GenerateCode( + new System.IO.StreamReader(path), + "ErrorPage", + "Microsoft.Owin.Diagnostics.Views", + @"ErrorPage.cshtml"); + +var provider = new Microsoft.CSharp.CSharpCodeProvider(); +var writer = new System.IO.StringWriter(); +provider.GenerateCodeFromCompileUnit(code.GeneratedCode, writer, null); +var source = writer.ToString(); +var startIndex = 0; +while(startIndex < source.Length) +{ + var startMatch = @"Write(@""[["; + var startCode = @"WriteLiteral(@"""; + var endMatch = @"]]"");"; + var endCode = @""");"; + startIndex = source.IndexOf(startMatch, startIndex); + if (startIndex == -1) + { + break; + } + var endIndex = source.IndexOf(endMatch, startIndex); + if (endIndex == -1) + { + break; + } + var fileName = source.Substring(startIndex + startMatch.Length, endIndex - (startIndex + startMatch.Length)); + var replacement = File.ReadAllText(Host.ResolvePath(fileName)).Replace("\"", "\"\""); + source = source.Substring(0, startIndex) + startCode + replacement + endCode + source.Substring(endIndex + endMatch.Length); + startIndex = startIndex + startCode.Length + replacement.Length + endCode.Length; + } +#> +<#=source#> diff --git a/src/Microsoft.AspNet.Diagnostics/Views/ErrorPageModel.cs b/src/Microsoft.AspNet.Diagnostics/Views/ErrorPageModel.cs new file mode 100644 index 0000000000..cb2f5f63c8 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Views/ErrorPageModel.cs @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using Microsoft.AspNet.Abstractions; +using System; +using System.Collections.Generic; + +namespace Microsoft.AspNet.Diagnostics.Views +{ + /// + /// Holds data to be displayed on the error page. + /// + public class ErrorPageModel + { + /// + /// Options for what output to display. + /// + public ErrorPageOptions Options { get; set; } + + /// + /// Detailed information about each exception in the stack + /// + public IEnumerable ErrorDetails { get; set; } + + /// + /// Parsed query data + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Model class contains collection")] + public IReadableStringCollection Query { get; set; } + + /* TODO: + /// + /// Request cookies + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Model class contains collection")] + public RequestCookieCollection Cookies { get; set; } + */ + /// + /// Request headers + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Model class contains collection")] + public IDictionary Headers { get; set; } + /* TODO: + /// + /// The request environment + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Model class contains collection")] + public HttpContext Environment { get; set; } + */ + } +} diff --git a/src/Microsoft.AspNet.Diagnostics/Views/StackFrame.cs b/src/Microsoft.AspNet.Diagnostics/Views/StackFrame.cs new file mode 100644 index 0000000000..5f962ccefb --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Views/StackFrame.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System.Collections.Generic; + +namespace Microsoft.AspNet.Diagnostics.Views +{ + /// + /// Detailed exception stack information used to generate a view + /// + public class StackFrame + { + /// + /// Function containing instruction + /// + public string Function { get; set; } + + /// + /// File containing the instruction + /// + public string File { get; set; } + + /// + /// The line number of the instruction + /// + public int Line { get; set; } + + /// + /// The line preceeding the frame line + /// + public int PreContextLine { get; set; } + + /// + /// + /// + public IEnumerable PreContextCode { get; set; } + + /// + /// + /// + public string ContextCode { get; set; } + + /// + /// + /// + public IEnumerable PostContextCode { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Diagnostics/Views/WelcomePage.cs b/src/Microsoft.AspNet.Diagnostics/Views/WelcomePage.cs new file mode 100644 index 0000000000..5c22877b46 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Views/WelcomePage.cs @@ -0,0 +1,3953 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.34006 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.AspNet.Diagnostics.Views { + + #line 1 "WelcomePage.cshtml" + using System; + + #line default + #line hidden + + + public class WelcomePage : Microsoft.AspNet.Diagnostics.Views.BaseView { + +#line hidden + + public WelcomePage() { + } + + public override void Execute() { + + #line 2 "WelcomePage.cshtml" + + Response.ContentType = "text/html"; + + + #line default + #line hidden +WriteLiteral("\r\n\r\n(System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName + + #line default + #line hidden +, 92), false) +); + +WriteLiteral(">\r\n\r\n \r\n "); + + + #line 9 "WelcomePage.cshtml" + Write(Resources.WelcomeTitle); + + + #line default + #line hidden +WriteLiteral("\r\n \r\n "); + +WriteLiteral("@font-face {\r\n font-family: \'SegoeLight\';\r\n src: url(//:) f" + +"ormat(\'no404\'), url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAFbcABAAAAAA" + +"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" + +"ZhtsdTV9sO3/GJOrXk9IZ1sA) format(\'woff\'), url(data:font/truetype;charset=utf-8;b" + +"ase64,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" + +"cAAAAIAAIAAAAAAAAAAQAAB2f99wAACAD/BP+uCAAAAQAAAAAAAAAAAAAAAAAAAOsEAACAAAAAAAKqAA" + +"ACMQAAAkYA0wKuAKwE1QA1BB8AogZGAFIFkwCNAbYArAJCAJYCQgAXAz8ARgUzANUBxwAvAy8AkQHHAJ" + +"MC7v/jBB8AXgQfAJMEHwBSBB8AcwQfAB0EHwCcBB8AewQfAFoEHwBtBB8AZgHHAJMBxwAvBTMA+gUzAN" + +"UFMwD6A3EAZAeNAKgFCAA7BFoAuAT4AG0FZAC4BAAAuAO4ALgFWABtBWoAuAHTALgCmAASBDcAuAOqAL" + +"gGqgC4BawAuAYXAG0EWgC4BhcAbQRxALgD+gCLBBcAPQUvAKYE1QApBykAMwSBAD0EUgA9BI8AQgJCAN" + +"EC7v/jAkIAMwUzAQQDUgAAAfwATAP0AGoEewCkA40AWgR7AFoECgBaAjUAIwR7AFoESACkAaQAhQGk/w" + +"QDjQCkAaQApAaTAKQESACkBH0AWgR7AKQEewBaAqQApAMbAG8CYAAXBEgAjwOgABQFagAlA14AIQOgAB" + +"QDtgA5AkIAXgHPALgCQgBIBTMA9gIxAAACRgDTBB8ApgQfAFAEcwCFBB8ASgHPALgDlgCmAzEAqgcMAJ" + +"wC6QBMA7gAewUzANUDLwCRBwwAnANSAFIDFwCPBTMA1QKiAE4CogBYAfwAiQRcAKQDywBxAccAkwGcAD" + +"kCogBzAysASAO4AHkF6QBzBlYAcwXpAFgDcQBzBQgAOwUIADsFCAA7BQgAOwUIADsFCAA7BqoAEAT4AG" + +"0EAAC4BAAAuAQAALgEAAC4AdMAEgHTAHIB0//5AdP//QVkACMFrAC4BhcAbQYXAG0GFwBtBhcAbQYXAG" + +"0FMwEQBhcAVAUvAKYFLwCmBS8ApgUvAKYEUgA9BFoAuAQlAKQD9ABqA/QAagP0AGoD9ABqA/QAagP0AG" + +"oGtgBqA40AWgQKAFoECgBaBAoAWgQKAFoBpAAGAaQAUwGk/+IBpP/kBEIAWgRIAKQEfQBaBH0AWgR9AF" + +"oEfQBaBH0AWgUzANUEfQAdBEgAjwRIAI8ESACPBEgAjwOgABQEewCkA6AAFAGkAKQHjwBtB14AWgRSAK" + +"wC/gCBAlIAYAKJACkDswAAB2cAAAOzAAAHZwAAAncAAAHZAAABOwAAATsAAADsAAABewAAAGkAAAMvAJ" + +"EDLwCRAy8AkQQAAAAIAAAAAbYAcQG2AHEBtgBOAq4AcQKuAHECrgBOAysApAVUAI0BewAAAnsAewJ7AH" + +"sB2QAABB8ATgYxAEYEAQAAA9kAIwPZACMGDgAjAAAALAAsACwALABqAJoBdgHuAqIDagOKA7oD6AQqBG" + +"wEngS8BOYFFgVkBawGCgZ4BuQHPAeuB+gIXgjQCQ4JYAmoCcoKEgp8C0gL3gxKDJIM0g0ODUQNrg3mDg" + +"QOMg6cDsIPPg+cD/QQOBC2ESoRjhG+EfYSUhLyE7AUDhRKFHgUqhTcFSgVQBVwFfgWVBaYFvQXThecGB" + +"AYVhiWGOQZSBlmGc4aEhpeGrobFhtSG7QcBhxKHKQdQh4WHrAe7B9MH2gfyCAYIBggVCDGISgiCiKgIs" + +"YjViOUJCoksiUyJVoleCY8JkYmkCbgJ0gntifkKDAocCiYKN4pJiluKewqtiuELH4s6Cz0LQAtDC0YLS" + +"Qt6C5gLvAu/C8ILxQvIC8sLzgvRC9QL7Ivvi/KL9Yv4i/uL/owmDFqMXYxgjGOMZoxpjHwMmoydjKCMo" + +"4ymjKmMrIzYjPuM/o0BjQSNB40KjQ2NEI0TjUINRQ1IDUsNTg1RDVQNZY2WDZkNnA2fDaINpQ28Db8Nx" + +"o3kjgwODw4jDjaOSI5IjkiOSI5IjkiOSI5IjkiOSI5IjkiOUA5Xjl8OZQ5rDnKOeg6Bjo0OmI6kDq+Ox" + +"Y7FjtgO6g7qDwsPLY8xD1GPag9uAABAAAA6wA+AAUAOwAEAAIAAQACABYAAAEAAVYAAwABAAAACABmAA" + +"MAAQQJAAAAZAAAAAMAAQQJAAEACgBkAAMAAQQJAAIACgBuAAMAAQQJAAMADgB4AAMAAQQJAAQAFgCGAA" + +"MAAQQJAAUAGACcAAMAAQQJAAYAFgC0AAMAAQQJAMgAbgDKAKkAIAAyADAAMAA2ACAATQBpAGMAcgBvAH" + +"MAbwBmAHQAIABDAG8AcgBwAG8AcgBhAHQAaQBvAG4ALgAgAEEAbABsACAAUgBpAGcAaAB0AHMAIABSAG" + +"UAcwBlAHIAdgBlAGQALgBTAGUAZwBvAGUATABpAGcAaAB0AHcAZQBiAGYAbwBuAHQAUwBlAGcAbwBlAC" + +"AATABpAGcAaAB0AFYAZQByAHMAaQBvAG4AIAAyAC4AMgAwAFMAZQBnAG8AZQAtAEwAaQBnAGgAdABUAG" + +"gAaQBzACAAZgBvAG4AdAAgAHcAYQBzACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIAB0AGgAZQAgAE" + +"YAbwBuAHQAIABTAHEAdQBpAHIAcgBlAGwAIABHAGUAbgBlAHIAYQB0AG8AcgAuAAAAAgAAAAAAAP9OAH" + +"cAAAAAAAAAAAAAAAAAAAAAAAAAAADrAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARAB" + +"IAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwECAQMALgAvAD" + +"AAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQA+AD8AQABBAEIAQwBEAEUARgBHAEgASQBKAEsBBAEFAE" + +"4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoAWwBcAF0AXgBfAGAAYQEGAKMAhACFAL0AlgDoAIYAjgCLAJ" + +"0AqQCkAQcAigDaAIMAkwEIAQkAjQEKAIgAwwDeAQsAngCqAPUA9AD2AKIArQDJAMcArgBiAGMAkABkAM" + +"sAZQDIAMoAzwDMAM0AzgDpAGYA0wDQANEArwBnAPAAkQDWANQA1QBoAOsA7QCJAGoAaQBrAG0AbABuAK" + +"AAbwBxAHAAcgBzAHUAdAB2AHcA6gB4AHoAeQB7AH0AfAC4AKEAfwB+AIAAgQDsAO4AugDXALAAsQC7AN" + +"gA3QDZAQwBDQEOAQ8BEAERARIBEwEUARUBFgEXARgBGQCyALMAtgC3AMQAtAC1AMUAhwCrARoAvgC/AR" + +"sBHACMAR0BHgEfASAJYWZpaTEwMDU1CWFmaWkxMDA1NwlhZmlpMTAxMDMJYWZpaTEwMTA1B3VuaTAwQT" + +"AHdW5pMDBBRAd1bmkwMEIyB3VuaTAwQjMHdW5pMDBCNQd1bmkwMEI5B3VuaTIwMDAHdW5pMjAwMQd1bm" + +"kyMDAyB3VuaTIwMDMHdW5pMjAwNAd1bmkyMDA1B3VuaTIwMDYHdW5pMjAwNwd1bmkyMDA4B3VuaTIwMD" + +"kHdW5pMjAwQQd1bmkyMDEwB3VuaTIwMTEKZmlndXJlZGFzaAd1bmkyMDJGB3VuaTIwNUYERXVybwd1bm" + +"lFMDAwB3VuaUZCMDEHdW5pRkIwMgd1bmlGQjA0uAH/hbABjQBLsAhQWLEBAY5ZsUYGK1ghsBBZS7AUUl" + +"ghsIBZHbAGK1xYALAFIEWwAytEsAggRboABQQMAAIrsAMrRLAHIEWyCCUCK7ADK0SwBiBFsge4AiuwAy" + +"tEsAkgRbIFtgIrsAMrRLAKIEWyCZ4CK7ADK0SwCyBFsgqcAiuwAytEsAwgRbILawIrsAMrRLANIEWyDF" + +"QCK7ADK0SwDiBFsg1RAiuwAytEsA8gRbIOIgIrsAMrRLAQIEWyDxsCK7ADK0QBsBEgRbADK0SwEiBFsh" + +"GbAiuxA0Z2K0SwEyBFugARf/8AAiuxA0Z2K0SwFCBFugATARcAAiuxA0Z2K0SwFSBFshSFAiuxA0Z2K0" + +"SwFiBFshVcAiuxA0Z2K0SwFyBFshZFAiuxA0Z2K0SwGCBFshcwAiuxA0Z2K0SwGSBFshgvAiuxA0Z2K0" + +"SwGiBFshkeAiuxA0Z2K0SwGyBFshobAiuxA0Z2K0RZsBQrAAA=) format(\'truetype\'), url(\'seg" + +"oel-webfont.svg#webfontPKyR4Ica\') format(\'svg\');\r\n font-weight: norma" + +"l;\r\n font-style: normal;\r\n }\r\n\r\n body {\r\n ba" + +"ckground-color: #00abec;\r\n color: #fff;\r\n font-family: \'Se" + +"goeLight\', helvetica, sans-serif;\r\n font-size: 18px;\r\n mar" + +"gin: 0;\r\n padding: 0;\r\n }\r\n\r\n .content {\r\n p" + +"osition: absolute;\r\n left: 50px;\r\n top: 38px;\r\n " + +" width: 400px;\r\n }\r\n\r\n .content .azureLogo {\r\n " + +"margin: 0 0 65px 0;\r\n }\r\n\r\n .content .bodyHeadline {\r\n " + +" margin: 35px 0 0;\r\n font-size: 40px;\r\n " + +" line-height: 43px;\r\n }\r\n\r\n .content .bodyContent {\r\n " + +" margin: 10px 0 30px 0;\r\n line-height: 22px;\r\n " + +" }\r\n\r\n .content .bodyContent a {\r\n color: #f" + +"ff;\r\n text-decoration: none;\r\n }\r\n\r\n " + +" .content .bodyContent a:hover {\r\n opacity: .7;\r" + +"\n }\r\n\r\n .content .bodyCTA {\r\n color" + +": #fff;\r\n display: block;\r\n line-height: 30px;\r\n " + +" height: 29px;\r\n width: 230px;\r\n curs" + +"or: pointer;\r\n text-decoration: none;\r\n position: " + +"relative;\r\n }\r\n\r\n .content .bodyCTA.longer {\r\n " + +" margin-top: 10px;\r\n width: 430px;\r\n " + +" }\r\n\r\n .content .bodyCTA div {\r\n position: ab" + +"solute;\r\n overflow: hidden;\r\n width: 29px;" + +"\r\n height: 29px;\r\n float: right;\r\n " + +" top: 0;\r\n right: 0;\r\n }\r\n\r\n " + +" .content .bodyCTA div img {\r\n position: abso" + +"lute;\r\n top: 0;\r\n left: 0;\r\n " + +" border: 0;\r\n }\r\n\r\n .content " + +".bodyCTA:hover div img {\r\n left: -29px;\r\n }\r\n\r" + +"\n .content .bodyCTA:hover {\r\n opacity: .7;\r\n " + +" }\r\n\r\n .wrapper {\r\n width: 100%;\r\n hei" + +"ght: 100%;\r\n overflow: hidden;\r\n min-width: 1200px;\r\n " + +" }\r\n\r\n .innerwrapper {\r\n width: 384px;\r\n height: " + +"100%;\r\n margin-right: auto;\r\n margin-left: auto;\r\n " + +"}\r\n\r\n .browser {\r\n position: absolute;\r\n display: b" + +"lock;\r\n top: 400px;\r\n width: 384px;\r\n height: 3" + +"05px;\r\n cursor: pointer;\r\n z-index: 10;\r\n }\r\n\r\n " + +" .browser div {\r\n width: 384px;\r\n height: 3" + +"05px;\r\n position: absolute;\r\n top: 40px;\r\n " + +" left: 100px;\r\n font-size: 200px;\r\n text-al" + +"ign: left;\r\n -webkit-touch-callout: none;\r\n -webki" + +"t-user-select: none;\r\n -khtml-user-select: none;\r\n " + +" -moz-user-select: none;\r\n -ms-user-select: none;\r\n " + +" user-select: none;\r\n }\r\n\r\n .bulb {\r\n position: fi" + +"xed;\r\n margin-left: 20px;\r\n top: 0;\r\n }\r\n\r\n " + +".light {\r\n position: fixed;\r\n margin-left: 53px;\r\n " + +" top: 0;\r\n opacity: 0;\r\n }\r\n\r\n .bottom {\r\n " + +" position: fixed;\r\n bottom: 0;\r\n margin-right: auto;\r\n " + +" margin-left: -303px;\r\n z-index: -1;\r\n height: 202" + +"px;\r\n }\r\n \r\n \r\n\r\n\r\n \r\n \r\n \r\n (Resources.WelcomePageImageText_LightBulb + + #line default + #line hidden +, 250499), false) +); + +WriteAttribute("title", Tuple.Create(" title=\"", 250541), Tuple.Create("\"", 250590) + + #line 291 "WelcomePage.cshtml" +, Tuple.Create(Tuple.Create("", 250549), Tuple.Create(Resources.WelcomePageImageText_LightBulb + + #line default + #line hidden +, 250549), false) +); + +WriteLiteral(" width=\"274\""); + +WriteLiteral(" height=\"274\""); + +WriteLiteral(" />\r\n \r\n (Resources.WelcomePageImageText_Browser + + #line default + #line hidden +, 253697), false) +); + +WriteAttribute("title", Tuple.Create(" title=\"", 253737), Tuple.Create("\"", 253784) + + #line 294 "WelcomePage.cshtml" +, Tuple.Create(Tuple.Create("", 253745), Tuple.Create(Resources.WelcomePageImageText_Browser + + #line default + #line hidden +, 253745), false) +); + +WriteLiteral(" width=\"384\""); + +WriteLiteral(" height=\"305\""); + +WriteLiteral(" />
:-|
\r\n \r\n \r\n (Resources.WelcomePageImageText_LightBulb + + #line default + #line hidden +, 260233), false) +); + +WriteAttribute("title", Tuple.Create(" title=\"", 260275), Tuple.Create("\"", 260324) + + #line 298 "WelcomePage.cshtml" +, Tuple.Create(Tuple.Create("", 260283), Tuple.Create(Resources.WelcomePageImageText_LightBulb + + #line default + #line hidden +, 260283), false) +); + +WriteLiteral(" width=\"274\""); + +WriteLiteral(" height=\"274\""); + +WriteLiteral(" />\r\n \r\n (Resources.WelcomePageImageText_LightBulb + + #line default + #line hidden +, 269125), false) +); + +WriteAttribute("title", Tuple.Create(" title=\"", 269167), Tuple.Create("\"", 269216) + + #line 301 "WelcomePage.cshtml" +, Tuple.Create(Tuple.Create("", 269175), Tuple.Create(Resources.WelcomePageImageText_LightBulb + + #line default + #line hidden +, 269175), false) +); + +WriteLiteral(" width=\"346\""); + +WriteLiteral(" height=\"658\""); + +WriteLiteral(" />\r\n \r\n (Resources.WelcomePageImageText_Skyline + + #line default + #line hidden +, 284091), false) +); + +WriteAttribute("title", Tuple.Create(" title=\"", 284131), Tuple.Create("\"", 284178) + + #line 304 "WelcomePage.cshtml" +, Tuple.Create(Tuple.Create("", 284139), Tuple.Create(Resources.WelcomePageImageText_Skyline + + #line default + #line hidden +, 284139), false) +); + +WriteLiteral(" width=\"1212\""); + +WriteLiteral(" height=\"202\""); + +WriteLiteral(" />\r\n \r\n \r\n\r\n \r\n "); + + + #line 309 "WelcomePage.cshtml" + Write(Resources.WelcomeHeader); + + + #line default + #line hidden +WriteLiteral("\r\n "); + + + #line 310 "WelcomePage.cshtml" + Write(Resources.WelcomeStarted); + + + #line default + #line hidden +WriteLiteral("\r\n "); + + + #line 311 "WelcomePage.cshtml" + Write(Resources.WelcomeLearnOwin); + + + #line default + #line hidden +WriteLiteral("\r\n
\r\n (Resources.WelcomePageImageText_LearnMore + + #line default + #line hidden +, 287037), false) +); + +WriteAttribute("title", Tuple.Create(" title=\"", 287079), Tuple.Create("\"", 287128) + + #line 314 "WelcomePage.cshtml" +, Tuple.Create(Tuple.Create("", 287087), Tuple.Create(Resources.WelcomePageImageText_LearnMore + + #line default + #line hidden +, 287087), false) +); + +WriteLiteral(" width=\"58\""); + +WriteLiteral(" height=\"29\""); + +WriteLiteral(" />
\r\n \r\n "); + + + #line 316 "WelcomePage.cshtml" + Write(Resources.WelcomeLearnMicrosoftOwin); + + + #line default + #line hidden +WriteLiteral("
\r\n (Resources.WelcomePageImageText_LearnMore + + #line default + #line hidden +, 289803), false) +); + +WriteAttribute("title", Tuple.Create(" title=\"", 289845), Tuple.Create("\"", 289894) + + #line 318 "WelcomePage.cshtml" +, Tuple.Create(Tuple.Create("", 289853), Tuple.Create(Resources.WelcomePageImageText_LearnMore + + #line default + #line hidden +, 289853), false) +); + +WriteLiteral(" width=\"58\""); + +WriteLiteral(" height=\"29\""); + +WriteLiteral(" />
\r\n \r\n \r\n\r\n\r\n\r\n"); + + } + } +} + diff --git a/src/Microsoft.AspNet.Diagnostics/Views/WelcomePage.cshtml b/src/Microsoft.AspNet.Diagnostics/Views/WelcomePage.cshtml new file mode 100644 index 0000000000..aad90f6533 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Views/WelcomePage.cshtml @@ -0,0 +1,323 @@ +@using System +@{ + Response.ContentType = "text/html"; +} + + + + + @Resources.WelcomeTitle + + + + +
+
+
+ @Resources.WelcomePageImageText_LightBulb
+
+ @Resources.WelcomePageImageText_Browser
:-|
+
+
+ @Resources.WelcomePageImageText_LightBulb
+
+ @Resources.WelcomePageImageText_LightBulb
+
+ @Resources.WelcomePageImageText_Skyline
+
+
+ +
+
@Resources.WelcomeHeader
+
@Resources.WelcomeStarted
+ @Resources.WelcomeLearnOwin +
+ @Resources.WelcomePageImageText_LearnMore
+
+ @Resources.WelcomeLearnMicrosoftOwin
+ @Resources.WelcomePageImageText_LearnMore
+
+
+ + + diff --git a/src/Microsoft.AspNet.Diagnostics/Views/WelcomePage.tt b/src/Microsoft.AspNet.Diagnostics/Views/WelcomePage.tt new file mode 100644 index 0000000000..3808f5d431 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/Views/WelcomePage.tt @@ -0,0 +1,50 @@ +<#@ template debug="false" hostspecific="true" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Web.Razor" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.IO" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Web.Razor" #> +<#@ import namespace="System.Web.Razor.Text" #> +<#@ output extension=".cs" #> +<# +var host = new RazorEngineHost(new CSharpRazorCodeLanguage()); +host.DefaultBaseClass = "Microsoft.Owin.Diagnostics.Views.BaseView"; +var engine = new RazorTemplateEngine(host); +var path = Host.ResolvePath("WelcomePage.cshtml"); + +var code = engine.GenerateCode( + new System.IO.StreamReader(path), + "WelcomePage", + "Microsoft.Owin.Diagnostics.Views", + "WelcomePage.cshtml"); + +var provider = new Microsoft.CSharp.CSharpCodeProvider(); +var writer = new System.IO.StringWriter(); +provider.GenerateCodeFromCompileUnit(code.GeneratedCode, writer, null); +var source = writer.ToString(); +var startIndex = 0; +while(startIndex < source.Length) +{ + var startMatch = @"Write(@""[["; + var startCode = @"WriteLiteral(@"""; + var endMatch = @"]]"");"; + var endCode = @""");"; + startIndex = source.IndexOf(startMatch, startIndex); + if (startIndex == -1) + { + break; + } + var endIndex = source.IndexOf(endMatch, startIndex); + if (endIndex == -1) + { + break; + } + var fileName = source.Substring(startIndex + startMatch.Length, endIndex - (startIndex + startMatch.Length)); + var replacement = File.ReadAllText(Host.ResolvePath(fileName)).Replace("\"", "\"\""); + source = source.Substring(0, startIndex) + startCode + replacement + endCode + source.Substring(endIndex + endMatch.Length); + startIndex = startIndex + startCode.Length + replacement.Length + endCode.Length; + } +#> +<#=source#> diff --git a/src/Microsoft.AspNet.Diagnostics/WelcomePageExtensions.cs b/src/Microsoft.AspNet.Diagnostics/WelcomePageExtensions.cs new file mode 100644 index 0000000000..711bb33b17 --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/WelcomePageExtensions.cs @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Abstractions; +using Microsoft.AspNet.Diagnostics; + +namespace Microsoft.AspNet +{ + /// + /// IBuilder extensions for the WelcomePageMiddleware. + /// + public static class WelcomePageExtensions + { + /// + /// Adds the WelcomePageMiddleware to the pipeline with the given options. + /// + /// + /// + /// + public static IBuilder UseWelcomePage(this IBuilder builder, WelcomePageOptions options) + { + if (builder == null) + { + throw new ArgumentNullException("builder"); + } + + return builder.Use(next => new WelcomePageMiddleware(next, options).Invoke); + } + + /// + /// Adds the WelcomePageMiddleware to the pipeline with the given path. + /// + /// + /// + /// + public static IBuilder UseWelcomePage(this IBuilder builder, PathString path) + { + return UseWelcomePage(builder, new WelcomePageOptions { Path = path }); + } + + /// + /// Adds the WelcomePageMiddleware to the pipeline with the given path. + /// + /// + /// + /// + public static IBuilder UseWelcomePage(this IBuilder builder, string path) + { + return UseWelcomePage(builder, new WelcomePageOptions { Path = new PathString(path) }); + } + + /// + /// Adds the WelcomePageMiddleware to the pipeline. + /// + /// + /// + public static IBuilder UseWelcomePage(this IBuilder builder) + { + return UseWelcomePage(builder, new WelcomePageOptions()); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Diagnostics/WelcomePageMiddleware.cs b/src/Microsoft.AspNet.Diagnostics/WelcomePageMiddleware.cs new file mode 100644 index 0000000000..a37b92cd7e --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/WelcomePageMiddleware.cs @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.AspNet.Diagnostics.Views; +using Microsoft.AspNet.Abstractions; + +namespace Microsoft.AspNet.Diagnostics +{ + /// + /// This middleware provides a default web page for new applications. + /// + public class WelcomePageMiddleware + { + private readonly RequestDelegate _next; + private readonly WelcomePageOptions _options; + + /// + /// Creates a default web page for new applications. + /// + /// + /// + public WelcomePageMiddleware(RequestDelegate next, WelcomePageOptions options) + { + if (next == null) + { + throw new ArgumentNullException("next"); + } + if (options == null) + { + throw new ArgumentNullException("options"); + } + + _next = next; + _options = options; + } + + /// + /// Process an individual request. + /// + /// + /// + public Task Invoke(HttpContext context) + { + HttpRequest request = context.Request; + if (!_options.Path.HasValue || _options.Path == request.Path) + { + // Dynamically generated for LOC. + var welcomePage = new WelcomePage(); + welcomePage.Execute(context); + return Task.FromResult(0); + } + + return _next(context); + } + } +} diff --git a/src/Microsoft.AspNet.Diagnostics/WelcomePageOptions.cs b/src/Microsoft.AspNet.Diagnostics/WelcomePageOptions.cs new file mode 100644 index 0000000000..1ea64b6b2d --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/WelcomePageOptions.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using Microsoft.AspNet.Abstractions; + +namespace Microsoft.AspNet.Diagnostics +{ + /// + /// Options for the WelcomePageMiddleware. + /// + public class WelcomePageOptions + { + /// + /// Specifies which requests paths will be responded to. Exact matches only. Leave null to handle all requests. + /// + public PathString Path { get; set; } + } +} diff --git a/src/Microsoft.AspNet.Diagnostics/project.json b/src/Microsoft.AspNet.Diagnostics/project.json new file mode 100644 index 0000000000..fd27f24aff --- /dev/null +++ b/src/Microsoft.AspNet.Diagnostics/project.json @@ -0,0 +1,32 @@ +{ + "version": "0.1-alpha-*", + "dependencies": { + "Microsoft.AspNet.DependencyInjection": "0.1-alpha-*", + "Microsoft.AspNet.ConfigurationModel": "0.1-alpha-*", + "Microsoft.AspNet.PipelineCore": "0.1-alpha-*", + "Microsoft.AspNet.Abstractions": "0.1-alpha-*", + "Microsoft.AspNet.FeatureModel": "0.1-alpha-*" + }, + "configurations": { + "net45": {}, + "k10": { + "dependencies": { + "System.Collections": "4.0.0.0", + "System.ComponentModel": "4.0.0.0", + "System.Diagnostics.Debug": "4.0.10.0", + "System.Diagnostics.Tools": "4.0.0.0", + "System.Globalization": "4.0.10.0", + "System.IO": "4.0.0.0", + "System.IO.FileSystem": "4.0.0.0", + "System.IO.FileSystem.Primitives": "4.0.0.0", + "System.Linq": "4.0.0.0", + "System.Reflection": "4.0.10.0", + "System.Resources.ResourceManager": "4.0.0.0", + "System.Runtime": "4.0.20.0", + "System.Runtime.Extensions": "4.0.10.0", + "System.Threading": "4.0.0.0", + "System.Threading.Tasks": "4.0.0.0" + } + } + } +} \ No newline at end of file