From abdb2c3588482b14526830dba9304190a65f8adf Mon Sep 17 00:00:00 2001 From: Chris R Date: Wed, 20 May 2015 09:10:28 -0700 Subject: [PATCH 1/5] Add build infrastructure. --- .gitattributes | 50 ++++++++++++++++++++++++++++++++++++++++++++ .gitignore | 26 +++++++++++++++++++++++ NuGet.Config | 7 +++++++ NuGet.master.config | 7 +++++++ NuGet.release.config | 7 +++++++ build.cmd | 28 +++++++++++++++++++++++++ build.sh | 38 +++++++++++++++++++++++++++++++++ makefile.shade | 7 +++++++ 8 files changed, 170 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 NuGet.Config create mode 100644 NuGet.master.config create mode 100644 NuGet.release.config create mode 100644 build.cmd create mode 100644 build.sh create mode 100644 makefile.shade diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..bdaa5ba --- /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 0000000..216e8d9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +[Oo]bj/ +[Bb]in/ +TestResults/ +.nuget/ +*.sln.ide/ +_ReSharper.*/ +packages/ +artifacts/ +PublishProfiles/ +*.user +*.suo +*.cache +*.docstates +_ReSharper.* +nuget.exe +*net45.csproj +*net451.csproj +*k10.csproj +*.psess +*.vsp +*.pidb +*.userprefs +*DS_Store +*.ncrunchsolution +*.*sdf +*.ipch \ No newline at end of file diff --git a/NuGet.Config b/NuGet.Config new file mode 100644 index 0000000..46c3b3e --- /dev/null +++ b/NuGet.Config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/NuGet.master.config b/NuGet.master.config new file mode 100644 index 0000000..e2edffc --- /dev/null +++ b/NuGet.master.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/NuGet.release.config b/NuGet.release.config new file mode 100644 index 0000000..1978dc0 --- /dev/null +++ b/NuGet.release.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/build.cmd b/build.cmd new file mode 100644 index 0000000..41025af --- /dev/null +++ b/build.cmd @@ -0,0 +1,28 @@ +@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 + +IF "%SKIP_DNX_INSTALL%"=="1" goto run +CALL packages\KoreBuild\build\dnvm upgrade -runtime CLR -arch x86 +CALL packages\KoreBuild\build\dnvm install default -runtime CoreCLR -arch x86 + +:run +CALL packages\KoreBuild\build\dnvm use default -runtime CLR -arch x86 +packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %* diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..c8cc2a7 --- /dev/null +++ b/build.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +if test `uname` = Darwin; then + cachedir=~/Library/Caches/KBuild +else + if [ -z $XDG_DATA_HOME ]; then + cachedir=$HOME/.local/share + else + cachedir=$XDG_DATA_HOME; + fi +fi +mkdir -p $cachedir + +url=https://www.nuget.org/nuget.exe + +if test ! -f $cachedir/nuget.exe; then + wget -O $cachedir/nuget.exe $url 2>/dev/null || curl -o $cachedir/nuget.exe --location $url /dev/null +fi + +if test ! -e .nuget; then + mkdir .nuget + cp $cachedir/nuget.exe .nuget/nuget.exe +fi + +if test ! -d packages/KoreBuild; then + mono .nuget/nuget.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre + mono .nuget/nuget.exe install Sake -version 0.2 -o packages -ExcludeVersion +fi + +if ! type dnvm > /dev/null 2>&1; then + source packages/KoreBuild/build/dnvm.sh +fi + +if ! type dnx > /dev/null 2>&1; then + dnvm upgrade +fi + +mono packages/Sake/tools/Sake.exe -I packages/KoreBuild/build -f makefile.shade "$@" diff --git a/makefile.shade b/makefile.shade new file mode 100644 index 0000000..562494d --- /dev/null +++ b/makefile.shade @@ -0,0 +1,7 @@ + +var VERSION='0.1' +var FULL_VERSION='0.1' +var AUTHORS='Microsoft Open Technologies, Inc.' + +use-standard-lifecycle +k-standard-goals From 24f67ed79965c4bf7220147af3432db0b0893e8f Mon Sep 17 00:00:00 2001 From: Chris R Date: Fri, 22 May 2015 12:53:34 -0700 Subject: [PATCH 2/5] Rough outline of middleware, sample, and test projects. --- .gitignore | 3 +- ResponseCaching.sln | 50 ++++++ global.json | 3 + .../ResponseCachingSample.xproj | 19 +++ samples/ResponseCachingSample/Startup.cs | 33 ++++ samples/ResponseCachingSample/project.json | 33 ++++ .../CachingContext.cs | 143 ++++++++++++++++++ .../Microsoft.AspNet.ResponseCaching.xproj | 20 +++ .../Properties/AssemblyInfo.cs | 8 + .../ResponseCacheEntry.cs | 14 ++ .../ResponseCachingExtensions.cs | 15 ++ .../ResponseCachingMiddleware.cs | 61 ++++++++ .../project.json | 15 ++ .../CachingContextTests.cs | 33 ++++ ...crosoft.AspNet.ResponseCaching.Tests.xproj | 20 +++ .../project.json | 15 ++ 16 files changed, 484 insertions(+), 1 deletion(-) create mode 100644 ResponseCaching.sln create mode 100644 global.json create mode 100644 samples/ResponseCachingSample/ResponseCachingSample.xproj create mode 100644 samples/ResponseCachingSample/Startup.cs create mode 100644 samples/ResponseCachingSample/project.json create mode 100644 src/Microsoft.AspNet.ResponseCaching/CachingContext.cs create mode 100644 src/Microsoft.AspNet.ResponseCaching/Microsoft.AspNet.ResponseCaching.xproj create mode 100644 src/Microsoft.AspNet.ResponseCaching/Properties/AssemblyInfo.cs create mode 100644 src/Microsoft.AspNet.ResponseCaching/ResponseCacheEntry.cs create mode 100644 src/Microsoft.AspNet.ResponseCaching/ResponseCachingExtensions.cs create mode 100644 src/Microsoft.AspNet.ResponseCaching/ResponseCachingMiddleware.cs create mode 100644 src/Microsoft.AspNet.ResponseCaching/project.json create mode 100644 test/Microsoft.AspNet.ResponseCaching.Tests/CachingContextTests.cs create mode 100644 test/Microsoft.AspNet.ResponseCaching.Tests/Microsoft.AspNet.ResponseCaching.Tests.xproj create mode 100644 test/Microsoft.AspNet.ResponseCaching.Tests/project.json diff --git a/.gitignore b/.gitignore index 216e8d9..be311a1 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,5 @@ nuget.exe *DS_Store *.ncrunchsolution *.*sdf -*.ipch \ No newline at end of file +*.ipch +project.lock.json \ No newline at end of file diff --git a/ResponseCaching.sln b/ResponseCaching.sln new file mode 100644 index 0000000..358a798 --- /dev/null +++ b/ResponseCaching.sln @@ -0,0 +1,50 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.22823.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.ResponseCaching", "src\Microsoft.AspNet.ResponseCaching\Microsoft.AspNet.ResponseCaching.xproj", "{D1031270-DBD3-4F02-A3DC-3E7DADE8EBE6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{367AABAF-E03C-4491-A9A7-BDDE8903D1B4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{C51DF5BD-B53D-4795-BC01-A9AB066BF286}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{89A50974-E9D4-4F87-ACF2-6A6005E64931}" +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ResponseCachingSample", "samples\ResponseCachingSample\ResponseCachingSample.xproj", "{1139BDEE-FA15-474D-8855-0AB91F23CF26}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F787A492-C2FF-4569-A663-F8F24B900657}" + ProjectSection(SolutionItems) = preProject + global.json = global.json + EndProjectSection +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.ResponseCaching.Tests", "test\Microsoft.AspNet.ResponseCaching.Tests\Microsoft.AspNet.ResponseCaching.Tests.xproj", "{151B2027-3936-44B9-A4A0-E1E5902125AB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D1031270-DBD3-4F02-A3DC-3E7DADE8EBE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D1031270-DBD3-4F02-A3DC-3E7DADE8EBE6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D1031270-DBD3-4F02-A3DC-3E7DADE8EBE6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D1031270-DBD3-4F02-A3DC-3E7DADE8EBE6}.Release|Any CPU.Build.0 = Release|Any CPU + {1139BDEE-FA15-474D-8855-0AB91F23CF26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1139BDEE-FA15-474D-8855-0AB91F23CF26}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1139BDEE-FA15-474D-8855-0AB91F23CF26}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1139BDEE-FA15-474D-8855-0AB91F23CF26}.Release|Any CPU.Build.0 = Release|Any CPU + {151B2027-3936-44B9-A4A0-E1E5902125AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {151B2027-3936-44B9-A4A0-E1E5902125AB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {151B2027-3936-44B9-A4A0-E1E5902125AB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {151B2027-3936-44B9-A4A0-E1E5902125AB}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {D1031270-DBD3-4F02-A3DC-3E7DADE8EBE6} = {367AABAF-E03C-4491-A9A7-BDDE8903D1B4} + {1139BDEE-FA15-474D-8855-0AB91F23CF26} = {C51DF5BD-B53D-4795-BC01-A9AB066BF286} + {151B2027-3936-44B9-A4A0-E1E5902125AB} = {89A50974-E9D4-4F87-ACF2-6A6005E64931} + EndGlobalSection +EndGlobal diff --git a/global.json b/global.json new file mode 100644 index 0000000..397ac5f --- /dev/null +++ b/global.json @@ -0,0 +1,3 @@ +{ + "projects": ["src"] +} \ No newline at end of file diff --git a/samples/ResponseCachingSample/ResponseCachingSample.xproj b/samples/ResponseCachingSample/ResponseCachingSample.xproj new file mode 100644 index 0000000..2403e53 --- /dev/null +++ b/samples/ResponseCachingSample/ResponseCachingSample.xproj @@ -0,0 +1,19 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 1139bdee-fa15-474d-8855-0ab91f23cf26 + ResponseCachingSample + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + 2.0 + 2931 + + + \ No newline at end of file diff --git a/samples/ResponseCachingSample/Startup.cs b/samples/ResponseCachingSample/Startup.cs new file mode 100644 index 0000000..1ca6d9a --- /dev/null +++ b/samples/ResponseCachingSample/Startup.cs @@ -0,0 +1,33 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Net.Http.Headers; + +namespace ResponseCachingSample +{ + public class Startup + { + public void ConfigureServices(IServiceCollection services) + { + services.AddCaching(); + } + + public void Configure(IApplicationBuilder app) + { + app.UseResponseCaching(); + app.Run(async (context) => + { + context.Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue() + { + Public = true, + MaxAge = TimeSpan.FromSeconds(10) + }; + await context.Response.WriteAsync("Hello World! " + DateTime.UtcNow); + }); + } + } +} diff --git a/samples/ResponseCachingSample/project.json b/samples/ResponseCachingSample/project.json new file mode 100644 index 0000000..ca19e78 --- /dev/null +++ b/samples/ResponseCachingSample/project.json @@ -0,0 +1,33 @@ +{ + "webroot": "wwwroot", + "version": "1.0.0-*", + + "dependencies": { + "Microsoft.AspNet.ResponseCaching": "1.0.0-*", + "Microsoft.AspNet.Server.IIS": "1.0.0-*", + "Microsoft.AspNet.Server.WebListener": "1.0.0-*", + "Microsoft.Framework.Caching.Memory": "1.0.0-*" + }, + + "commands": { + "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000" + }, + + "frameworks": { + "dnx451": { }, + "dnxcore50": { } + }, + + "publishExclude": [ + "node_modules", + "bower_components", + "**.xproj", + "**.user", + "**.vspscc" + ], + "exclude": [ + "wwwroot", + "node_modules", + "bower_components" + ] +} diff --git a/src/Microsoft.AspNet.ResponseCaching/CachingContext.cs b/src/Microsoft.AspNet.ResponseCaching/CachingContext.cs new file mode 100644 index 0000000..c5586ce --- /dev/null +++ b/src/Microsoft.AspNet.ResponseCaching/CachingContext.cs @@ -0,0 +1,143 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNet.Http; +using Microsoft.Framework.Caching.Memory; + +namespace Microsoft.AspNet.ResponseCaching +{ + internal class CachingContext + { + private string _cacheKey; + + public CachingContext(HttpContext httpContext, IMemoryCache cache) + { + HttpContext = httpContext; + Cache = cache; + } + + private HttpContext HttpContext { get; } + + private IMemoryCache Cache { get; } + + private Stream OriginalResponseStream { get; set; } + + private MemoryStream Buffer { get; set; } + + internal bool ResponseStarted { get; set; } + + private bool CacheResponse { get; set; } + + internal bool CheckRequestAllowsCaching() + { + // Verify the method + // TODO: What other methods should be supported? + if (!string.Equals("GET", HttpContext.Request.Method, StringComparison.OrdinalIgnoreCase)) + { + return false; + } + + // Verify the request headers do not opt-out of caching + // TODO: + return true; + } + + // Only QueryString is treated as case sensitive + // GET;HTTP://MYDOMAIN.COM:80/PATHBASE/PATH?QueryString + private string CreateCacheKey() + { + var request = HttpContext.Request; + return request.Method.ToUpperInvariant() + + ";" + + request.Scheme.ToUpperInvariant() + + "://" + + request.Host.Value.ToUpperInvariant() + + request.PathBase.Value.ToUpperInvariant() + + request.Path.Value.ToUpperInvariant() + + request.QueryString; + } + + internal async Task TryServeFromCacheAsync() + { + _cacheKey = CreateCacheKey(); + ResponseCacheEntry cacheEntry; + if (Cache.TryGetValue(_cacheKey, out cacheEntry)) + { + // TODO: Compare cached request headers + + // TODO: Evaluate Vary-By and select the most appropriate response + + // TODO: Content negotiation if there are multiple cached response formats? + + // TODO: Verify content freshness, or else re-validate the data? + + var response = HttpContext.Response; + // Copy the cached status code and response headers + response.StatusCode = cacheEntry.StatusCode; + foreach (var pair in cacheEntry.Headers) + { + response.Headers.SetValues(pair.Key, pair.Value); + } + + // TODO: Update cache headers (Age) + response.Headers["Served_From_Cache"] = DateTime.Now.ToString(); + + // Copy the cached response body + var body = cacheEntry.Body; + if (body.Length > 0) + { + await response.Body.WriteAsync(body, 0, body.Length); + } + return true; + } + + return false; + } + + internal void HookResponseStream() + { + // TODO: Use a wrapper stream to listen for writes (e.g. the start of the response), + // check the headers, and verify if we should cache the response. + // Then we should stream data out to the client at the same time as we buffer for the cache. + // For now we'll just buffer everything in memory before checking the response headers. + // TODO: Consider caching large responses on disk and serving them from there. + OriginalResponseStream = HttpContext.Response.Body; + Buffer = new MemoryStream(); + HttpContext.Response.Body = Buffer; + } + + internal bool OnResponseStarting() + { + // Evaluate the response headers, see if we should buffer and cache + CacheResponse = true; // TODO: + return CacheResponse; + } + + internal void FinalizeCaching() + { + if (CacheResponse) + { + // Store the buffer to cache + var cacheEntry = new ResponseCacheEntry(); + cacheEntry.StatusCode = HttpContext.Response.StatusCode; + cacheEntry.Headers = HttpContext.Response.Headers.ToList(); + cacheEntry.Body = Buffer.ToArray(); + Cache.Set(_cacheKey, cacheEntry); // TODO: Timeouts + } + + // TODO: TEMP, flush the buffer to the client + Buffer.Seek(0, SeekOrigin.Begin); + Buffer.CopyTo(OriginalResponseStream); + } + + internal void UnhookResponseStream() + { + // Unhook the response stream. + HttpContext.Response.Body = OriginalResponseStream; + } + } +} diff --git a/src/Microsoft.AspNet.ResponseCaching/Microsoft.AspNet.ResponseCaching.xproj b/src/Microsoft.AspNet.ResponseCaching/Microsoft.AspNet.ResponseCaching.xproj new file mode 100644 index 0000000..bb65aad --- /dev/null +++ b/src/Microsoft.AspNet.ResponseCaching/Microsoft.AspNet.ResponseCaching.xproj @@ -0,0 +1,20 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + d1031270-dbd3-4f02-a3dc-3e7dade8ebe6 + Microsoft.AspNet.ResponseCaching + ..\artifacts\obj\$(MSBuildProjectName) + ..\artifacts\bin\$(MSBuildProjectName)\ + + + + 2.0 + + + diff --git a/src/Microsoft.AspNet.ResponseCaching/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.ResponseCaching/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..09bbb58 --- /dev/null +++ b/src/Microsoft.AspNet.ResponseCaching/Properties/AssemblyInfo.cs @@ -0,0 +1,8 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Microsoft.AspNet.ResponseCaching.Tests")] +[assembly: AssemblyMetadata("Serviceable", "True")] \ No newline at end of file diff --git a/src/Microsoft.AspNet.ResponseCaching/ResponseCacheEntry.cs b/src/Microsoft.AspNet.ResponseCaching/ResponseCacheEntry.cs new file mode 100644 index 0000000..f23685d --- /dev/null +++ b/src/Microsoft.AspNet.ResponseCaching/ResponseCacheEntry.cs @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; + +namespace Microsoft.AspNet.ResponseCaching +{ + internal class ResponseCacheEntry + { + public int StatusCode { get; set; } + internal IEnumerable> Headers { get; set; } + internal byte[] Body { get; set; } + } +} diff --git a/src/Microsoft.AspNet.ResponseCaching/ResponseCachingExtensions.cs b/src/Microsoft.AspNet.ResponseCaching/ResponseCachingExtensions.cs new file mode 100644 index 0000000..6632ad0 --- /dev/null +++ b/src/Microsoft.AspNet.ResponseCaching/ResponseCachingExtensions.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.ResponseCaching; + +namespace Microsoft.AspNet.Builder +{ + public static class ResponseCachingExtensions + { + public static IApplicationBuilder UseResponseCaching(this IApplicationBuilder app) + { + return app.UseMiddleware(); + } + } +} diff --git a/src/Microsoft.AspNet.ResponseCaching/ResponseCachingMiddleware.cs b/src/Microsoft.AspNet.ResponseCaching/ResponseCachingMiddleware.cs new file mode 100644 index 0000000..0c0fda4 --- /dev/null +++ b/src/Microsoft.AspNet.ResponseCaching/ResponseCachingMiddleware.cs @@ -0,0 +1,61 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Microsoft.AspNet.Builder; +using Microsoft.AspNet.Http; +using Microsoft.Framework.Caching.Memory; + +namespace Microsoft.AspNet.ResponseCaching +{ + // http://tools.ietf.org/html/rfc7234 + public class ResponseCachingMiddleware + { + private readonly RequestDelegate _next; + private readonly IMemoryCache _cache; + + public ResponseCachingMiddleware(RequestDelegate next, IMemoryCache cache) + { + _next = next; + _cache = cache; + } + + public async Task Invoke(HttpContext context) + { + var cachingContext = new CachingContext(context, _cache); + // Should we attempt any caching logic? + if (cachingContext.CheckRequestAllowsCaching()) + { + // Can this request be served from cache? + if (await cachingContext.TryServeFromCacheAsync()) + { + return; + } + + // Hook up to listen to the response stream + cachingContext.HookResponseStream(); + + try + { + await _next(context); + + // If there was no response body, check the response headers now. We can cache things like redirects. + if (!cachingContext.ResponseStarted) + { + cachingContext.OnResponseStarting(); + } + // Finalize the cache entry + cachingContext.FinalizeCaching(); + } + finally + { + cachingContext.UnhookResponseStream(); + } + } + else + { + await _next(context); + } + } + } +} diff --git a/src/Microsoft.AspNet.ResponseCaching/project.json b/src/Microsoft.AspNet.ResponseCaching/project.json new file mode 100644 index 0000000..b7f364b --- /dev/null +++ b/src/Microsoft.AspNet.ResponseCaching/project.json @@ -0,0 +1,15 @@ +{ + "version": "1.0.0-*", + "description": "Middleare that automatically caches HTTP responses on the server.", + "dependencies": { + "Microsoft.AspNet.Http.Abstractions": "1.0.0-*", + "Microsoft.Framework.Caching.Abstractions": "1.0.0-*" + }, + "frameworks" : { + "dnx451": { }, + "dnxcore50" : { + "dependencies": { + } + } + } +} diff --git a/test/Microsoft.AspNet.ResponseCaching.Tests/CachingContextTests.cs b/test/Microsoft.AspNet.ResponseCaching.Tests/CachingContextTests.cs new file mode 100644 index 0000000..d0315b5 --- /dev/null +++ b/test/Microsoft.AspNet.ResponseCaching.Tests/CachingContextTests.cs @@ -0,0 +1,33 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Http.Internal; +using Microsoft.Framework.Caching.Memory; +using Xunit; + +namespace Microsoft.AspNet.ResponseCaching +{ + public class CachingContextTests + { + [Fact] + public void CheckRequestAllowsCaching_Method_GET_Allowed() + { + var httpContext = new DefaultHttpContext(); + httpContext.Request.Method = "GET"; + var context = new CachingContext(httpContext, new MemoryCache(new MemoryCacheOptions())); + + Assert.True(context.CheckRequestAllowsCaching()); + } + + [Theory] + [InlineData("POST")] + public void CheckRequestAllowsCaching_Method_Unsafe_NotAllowed(string method) + { + var httpContext = new DefaultHttpContext(); + httpContext.Request.Method = method; + var context = new CachingContext(httpContext, new MemoryCache(new MemoryCacheOptions())); + + Assert.False(context.CheckRequestAllowsCaching()); + } + } +} diff --git a/test/Microsoft.AspNet.ResponseCaching.Tests/Microsoft.AspNet.ResponseCaching.Tests.xproj b/test/Microsoft.AspNet.ResponseCaching.Tests/Microsoft.AspNet.ResponseCaching.Tests.xproj new file mode 100644 index 0000000..ee98d4b --- /dev/null +++ b/test/Microsoft.AspNet.ResponseCaching.Tests/Microsoft.AspNet.ResponseCaching.Tests.xproj @@ -0,0 +1,20 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + 151b2027-3936-44b9-a4a0-e1e5902125ab + Microsoft.AspNet.ResponseCaching.Tests + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + + 2.0 + + + diff --git a/test/Microsoft.AspNet.ResponseCaching.Tests/project.json b/test/Microsoft.AspNet.ResponseCaching.Tests/project.json new file mode 100644 index 0000000..5ad3ebb --- /dev/null +++ b/test/Microsoft.AspNet.ResponseCaching.Tests/project.json @@ -0,0 +1,15 @@ +{ + "dependencies": { + "Microsoft.AspNet.ResponseCaching": "1.0.0-*", + "xunit.runner.aspnet": "2.0.0-aspnet-*", + "Microsoft.AspNet.Http": "1.0.0-beta5-11528", + "Microsoft.Framework.Caching.Memory": "1.0.0-beta5-11395" + }, + "commands": { + "test": "xunit.runner.aspnet" + }, + "frameworks": { + "dnx451": { }, + "dnxcore50": { } + } +} From fdf0f586f7424c8650fae55c59bd983a376e11af Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Sun, 24 Apr 2016 23:49:44 +0100 Subject: [PATCH 3/5] Update for AspNetCore "version": "0.1.0-*" --- .gitattributes | 2 + .gitignore | 7 +- .travis.yml | 30 ++++++++ ResponseCaching.sln | 6 +- appveyor.yml | 13 ++++ build.cmd | 30 +------- build.ps1 | 67 +++++++++++++++++ build.sh | 74 ++++++++++--------- global.json | 2 +- samples/ResponseCachingSample/Startup.cs | 23 ++++-- samples/ResponseCachingSample/project.json | 50 +++++++------ .../project.json | 15 ---- .../CachingContext.cs | 41 +++++++--- ...icrosoft.AspNetCore.ResponseCaching.xproj} | 6 +- .../Properties/AssemblyInfo.cs | 0 .../ResponseCacheEntry.cs | 9 ++- .../ResponseCachingExtensions.cs | 4 +- .../ResponseCachingMiddleware.cs | 7 +- .../project.json | 27 +++++++ .../project.json | 15 ---- .../CachingContextTests.cs | 6 +- ...ft.AspNetCore.ResponseCaching.Tests.xproj} | 6 +- .../project.json | 37 ++++++++++ 23 files changed, 322 insertions(+), 155 deletions(-) create mode 100644 .travis.yml create mode 100644 appveyor.yml create mode 100644 build.ps1 delete mode 100644 src/Microsoft.AspNet.ResponseCaching/project.json rename src/{Microsoft.AspNet.ResponseCaching => Microsoft.AspNetCore.ResponseCaching}/CachingContext.cs (79%) rename src/{Microsoft.AspNet.ResponseCaching/Microsoft.AspNet.ResponseCaching.xproj => Microsoft.AspNetCore.ResponseCaching/Microsoft.AspNetCore.ResponseCaching.xproj} (92%) rename src/{Microsoft.AspNet.ResponseCaching => Microsoft.AspNetCore.ResponseCaching}/Properties/AssemblyInfo.cs (100%) rename src/{Microsoft.AspNet.ResponseCaching => Microsoft.AspNetCore.ResponseCaching}/ResponseCacheEntry.cs (52%) rename src/{Microsoft.AspNet.ResponseCaching => Microsoft.AspNetCore.ResponseCaching}/ResponseCachingExtensions.cs (83%) rename src/{Microsoft.AspNet.ResponseCaching => Microsoft.AspNetCore.ResponseCaching}/ResponseCachingMiddleware.cs (92%) create mode 100644 src/Microsoft.AspNetCore.ResponseCaching/project.json delete mode 100644 test/Microsoft.AspNet.ResponseCaching.Tests/project.json rename test/{Microsoft.AspNet.ResponseCaching.Tests => Microsoft.AspNetCore.ResponseCaching.Tests}/CachingContextTests.cs (89%) rename test/{Microsoft.AspNet.ResponseCaching.Tests/Microsoft.AspNet.ResponseCaching.Tests.xproj => Microsoft.AspNetCore.ResponseCaching.Tests/Microsoft.AspNetCore.ResponseCaching.Tests.xproj} (92%) create mode 100644 test/Microsoft.AspNetCore.ResponseCaching.Tests/project.json diff --git a/.gitattributes b/.gitattributes index bdaa5ba..c2f0f84 100644 --- a/.gitattributes +++ b/.gitattributes @@ -48,3 +48,5 @@ *.fsproj text=auto *.dbproj text=auto *.sln text=auto eol=crlf + +*.sh eol=lf \ No newline at end of file diff --git a/.gitignore b/.gitignore index be311a1..6acc284 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ _ReSharper.*/ packages/ artifacts/ PublishProfiles/ +.vs/ *.user *.suo *.cache @@ -24,4 +25,8 @@ nuget.exe *.ncrunchsolution *.*sdf *.ipch -project.lock.json \ No newline at end of file +project.lock.json +runtimes/ +.build/ +.testPublish/ +launchSettings.json diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..aff1fb6 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,30 @@ +language: csharp +sudo: required +dist: trusty +addons: + apt: + packages: + - gettext + - libcurl4-openssl-dev + - libicu-dev + - libssl-dev + - libunwind8 + - zlib1g +before_install: + - if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install icu4c; fi +mono: + - 4.0.5 +os: + - linux + - osx +osx_image: xcode7.1 +branches: + only: + - master + - release + - dev + - /^(.*\/)?ci-.*$/ +script: + - ./build.sh --quiet verify +env: + - KOREBUILD_TEST_SKIPMONO=1 \ No newline at end of file diff --git a/ResponseCaching.sln b/ResponseCaching.sln index 358a798..6f455f5 100644 --- a/ResponseCaching.sln +++ b/ResponseCaching.sln @@ -1,9 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.22823.1 +VisualStudioVersion = 14.0.25123.0 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.ResponseCaching", "src\Microsoft.AspNet.ResponseCaching\Microsoft.AspNet.ResponseCaching.xproj", "{D1031270-DBD3-4F02-A3DC-3E7DADE8EBE6}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.ResponseCaching", "src\Microsoft.AspNetCore.ResponseCaching\Microsoft.AspNetCore.ResponseCaching.xproj", "{D1031270-DBD3-4F02-A3DC-3E7DADE8EBE6}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{367AABAF-E03C-4491-A9A7-BDDE8903D1B4}" EndProject @@ -18,7 +18,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution global.json = global.json EndProjectSection EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.ResponseCaching.Tests", "test\Microsoft.AspNet.ResponseCaching.Tests\Microsoft.AspNet.ResponseCaching.Tests.xproj", "{151B2027-3936-44B9-A4A0-E1E5902125AB}" +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.ResponseCaching.Tests", "test\Microsoft.AspNetCore.ResponseCaching.Tests\Microsoft.AspNetCore.ResponseCaching.Tests.xproj", "{151B2027-3936-44B9-A4A0-E1E5902125AB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..be95b88 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,13 @@ +init: + - git config --global core.autocrlf true +branches: + only: + - master + - release + - dev + - /^(.*\/)?ci-.*$/ +build_script: + - build.cmd --quiet verify +clone_depth: 1 +test: off +deploy: off \ No newline at end of file diff --git a/build.cmd b/build.cmd index 41025af..7d4894c 100644 --- a/build.cmd +++ b/build.cmd @@ -1,28 +1,2 @@ -@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 - -IF "%SKIP_DNX_INSTALL%"=="1" goto run -CALL packages\KoreBuild\build\dnvm upgrade -runtime CLR -arch x86 -CALL packages\KoreBuild\build\dnvm install default -runtime CoreCLR -arch x86 - -:run -CALL packages\KoreBuild\build\dnvm use default -runtime CLR -arch x86 -packages\Sake\tools\Sake.exe -I packages\KoreBuild\build -f makefile.shade %* +@ECHO OFF +PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0build.ps1' %*; exit $LASTEXITCODE" \ No newline at end of file diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..8f2f996 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,67 @@ +$ErrorActionPreference = "Stop" + +function DownloadWithRetry([string] $url, [string] $downloadLocation, [int] $retries) +{ + while($true) + { + try + { + Invoke-WebRequest $url -OutFile $downloadLocation + break + } + catch + { + $exceptionMessage = $_.Exception.Message + Write-Host "Failed to download '$url': $exceptionMessage" + if ($retries -gt 0) { + $retries-- + Write-Host "Waiting 10 seconds before retrying. Retries left: $retries" + Start-Sleep -Seconds 10 + + } + else + { + $exception = $_.Exception + throw $exception + } + } + } +} + +cd $PSScriptRoot + +$repoFolder = $PSScriptRoot +$env:REPO_FOLDER = $repoFolder + +$koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +if ($env:KOREBUILD_ZIP) +{ + $koreBuildZip=$env:KOREBUILD_ZIP +} + +$buildFolder = ".build" +$buildFile="$buildFolder\KoreBuild.ps1" + +if (!(Test-Path $buildFolder)) { + Write-Host "Downloading KoreBuild from $koreBuildZip" + + $tempFolder=$env:TEMP + "\KoreBuild-" + [guid]::NewGuid() + New-Item -Path "$tempFolder" -Type directory | Out-Null + + $localZipFile="$tempFolder\korebuild.zip" + + DownloadWithRetry -url $koreBuildZip -downloadLocation $localZipFile -retries 6 + + Add-Type -AssemblyName System.IO.Compression.FileSystem + [System.IO.Compression.ZipFile]::ExtractToDirectory($localZipFile, $tempFolder) + + New-Item -Path "$buildFolder" -Type directory | Out-Null + copy-item "$tempFolder\**\build\*" $buildFolder -Recurse + + # Cleanup + if (Test-Path $tempFolder) { + Remove-Item -Recurse -Force $tempFolder + } +} + +&"$buildFile" $args \ No newline at end of file diff --git a/build.sh b/build.sh index c8cc2a7..f420810 100644 --- a/build.sh +++ b/build.sh @@ -1,38 +1,46 @@ -#!/bin/bash +#!/usr/bin/env bash +repoFolder="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd $repoFolder -if test `uname` = Darwin; then - cachedir=~/Library/Caches/KBuild -else - if [ -z $XDG_DATA_HOME ]; then - cachedir=$HOME/.local/share - else - cachedir=$XDG_DATA_HOME; - fi -fi -mkdir -p $cachedir - -url=https://www.nuget.org/nuget.exe - -if test ! -f $cachedir/nuget.exe; then - wget -O $cachedir/nuget.exe $url 2>/dev/null || curl -o $cachedir/nuget.exe --location $url /dev/null -fi - -if test ! -e .nuget; then - mkdir .nuget - cp $cachedir/nuget.exe .nuget/nuget.exe +koreBuildZip="https://github.com/aspnet/KoreBuild/archive/dev.zip" +if [ ! -z $KOREBUILD_ZIP ]; then + koreBuildZip=$KOREBUILD_ZIP fi -if test ! -d packages/KoreBuild; then - mono .nuget/nuget.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre - mono .nuget/nuget.exe install Sake -version 0.2 -o packages -ExcludeVersion -fi - -if ! type dnvm > /dev/null 2>&1; then - source packages/KoreBuild/build/dnvm.sh -fi - -if ! type dnx > /dev/null 2>&1; then - dnvm upgrade +buildFolder=".build" +buildFile="$buildFolder/KoreBuild.sh" + +if test ! -d $buildFolder; then + echo "Downloading KoreBuild from $koreBuildZip" + + tempFolder="/tmp/KoreBuild-$(uuidgen)" + mkdir $tempFolder + + localZipFile="$tempFolder/korebuild.zip" + + retries=6 + until (wget -O $localZipFile $koreBuildZip 2>/dev/null || curl -o $localZipFile --location $koreBuildZip 2>/dev/null) + do + echo "Failed to download '$koreBuildZip'" + if [ "$retries" -le 0 ]; then + exit 1 + fi + retries=$((retries - 1)) + echo "Waiting 10 seconds before retrying. Retries left: $retries" + sleep 10s + done + + unzip -q -d $tempFolder $localZipFile + + mkdir $buildFolder + cp -r $tempFolder/**/build/** $buildFolder + + chmod +x $buildFile + + # Cleanup + if test ! -d $tempFolder; then + rm -rf $tempFolder + fi fi -mono packages/Sake/tools/Sake.exe -I packages/KoreBuild/build -f makefile.shade "$@" +$buildFile -r $repoFolder "$@" \ No newline at end of file diff --git a/global.json b/global.json index 397ac5f..0ddf69c 100644 --- a/global.json +++ b/global.json @@ -1,3 +1,3 @@ { - "projects": ["src"] + "projects": [ "src" ] } \ No newline at end of file diff --git a/samples/ResponseCachingSample/Startup.cs b/samples/ResponseCachingSample/Startup.cs index 1ca6d9a..38f3dcc 100644 --- a/samples/ResponseCachingSample/Startup.cs +++ b/samples/ResponseCachingSample/Startup.cs @@ -2,9 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using Microsoft.AspNet.Builder; -using Microsoft.AspNet.Http; -using Microsoft.Framework.DependencyInjection; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Net.Http.Headers; namespace ResponseCachingSample @@ -13,7 +14,7 @@ public class Startup { public void ConfigureServices(IServiceCollection services) { - services.AddCaching(); + services.AddMemoryCache(); } public void Configure(IApplicationBuilder app) @@ -24,10 +25,22 @@ public void Configure(IApplicationBuilder app) context.Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue() { Public = true, - MaxAge = TimeSpan.FromSeconds(10) + MaxAge = TimeSpan.FromSeconds(10) }; await context.Response.WriteAsync("Hello World! " + DateTime.UtcNow); }); } + + public static void Main(string[] args) + { + var host = new WebHostBuilder() + .UseDefaultHostingConfiguration(args) + .UseIISIntegration() + .UseKestrel() + .UseStartup() + .Build(); + + host.Run(); + } } } diff --git a/samples/ResponseCachingSample/project.json b/samples/ResponseCachingSample/project.json index ca19e78..137ac8f 100644 --- a/samples/ResponseCachingSample/project.json +++ b/samples/ResponseCachingSample/project.json @@ -1,33 +1,35 @@ { - "webroot": "wwwroot", - "version": "1.0.0-*", - - "dependencies": { - "Microsoft.AspNet.ResponseCaching": "1.0.0-*", - "Microsoft.AspNet.Server.IIS": "1.0.0-*", - "Microsoft.AspNet.Server.WebListener": "1.0.0-*", - "Microsoft.Framework.Caching.Memory": "1.0.0-*" + "compilationOptions": { + "emitEntryPoint": true, + "preserveCompilationContext": true }, - "commands": { - "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000" + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1-*", + "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-*", + "Microsoft.AspNetCore.Server.Kestrel": "1.0.0-*", + "Microsoft.Extensions.Caching.Memory": "1.0.0-*", + "Microsoft.AspNetCore.Http.Abstractions": "1.0.0-*", + "Microsoft.AspNetCore.Http.Extensions": "1.0.0-*", + "Microsoft.AspNetCore.ResponseCaching": "0.1.0-*" }, "frameworks": { - "dnx451": { }, - "dnxcore50": { } + "net451": { }, + "netcoreapp1.0": { + "imports": [ + "dnxcore50", + "portable-net451+win8" + ], + "dependencies": { + "Microsoft.NETCore.App": { + "version": "1.0.0-*", + "type": "platform" + } + } + } }, - - "publishExclude": [ - "node_modules", - "bower_components", - "**.xproj", - "**.user", - "**.vspscc" - ], - "exclude": [ - "wwwroot", - "node_modules", - "bower_components" + "content": [ + "web.config" ] } diff --git a/src/Microsoft.AspNet.ResponseCaching/project.json b/src/Microsoft.AspNet.ResponseCaching/project.json deleted file mode 100644 index b7f364b..0000000 --- a/src/Microsoft.AspNet.ResponseCaching/project.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "version": "1.0.0-*", - "description": "Middleare that automatically caches HTTP responses on the server.", - "dependencies": { - "Microsoft.AspNet.Http.Abstractions": "1.0.0-*", - "Microsoft.Framework.Caching.Abstractions": "1.0.0-*" - }, - "frameworks" : { - "dnx451": { }, - "dnxcore50" : { - "dependencies": { - } - } - } -} diff --git a/src/Microsoft.AspNet.ResponseCaching/CachingContext.cs b/src/Microsoft.AspNetCore.ResponseCaching/CachingContext.cs similarity index 79% rename from src/Microsoft.AspNet.ResponseCaching/CachingContext.cs rename to src/Microsoft.AspNetCore.ResponseCaching/CachingContext.cs index c5586ce..51643a7 100644 --- a/src/Microsoft.AspNet.ResponseCaching/CachingContext.cs +++ b/src/Microsoft.AspNetCore.ResponseCaching/CachingContext.cs @@ -2,15 +2,16 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.IO; -using System.Linq; using System.Threading.Tasks; -using Microsoft.AspNet.Http; -using Microsoft.Framework.Caching.Memory; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Primitives; -namespace Microsoft.AspNet.ResponseCaching +namespace Microsoft.AspNetCore.ResponseCaching { - internal class CachingContext + public struct CachingContext { private string _cacheKey; @@ -18,6 +19,12 @@ public CachingContext(HttpContext httpContext, IMemoryCache cache) { HttpContext = httpContext; Cache = cache; + + _cacheKey = null; + OriginalResponseStream = null; + Buffer = null; + ResponseStarted = false; + CacheResponse = false; } private HttpContext HttpContext { get; } @@ -32,7 +39,7 @@ public CachingContext(HttpContext httpContext, IMemoryCache cache) private bool CacheResponse { get; set; } - internal bool CheckRequestAllowsCaching() + public bool CheckRequestAllowsCaching() { // Verify the method // TODO: What other methods should be supported? @@ -78,9 +85,12 @@ internal async Task TryServeFromCacheAsync() var response = HttpContext.Response; // Copy the cached status code and response headers response.StatusCode = cacheEntry.StatusCode; - foreach (var pair in cacheEntry.Headers) + + var headers = cacheEntry.Headers; + for (var i = 0; i < headers.Count; i++) { - response.Headers.SetValues(pair.Key, pair.Value); + var entry = headers[i]; + response.Headers[entry.Key] = entry.Value; } // TODO: Update cache headers (Age) @@ -124,7 +134,20 @@ internal void FinalizeCaching() // Store the buffer to cache var cacheEntry = new ResponseCacheEntry(); cacheEntry.StatusCode = HttpContext.Response.StatusCode; - cacheEntry.Headers = HttpContext.Response.Headers.ToList(); + + var headers = HttpContext.Response.Headers; + var count = headers.Count + - (headers.ContainsKey("Date") ? 1 : 0); + var cachedHeaders = new List>(count); + foreach (var entry in headers) + { + // Don't copy Date header + if (entry.Key != "Date") + { + cachedHeaders.Add(entry); + } + } + cacheEntry.Body = Buffer.ToArray(); Cache.Set(_cacheKey, cacheEntry); // TODO: Timeouts } diff --git a/src/Microsoft.AspNet.ResponseCaching/Microsoft.AspNet.ResponseCaching.xproj b/src/Microsoft.AspNetCore.ResponseCaching/Microsoft.AspNetCore.ResponseCaching.xproj similarity index 92% rename from src/Microsoft.AspNet.ResponseCaching/Microsoft.AspNet.ResponseCaching.xproj rename to src/Microsoft.AspNetCore.ResponseCaching/Microsoft.AspNetCore.ResponseCaching.xproj index bb65aad..9c0615c 100644 --- a/src/Microsoft.AspNet.ResponseCaching/Microsoft.AspNet.ResponseCaching.xproj +++ b/src/Microsoft.AspNetCore.ResponseCaching/Microsoft.AspNetCore.ResponseCaching.xproj @@ -4,17 +4,15 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - d1031270-dbd3-4f02-a3dc-3e7dade8ebe6 - Microsoft.AspNet.ResponseCaching + Microsoft.AspNetCore.ResponseCaching ..\artifacts\obj\$(MSBuildProjectName) ..\artifacts\bin\$(MSBuildProjectName)\ - 2.0 - + \ No newline at end of file diff --git a/src/Microsoft.AspNet.ResponseCaching/Properties/AssemblyInfo.cs b/src/Microsoft.AspNetCore.ResponseCaching/Properties/AssemblyInfo.cs similarity index 100% rename from src/Microsoft.AspNet.ResponseCaching/Properties/AssemblyInfo.cs rename to src/Microsoft.AspNetCore.ResponseCaching/Properties/AssemblyInfo.cs diff --git a/src/Microsoft.AspNet.ResponseCaching/ResponseCacheEntry.cs b/src/Microsoft.AspNetCore.ResponseCaching/ResponseCacheEntry.cs similarity index 52% rename from src/Microsoft.AspNet.ResponseCaching/ResponseCacheEntry.cs rename to src/Microsoft.AspNetCore.ResponseCaching/ResponseCacheEntry.cs index f23685d..e5f2721 100644 --- a/src/Microsoft.AspNet.ResponseCaching/ResponseCacheEntry.cs +++ b/src/Microsoft.AspNetCore.ResponseCaching/ResponseCacheEntry.cs @@ -2,13 +2,14 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; +using Microsoft.Extensions.Primitives; -namespace Microsoft.AspNet.ResponseCaching +namespace Microsoft.AspNetCore.ResponseCaching { - internal class ResponseCacheEntry + public class ResponseCacheEntry { public int StatusCode { get; set; } - internal IEnumerable> Headers { get; set; } - internal byte[] Body { get; set; } + public List> Headers { get; set; } + public byte[] Body { get; set; } } } diff --git a/src/Microsoft.AspNet.ResponseCaching/ResponseCachingExtensions.cs b/src/Microsoft.AspNetCore.ResponseCaching/ResponseCachingExtensions.cs similarity index 83% rename from src/Microsoft.AspNet.ResponseCaching/ResponseCachingExtensions.cs rename to src/Microsoft.AspNetCore.ResponseCaching/ResponseCachingExtensions.cs index 6632ad0..60817a6 100644 --- a/src/Microsoft.AspNet.ResponseCaching/ResponseCachingExtensions.cs +++ b/src/Microsoft.AspNetCore.ResponseCaching/ResponseCachingExtensions.cs @@ -1,9 +1,9 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.AspNet.ResponseCaching; +using Microsoft.AspNetCore.ResponseCaching; -namespace Microsoft.AspNet.Builder +namespace Microsoft.AspNetCore.Builder { public static class ResponseCachingExtensions { diff --git a/src/Microsoft.AspNet.ResponseCaching/ResponseCachingMiddleware.cs b/src/Microsoft.AspNetCore.ResponseCaching/ResponseCachingMiddleware.cs similarity index 92% rename from src/Microsoft.AspNet.ResponseCaching/ResponseCachingMiddleware.cs rename to src/Microsoft.AspNetCore.ResponseCaching/ResponseCachingMiddleware.cs index 0c0fda4..fb7e4ce 100644 --- a/src/Microsoft.AspNet.ResponseCaching/ResponseCachingMiddleware.cs +++ b/src/Microsoft.AspNetCore.ResponseCaching/ResponseCachingMiddleware.cs @@ -2,11 +2,10 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; -using Microsoft.AspNet.Builder; -using Microsoft.AspNet.Http; -using Microsoft.Framework.Caching.Memory; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Caching.Memory; -namespace Microsoft.AspNet.ResponseCaching +namespace Microsoft.AspNetCore.ResponseCaching { // http://tools.ietf.org/html/rfc7234 public class ResponseCachingMiddleware diff --git a/src/Microsoft.AspNetCore.ResponseCaching/project.json b/src/Microsoft.AspNetCore.ResponseCaching/project.json new file mode 100644 index 0000000..d1ae42a --- /dev/null +++ b/src/Microsoft.AspNetCore.ResponseCaching/project.json @@ -0,0 +1,27 @@ +{ + "version": "0.1.0-*", + "description": "Middleware that automatically caches HTTP responses on the server.", + "repository": { + "type": "git", + "url": "git://github.com/aspnet/ResponseCaching" + }, + "compilationOptions": { + "warningsAsErrors": true + }, + "dependencies": { + "Microsoft.AspNetCore.Http.Abstractions": "1.0.0-*", + "Microsoft.Extensions.Caching.Abstractions": "1.0.0-*" + }, + "frameworks": { + "net451": { + "frameworkAssemblies": { + "System.Runtime": { "type": "build" } + } + }, + "netstandard1.3": { + "imports": [ + "portable-net451+win8" + ] + } + } +} diff --git a/test/Microsoft.AspNet.ResponseCaching.Tests/project.json b/test/Microsoft.AspNet.ResponseCaching.Tests/project.json deleted file mode 100644 index 5ad3ebb..0000000 --- a/test/Microsoft.AspNet.ResponseCaching.Tests/project.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "dependencies": { - "Microsoft.AspNet.ResponseCaching": "1.0.0-*", - "xunit.runner.aspnet": "2.0.0-aspnet-*", - "Microsoft.AspNet.Http": "1.0.0-beta5-11528", - "Microsoft.Framework.Caching.Memory": "1.0.0-beta5-11395" - }, - "commands": { - "test": "xunit.runner.aspnet" - }, - "frameworks": { - "dnx451": { }, - "dnxcore50": { } - } -} diff --git a/test/Microsoft.AspNet.ResponseCaching.Tests/CachingContextTests.cs b/test/Microsoft.AspNetCore.ResponseCaching.Tests/CachingContextTests.cs similarity index 89% rename from test/Microsoft.AspNet.ResponseCaching.Tests/CachingContextTests.cs rename to test/Microsoft.AspNetCore.ResponseCaching.Tests/CachingContextTests.cs index d0315b5..d191932 100644 --- a/test/Microsoft.AspNet.ResponseCaching.Tests/CachingContextTests.cs +++ b/test/Microsoft.AspNetCore.ResponseCaching.Tests/CachingContextTests.cs @@ -1,11 +1,11 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.AspNet.Http.Internal; -using Microsoft.Framework.Caching.Memory; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Caching.Memory; using Xunit; -namespace Microsoft.AspNet.ResponseCaching +namespace Microsoft.AspNetCore.ResponseCaching { public class CachingContextTests { diff --git a/test/Microsoft.AspNet.ResponseCaching.Tests/Microsoft.AspNet.ResponseCaching.Tests.xproj b/test/Microsoft.AspNetCore.ResponseCaching.Tests/Microsoft.AspNetCore.ResponseCaching.Tests.xproj similarity index 92% rename from test/Microsoft.AspNet.ResponseCaching.Tests/Microsoft.AspNet.ResponseCaching.Tests.xproj rename to test/Microsoft.AspNetCore.ResponseCaching.Tests/Microsoft.AspNetCore.ResponseCaching.Tests.xproj index ee98d4b..de350a0 100644 --- a/test/Microsoft.AspNet.ResponseCaching.Tests/Microsoft.AspNet.ResponseCaching.Tests.xproj +++ b/test/Microsoft.AspNetCore.ResponseCaching.Tests/Microsoft.AspNetCore.ResponseCaching.Tests.xproj @@ -4,17 +4,15 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - 151b2027-3936-44b9-a4a0-e1e5902125ab - Microsoft.AspNet.ResponseCaching.Tests + Microsoft.AspNetCore.ResponseCaching.Tests ..\..\artifacts\obj\$(MSBuildProjectName) ..\..\artifacts\bin\$(MSBuildProjectName)\ - 2.0 - + \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.ResponseCaching.Tests/project.json b/test/Microsoft.AspNetCore.ResponseCaching.Tests/project.json new file mode 100644 index 0000000..ba3e152 --- /dev/null +++ b/test/Microsoft.AspNetCore.ResponseCaching.Tests/project.json @@ -0,0 +1,37 @@ +{ + "compilationOptions": { + "warningsAsErrors": true + }, + "dependencies": { + "Microsoft.AspNetCore.Http": "1.0.0-*", + "Microsoft.Extensions.Caching.Memory": "1.0.0-*", + "Microsoft.AspNetCore.ResponseCaching": "0.1.0-*", + "xunit": "2.1.0" + }, + "frameworks": { + "netcoreapp1.0": { + "dependencies": { + "Microsoft.NETCore.App": { + "version": "1.0.0-*", + "type": "platform" + }, + "dotnet-test-xunit": "1.0.0-*", + "System.Diagnostics.Process": "4.1.0-*" + }, + "imports": [ + "dnxcore50", + "portable-net451+win8" + ] + }, + "net451": { + "frameworkAssemblies": { + "System.Runtime": "", + "System.Threading.Tasks": "" + }, + "dependencies": { + "xunit.runner.console": "2.1.0" + } + } + }, + "testRunner": "xunit" +} From 88821350be5d9393a6f16ee0585346ffd7149cc2 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Tue, 10 May 2016 18:41:36 +0100 Subject: [PATCH 4/5] Date & Age handling --- .../CachingContext.cs | 72 +++++++++++++++---- .../IResponseCacheOptions.cs | 12 ++++ .../ResponseCacheEntry.cs | 2 + .../project.json | 3 +- 4 files changed, 74 insertions(+), 15 deletions(-) create mode 100644 src/Microsoft.AspNetCore.ResponseCaching/IResponseCacheOptions.cs diff --git a/src/Microsoft.AspNetCore.ResponseCaching/CachingContext.cs b/src/Microsoft.AspNetCore.ResponseCaching/CachingContext.cs index 51643a7..e5db372 100644 --- a/src/Microsoft.AspNetCore.ResponseCaching/CachingContext.cs +++ b/src/Microsoft.AspNetCore.ResponseCaching/CachingContext.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Globalization; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Caching.Memory; @@ -14,12 +15,16 @@ namespace Microsoft.AspNetCore.ResponseCaching public struct CachingContext { private string _cacheKey; + private RequestType _requestType; + private bool _isProxied; public CachingContext(HttpContext httpContext, IMemoryCache cache) { HttpContext = httpContext; Cache = cache; + _requestType = RequestType.NotCached; + _isProxied = false; _cacheKey = null; OriginalResponseStream = null; Buffer = null; @@ -43,8 +48,18 @@ public bool CheckRequestAllowsCaching() { // Verify the method // TODO: What other methods should be supported? - if (!string.Equals("GET", HttpContext.Request.Method, StringComparison.OrdinalIgnoreCase)) + if (string.Equals("GET", HttpContext.Request.Method, StringComparison.OrdinalIgnoreCase)) { + _requestType = RequestType.FullReponse; + } + else if (string.Equals("HEAD", HttpContext.Request.Method, StringComparison.OrdinalIgnoreCase) || + string.Equals("OPTIONS", HttpContext.Request.Method, StringComparison.OrdinalIgnoreCase)) + { + _requestType = RequestType.HeadersOnly; + } + else + { + _requestType = RequestType.NotCached; return false; } @@ -93,14 +108,24 @@ internal async Task TryServeFromCacheAsync() response.Headers[entry.Key] = entry.Value; } - // TODO: Update cache headers (Age) - response.Headers["Served_From_Cache"] = DateTime.Now.ToString(); + // TODO: Allow setting proxied _isProxied + var age = Math.Max((DateTimeOffset.UtcNow - cacheEntry.Created).TotalSeconds, 0.0); + var ageString = (age > int.MaxValue ? int.MaxValue : (int)age).ToString(CultureInfo.InvariantCulture); + response.Headers[_isProxied ? "Age" : "X-Cache-Age"] = ageString; - // Copy the cached response body - var body = cacheEntry.Body; - if (body.Length > 0) + if (_requestType == RequestType.HeadersOnly) { - await response.Body.WriteAsync(body, 0, body.Length); + response.Headers["Content-Length"] = "0"; + } + else + { + // Copy the cached response body + var body = cacheEntry.Body; + response.Headers["Content-Length"] = body.Length.ToString(CultureInfo.InvariantCulture); + if (body.Length > 0) + { + await response.Body.WriteAsync(body, 0, body.Length); + } } return true; } @@ -129,23 +154,35 @@ internal bool OnResponseStarting() internal void FinalizeCaching() { - if (CacheResponse) + // Don't cache errors? 404 etc + if (CacheResponse && HttpContext.Response.StatusCode == 200) { // Store the buffer to cache - var cacheEntry = new ResponseCacheEntry(); - cacheEntry.StatusCode = HttpContext.Response.StatusCode; + var cacheEntry = new ResponseCacheEntry() + { + Created = DateTimeOffset.UtcNow, + StatusCode = HttpContext.Response.StatusCode + }; var headers = HttpContext.Response.Headers; var count = headers.Count - - (headers.ContainsKey("Date") ? 1 : 0); + - (headers.ContainsKey("Date") ? 1 : 0) + - (headers.ContainsKey("Content-Length") ? 1 : 0) + - (headers.ContainsKey("Age") ? 1 : 0); var cachedHeaders = new List>(count); + int age = 0; foreach (var entry in headers) { - // Don't copy Date header - if (entry.Key != "Date") + // Reduce create date by Age + if (entry.Key == "Age" && int.TryParse(entry.Value, out age) && age > 0) { - cachedHeaders.Add(entry); + cacheEntry.Created -= new TimeSpan(0, 0, age); } + // Don't copy Date header or Content-Length + else if (entry.Key != "Date" && entry.Key != "Content-Length") + { + cachedHeaders.Add(entry); + } } cacheEntry.Body = Buffer.ToArray(); @@ -162,5 +199,12 @@ internal void UnhookResponseStream() // Unhook the response stream. HttpContext.Response.Body = OriginalResponseStream; } + + private enum RequestType + { + NotCached, + HeadersOnly, + FullReponse + } } } diff --git a/src/Microsoft.AspNetCore.ResponseCaching/IResponseCacheOptions.cs b/src/Microsoft.AspNetCore.ResponseCaching/IResponseCacheOptions.cs new file mode 100644 index 0000000..556c33e --- /dev/null +++ b/src/Microsoft.AspNetCore.ResponseCaching/IResponseCacheOptions.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.AspNetCore.ResponseCaching +{ + interface IResponseCacheOptions + { + int MaxCachedItemBytes { get; set; } + } +} diff --git a/src/Microsoft.AspNetCore.ResponseCaching/ResponseCacheEntry.cs b/src/Microsoft.AspNetCore.ResponseCaching/ResponseCacheEntry.cs index e5f2721..dc749f7 100644 --- a/src/Microsoft.AspNetCore.ResponseCaching/ResponseCacheEntry.cs +++ b/src/Microsoft.AspNetCore.ResponseCaching/ResponseCacheEntry.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Microsoft.Extensions.Primitives; +using System; namespace Microsoft.AspNetCore.ResponseCaching { @@ -11,5 +12,6 @@ public class ResponseCacheEntry public int StatusCode { get; set; } public List> Headers { get; set; } public byte[] Body { get; set; } + public DateTimeOffset Created { get; set; } } } diff --git a/src/Microsoft.AspNetCore.ResponseCaching/project.json b/src/Microsoft.AspNetCore.ResponseCaching/project.json index d1ae42a..8018f3a 100644 --- a/src/Microsoft.AspNetCore.ResponseCaching/project.json +++ b/src/Microsoft.AspNetCore.ResponseCaching/project.json @@ -10,7 +10,8 @@ }, "dependencies": { "Microsoft.AspNetCore.Http.Abstractions": "1.0.0-*", - "Microsoft.Extensions.Caching.Abstractions": "1.0.0-*" + "Microsoft.Extensions.Caching.Abstractions": "1.0.0-*", + "System.Buffers": "4.0.0-*" }, "frameworks": { "net451": { From e24c9fe50114493e7431f736edb81d977cf11d0f Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Sun, 3 Jul 2016 04:50:24 +0100 Subject: [PATCH 5/5] Update to RTM --- .travis.yml | 13 +++--------- .../ResponseCachingSample.xproj | 2 +- samples/ResponseCachingSample/Startup.cs | 1 - samples/ResponseCachingSample/project.json | 21 ++++++++++--------- ...Microsoft.AspNetCore.ResponseCaching.xproj | 2 +- .../project.json | 17 ++++++++------- ...oft.AspNetCore.ResponseCaching.Tests.xproj | 5 ++++- .../project.json | 13 +++++------- 8 files changed, 35 insertions(+), 39 deletions(-) diff --git a/.travis.yml b/.travis.yml index aff1fb6..903efa7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,14 +4,7 @@ dist: trusty addons: apt: packages: - - gettext - - libcurl4-openssl-dev - - libicu-dev - - libssl-dev - libunwind8 - - zlib1g -before_install: - - if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install icu4c; fi mono: - 4.0.5 os: @@ -24,7 +17,7 @@ branches: - release - dev - /^(.*\/)?ci-.*$/ +before_install: + - if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; brew link --force openssl; fi script: - - ./build.sh --quiet verify -env: - - KOREBUILD_TEST_SKIPMONO=1 \ No newline at end of file + - ./build.sh --quiet verify \ No newline at end of file diff --git a/samples/ResponseCachingSample/ResponseCachingSample.xproj b/samples/ResponseCachingSample/ResponseCachingSample.xproj index 2403e53..cec78a3 100644 --- a/samples/ResponseCachingSample/ResponseCachingSample.xproj +++ b/samples/ResponseCachingSample/ResponseCachingSample.xproj @@ -9,7 +9,7 @@ 1139bdee-fa15-474d-8855-0ab91f23cf26 ResponseCachingSample ..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\artifacts\bin\$(MSBuildProjectName)\ + .\bin\ 2.0 diff --git a/samples/ResponseCachingSample/Startup.cs b/samples/ResponseCachingSample/Startup.cs index 38f3dcc..78685d6 100644 --- a/samples/ResponseCachingSample/Startup.cs +++ b/samples/ResponseCachingSample/Startup.cs @@ -34,7 +34,6 @@ public void Configure(IApplicationBuilder app) public static void Main(string[] args) { var host = new WebHostBuilder() - .UseDefaultHostingConfiguration(args) .UseIISIntegration() .UseKestrel() .UseStartup() diff --git a/samples/ResponseCachingSample/project.json b/samples/ResponseCachingSample/project.json index 137ac8f..a759eb8 100644 --- a/samples/ResponseCachingSample/project.json +++ b/samples/ResponseCachingSample/project.json @@ -1,5 +1,6 @@ { - "compilationOptions": { + "version": "0.1.0-*", + "buildOptions": { "emitEntryPoint": true, "preserveCompilationContext": true }, @@ -15,21 +16,21 @@ }, "frameworks": { - "net451": { }, + "net451": {}, "netcoreapp1.0": { - "imports": [ - "dnxcore50", - "portable-net451+win8" - ], "dependencies": { "Microsoft.NETCore.App": { "version": "1.0.0-*", "type": "platform" - } + }, + "System.Console": "4.0.0-*" } } }, - "content": [ - "web.config" - ] + + "runtimeOptions": { + "configProperties": { + "System.GC.Server": true + } + } } diff --git a/src/Microsoft.AspNetCore.ResponseCaching/Microsoft.AspNetCore.ResponseCaching.xproj b/src/Microsoft.AspNetCore.ResponseCaching/Microsoft.AspNetCore.ResponseCaching.xproj index 9c0615c..5fa1019 100644 --- a/src/Microsoft.AspNetCore.ResponseCaching/Microsoft.AspNetCore.ResponseCaching.xproj +++ b/src/Microsoft.AspNetCore.ResponseCaching/Microsoft.AspNetCore.ResponseCaching.xproj @@ -9,7 +9,7 @@ d1031270-dbd3-4f02-a3dc-3e7dade8ebe6 Microsoft.AspNetCore.ResponseCaching ..\artifacts\obj\$(MSBuildProjectName) - ..\artifacts\bin\$(MSBuildProjectName)\ + .\bin\ 2.0 diff --git a/src/Microsoft.AspNetCore.ResponseCaching/project.json b/src/Microsoft.AspNetCore.ResponseCaching/project.json index 8018f3a..76c316a 100644 --- a/src/Microsoft.AspNetCore.ResponseCaching/project.json +++ b/src/Microsoft.AspNetCore.ResponseCaching/project.json @@ -1,11 +1,17 @@ { "version": "0.1.0-*", "description": "Middleware that automatically caches HTTP responses on the server.", - "repository": { - "type": "git", - "url": "git://github.com/aspnet/ResponseCaching" + "packOptions": { + "repository": { + "type": "git", + "url": "git://github.com/aspnet/ResponseCaching" + }, + "tags": [ + "aspnetcore", + "response cache" + ] }, - "compilationOptions": { + "buildOptions": { "warningsAsErrors": true }, "dependencies": { @@ -20,9 +26,6 @@ } }, "netstandard1.3": { - "imports": [ - "portable-net451+win8" - ] } } } diff --git a/test/Microsoft.AspNetCore.ResponseCaching.Tests/Microsoft.AspNetCore.ResponseCaching.Tests.xproj b/test/Microsoft.AspNetCore.ResponseCaching.Tests/Microsoft.AspNetCore.ResponseCaching.Tests.xproj index de350a0..cefc297 100644 --- a/test/Microsoft.AspNetCore.ResponseCaching.Tests/Microsoft.AspNetCore.ResponseCaching.Tests.xproj +++ b/test/Microsoft.AspNetCore.ResponseCaching.Tests/Microsoft.AspNetCore.ResponseCaching.Tests.xproj @@ -9,10 +9,13 @@ 151b2027-3936-44b9-a4a0-e1e5902125ab Microsoft.AspNetCore.ResponseCaching.Tests ..\..\artifacts\obj\$(MSBuildProjectName) - ..\..\artifacts\bin\$(MSBuildProjectName)\ + .\bin\ 2.0 + + + \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.ResponseCaching.Tests/project.json b/test/Microsoft.AspNetCore.ResponseCaching.Tests/project.json index ba3e152..0a036ec 100644 --- a/test/Microsoft.AspNetCore.ResponseCaching.Tests/project.json +++ b/test/Microsoft.AspNetCore.ResponseCaching.Tests/project.json @@ -1,33 +1,30 @@ { - "compilationOptions": { + "buildOptions": { "warningsAsErrors": true }, "dependencies": { + "dotnet-test-xunit": "1.0.0-*", "Microsoft.AspNetCore.Http": "1.0.0-*", "Microsoft.Extensions.Caching.Memory": "1.0.0-*", "Microsoft.AspNetCore.ResponseCaching": "0.1.0-*", "xunit": "2.1.0" }, "frameworks": { + "netcoreapp1.0": { "dependencies": { "Microsoft.NETCore.App": { "version": "1.0.0-*", "type": "platform" - }, - "dotnet-test-xunit": "1.0.0-*", - "System.Diagnostics.Process": "4.1.0-*" + } }, "imports": [ "dnxcore50", "portable-net451+win8" ] }, + "net451": { - "frameworkAssemblies": { - "System.Runtime": "", - "System.Threading.Tasks": "" - }, "dependencies": { "xunit.runner.console": "2.1.0" }