|
|
@ -9,12 +9,20 @@ using System.Threading.Tasks; |
|
|
using Microsoft.AspNetCore.Http; |
|
|
using Microsoft.AspNetCore.Http; |
|
|
using Microsoft.AspNetCore.Mvc; |
|
|
using Microsoft.AspNetCore.Mvc; |
|
|
using Microsoft.AspNetCore.Mvc.Filters; |
|
|
using Microsoft.AspNetCore.Mvc.Filters; |
|
|
|
|
|
using Microsoft.Extensions.Options; |
|
|
using Microsoft.Net.Http.Headers; |
|
|
using Microsoft.Net.Http.Headers; |
|
|
|
|
|
|
|
|
namespace Squidex.Pipeline |
|
|
namespace Squidex.Pipeline |
|
|
{ |
|
|
{ |
|
|
public sealed class ETagFilter : IAsyncActionFilter |
|
|
public sealed class ETagFilter : IAsyncActionFilter |
|
|
{ |
|
|
{ |
|
|
|
|
|
private readonly ETagOptions options; |
|
|
|
|
|
|
|
|
|
|
|
public ETagFilter(IOptions<ETagOptions> options) |
|
|
|
|
|
{ |
|
|
|
|
|
this.options = options.Value; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) |
|
|
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) |
|
|
{ |
|
|
{ |
|
|
var resultContext = await next(); |
|
|
var resultContext = await next(); |
|
|
@ -22,14 +30,21 @@ namespace Squidex.Pipeline |
|
|
var httpContext = context.HttpContext; |
|
|
var httpContext = context.HttpContext; |
|
|
|
|
|
|
|
|
if (HttpMethods.IsGet(httpContext.Request.Method) && |
|
|
if (HttpMethods.IsGet(httpContext.Request.Method) && |
|
|
httpContext.Request.Headers.TryGetValue(HeaderNames.IfNoneMatch, out var noneMatch) && |
|
|
|
|
|
httpContext.Response.StatusCode == 200 && |
|
|
httpContext.Response.StatusCode == 200 && |
|
|
httpContext.Response.Headers.TryGetValue(HeaderNames.ETag, out var etag) && |
|
|
httpContext.Response.Headers.TryGetValue(HeaderNames.ETag, out var etag) && !string.IsNullOrWhiteSpace(etag)) |
|
|
!string.IsNullOrWhiteSpace(noneMatch) && |
|
|
|
|
|
!string.IsNullOrWhiteSpace(etag) && |
|
|
|
|
|
string.Equals(etag, noneMatch, System.StringComparison.Ordinal)) |
|
|
|
|
|
{ |
|
|
{ |
|
|
resultContext.Result = new StatusCodeResult(304); |
|
|
if (!options.Strong) |
|
|
|
|
|
{ |
|
|
|
|
|
httpContext.Response.Headers[HeaderNames.ETag] = "W/" + etag; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (httpContext.Request.Headers.TryGetValue(HeaderNames.IfNoneMatch, out var noneMatch) && !string.IsNullOrWhiteSpace(noneMatch)) |
|
|
|
|
|
{ |
|
|
|
|
|
if (string.Equals(etag, noneMatch, System.StringComparison.Ordinal)) |
|
|
|
|
|
{ |
|
|
|
|
|
resultContext.Result = new StatusCodeResult(304); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|