Browse Source

Etag fixed.

pull/342/head
Sebastian 7 years ago
parent
commit
09a8f8a062
  1. 2
      src/Squidex/Pipeline/CommandMiddlewares/ETagCommandMiddleware.cs
  2. 20
      src/Squidex/Pipeline/ETagFilter.cs
  3. 2
      src/Squidex/app/shared/components/language-selector.component.html
  4. 3
      src/Squidex/app/shared/components/language-selector.component.scss
  5. 10
      tests/Squidex.Tests/Pipeline/CommandMiddlewares/ETagCommandMiddlewareTests.cs
  6. 88
      tests/Squidex.Tests/Pipeline/ETagFilterTests.cs

2
src/Squidex/Pipeline/CommandMiddlewares/ETagCommandMiddleware.cs

@ -37,7 +37,7 @@ namespace Squidex.Pipeline.CommandMiddlewares
var headers = httpContextAccessor.HttpContext.Request.Headers; var headers = httpContextAccessor.HttpContext.Request.Headers;
if (headers.TryGetValue(HeaderNames.ETag, out var etag) && !string.IsNullOrWhiteSpace(etag)) if (headers.TryGetValue(HeaderNames.IfMatch, out var etag) && !string.IsNullOrWhiteSpace(etag))
{ {
var etagValue = etag.ToString(); var etagValue = etag.ToString();

20
src/Squidex/Pipeline/ETagFilter.cs

@ -29,21 +29,23 @@ namespace Squidex.Pipeline
var httpContext = context.HttpContext; var httpContext = context.HttpContext;
if (HttpMethods.IsGet(httpContext.Request.Method) && if (httpContext.Response.Headers.TryGetValue(HeaderNames.ETag, out var etag) && !string.IsNullOrWhiteSpace(etag))
httpContext.Response.StatusCode == 200 &&
httpContext.Response.Headers.TryGetValue(HeaderNames.ETag, out var etag) && !string.IsNullOrWhiteSpace(etag))
{ {
string etagValue = etag;
if (!options.Strong) if (!options.Strong)
{ {
httpContext.Response.Headers[HeaderNames.ETag] = "W/" + etag; etagValue = "W/" + etag;
httpContext.Response.Headers[HeaderNames.ETag] = etagValue;
} }
if (httpContext.Request.Headers.TryGetValue(HeaderNames.IfNoneMatch, out var noneMatch) && !string.IsNullOrWhiteSpace(noneMatch)) if (HttpMethods.IsGet(httpContext.Request.Method) &&
httpContext.Response.StatusCode == 200 &&
httpContext.Request.Headers.TryGetValue(HeaderNames.IfNoneMatch, out var noneMatch) && !string.IsNullOrWhiteSpace(noneMatch) &&
string.Equals(etagValue, noneMatch, System.StringComparison.Ordinal))
{ {
if (string.Equals(etag, noneMatch, System.StringComparison.Ordinal)) resultContext.Result = new StatusCodeResult(304);
{
resultContext.Result = new StatusCodeResult(304);
}
} }
} }
} }

2
src/Squidex/app/shared/components/language-selector.component.html

@ -10,7 +10,7 @@
</button> </button>
<div class="dropdown-menu" *sqxModalView="dropdown;closeAlways:true" [sqxModalTarget]="button" @fade> <div class="dropdown-menu" *sqxModalView="dropdown;closeAlways:true" [sqxModalTarget]="button" @fade>
<div class="dropdown-item" *ngFor="let language of languages" [class.active]="language == selectedLanguage" (click)="selectLanguage(language)"> <div class="dropdown-item" *ngFor="let language of languages" [class.active]="language == selectedLanguage" (click)="selectLanguage(language)">
<strong class="iso-code">{{language.iso2Code}}</strong> ({{language.englishName}}) <strong class="iso-code iso-code-dropdown">{{language.iso2Code}}</strong> ({{language.englishName}})
</div> </div>
</div> </div>
</div> </div>

3
src/Squidex/app/shared/components/language-selector.component.scss

@ -7,6 +7,9 @@
.iso-code { .iso-code {
font-family: monospace; font-family: monospace;
}
.iso-code-dropdown {
display: inline-block; display: inline-block;
min-width: 40px; min-width: 40px;
max-width: 60px; max-width: 60px;

10
tests/Squidex.Tests/Pipeline/CommandMiddlewares/ETagCommandMiddlewareTests.cs

@ -20,13 +20,13 @@ namespace Squidex.Pipeline.CommandMiddlewares
{ {
private readonly IHttpContextAccessor httpContextAccessor = A.Fake<IHttpContextAccessor>(); private readonly IHttpContextAccessor httpContextAccessor = A.Fake<IHttpContextAccessor>();
private readonly ICommandBus commandBus = A.Fake<ICommandBus>(); private readonly ICommandBus commandBus = A.Fake<ICommandBus>();
private readonly IHeaderDictionary requestHeaders = new HeaderDictionary(); private readonly HttpContext httpContext = new DefaultHttpContext();
private readonly ETagCommandMiddleware sut; private readonly ETagCommandMiddleware sut;
public ETagCommandMiddlewareTests() public ETagCommandMiddlewareTests()
{ {
A.CallTo(() => httpContextAccessor.HttpContext.Request.Headers) A.CallTo(() => httpContextAccessor.HttpContext)
.Returns(requestHeaders); .Returns(httpContext);
sut = new ETagCommandMiddleware(httpContextAccessor); sut = new ETagCommandMiddleware(httpContextAccessor);
} }
@ -48,7 +48,7 @@ namespace Squidex.Pipeline.CommandMiddlewares
[Fact] [Fact]
public async Task Should_add_expected_version_to_command() public async Task Should_add_expected_version_to_command()
{ {
requestHeaders[HeaderNames.ETag] = "13"; httpContext.Request.Headers[HeaderNames.IfMatch] = "13";
var command = new CreateContent(); var command = new CreateContent();
var context = new CommandContext(command, commandBus); var context = new CommandContext(command, commandBus);
@ -61,7 +61,7 @@ namespace Squidex.Pipeline.CommandMiddlewares
[Fact] [Fact]
public async Task Should_add_weak_etag_as_expected_version_to_command() public async Task Should_add_weak_etag_as_expected_version_to_command()
{ {
requestHeaders[HeaderNames.ETag] = "W/13"; httpContext.Request.Headers[HeaderNames.IfMatch] = "W/13";
var command = new CreateContent(); var command = new CreateContent();
var context = new CommandContext(command, commandBus); var context = new CommandContext(command, commandBus);

88
tests/Squidex.Tests/Pipeline/ETagFilterTests.cs

@ -0,0 +1,88 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Collections.Generic;
using System.Threading.Tasks;
using FakeItEasy;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
using Xunit;
namespace Squidex.Pipeline
{
public class ETagFilterTests
{
private readonly HttpContext httpContext = new DefaultHttpContext();
private readonly ActionExecutingContext executingContext;
private readonly ActionExecutedContext executedContext;
private readonly ETagFilter sut = new ETagFilter(Options.Create(new ETagOptions()));
public ETagFilterTests()
{
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
var filters = new List<IFilterMetadata>();
executingContext = new ActionExecutingContext(actionContext, filters, new Dictionary<string, object>(), this);
executedContext = new ActionExecutedContext(actionContext, filters, this)
{
Result = new OkResult()
};
}
[Fact]
public async Task Should_convert_strong_to_weak_tag()
{
httpContext.Response.Headers[HeaderNames.ETag] = "13";
await sut.OnActionExecutionAsync(executingContext, () => Task.FromResult(executedContext));
Assert.Equal("W/13", httpContext.Response.Headers[HeaderNames.ETag]);
}
[Fact]
public async Task Should_not_convert_empty_strong_to_weak_tag()
{
httpContext.Response.Headers[HeaderNames.ETag] = string.Empty;
await sut.OnActionExecutionAsync(executingContext, () => Task.FromResult(executedContext));
Assert.Null((string)httpContext.Response.Headers[HeaderNames.ETag]);
}
[Fact]
public async Task Should_return_304_for_same_etags()
{
httpContext.Request.Method = HttpMethods.Get;
httpContext.Request.Headers[HeaderNames.IfNoneMatch] = "W/13";
httpContext.Response.Headers[HeaderNames.ETag] = "13";
await sut.OnActionExecutionAsync(executingContext, () => Task.FromResult(executedContext));
Assert.Equal(304, (executedContext.Result as StatusCodeResult).StatusCode);
}
[Fact]
public async Task Should_not_return_304_for_different_etags()
{
httpContext.Request.Method = HttpMethods.Get;
httpContext.Request.Headers[HeaderNames.IfNoneMatch] = "W/11";
httpContext.Response.Headers[HeaderNames.ETag] = "13";
await sut.OnActionExecutionAsync(executingContext, () => Task.FromResult(executedContext));
Assert.Equal(200, (executedContext.Result as StatusCodeResult).StatusCode);
}
}
}
Loading…
Cancel
Save