Browse Source

Better Etag support.

pull/330/head
Sebastian Stehle 7 years ago
parent
commit
14ee7d97f7
  1. 4
      src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs
  2. 2
      src/Squidex/Areas/Api/Controllers/Languages/LanguagesController.cs
  3. 5
      src/Squidex/Areas/Api/Controllers/Rules/Models/RuleDto.cs
  4. 9
      src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs
  5. 2
      src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDetailsDto.cs
  6. 11
      src/Squidex/app/shared/services/assets.service.ts

4
src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs

@ -67,10 +67,12 @@ namespace Squidex.Areas.Api.Controllers.Assets
return NotFound(); return NotFound();
} }
var assetId = entity.Id.ToString(); Response.Headers["ETag"] = $"{entity.FileVersion};{width};{height};{mode}";
return new FileCallbackResult(entity.MimeType, entity.FileName, async bodyStream => return new FileCallbackResult(entity.MimeType, entity.FileName, async bodyStream =>
{ {
var assetId = entity.Id.ToString();
if (entity.IsImage && (width.HasValue || height.HasValue)) if (entity.IsImage && (width.HasValue || height.HasValue))
{ {
var assetSuffix = $"{width}_{height}_{mode}"; var assetSuffix = $"{width}_{height}_{mode}";

2
src/Squidex/Areas/Api/Controllers/Languages/LanguagesController.cs

@ -43,6 +43,8 @@ namespace Squidex.Areas.Api.Controllers.Languages
{ {
var response = Language.AllLanguages.Select(LanguageDto.FromLanguage).ToList(); var response = Language.AllLanguages.Select(LanguageDto.FromLanguage).ToList();
Response.Headers["Etag"] = "1";
return Ok(response); return Ok(response);
} }
} }

5
src/Squidex/Areas/Api/Controllers/Rules/Models/RuleDto.cs

@ -14,10 +14,11 @@ using Squidex.Domain.Apps.Core.Rules;
using Squidex.Domain.Apps.Entities.Rules; using Squidex.Domain.Apps.Entities.Rules;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Reflection;
using Squidex.Pipeline;
namespace Squidex.Areas.Api.Controllers.Rules.Models namespace Squidex.Areas.Api.Controllers.Rules.Models
{ {
public sealed class RuleDto public sealed class RuleDto : IGenerateEtag
{ {
/// <summary> /// <summary>
/// The id of the rule. /// The id of the rule.
@ -49,7 +50,7 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models
/// <summary> /// <summary>
/// The version of the rule. /// The version of the rule.
/// </summary> /// </summary>
public int Version { get; set; } public long Version { get; set; }
/// <summary> /// <summary>
/// Determines if the rule is enabled. /// Determines if the rule is enabled.

9
src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs

@ -9,6 +9,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using IdentityServer4.Models;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NodaTime; using NodaTime;
using Squidex.Areas.Api.Controllers.Rules.Models; using Squidex.Areas.Api.Controllers.Rules.Models;
@ -32,6 +33,8 @@ namespace Squidex.Areas.Api.Controllers.Rules
[MustBeAppDeveloper] [MustBeAppDeveloper]
public sealed class RulesController : ApiController public sealed class RulesController : ApiController
{ {
private static readonly string RuleActionsEtag = string.Join(";", RuleElementRegistry.Actions.Select(x => x.Key)).Sha256();
private static readonly string RuleTriggersEtag = string.Join(";", RuleElementRegistry.Triggers.Select(x => x.Key)).Sha256();
private readonly IAppProvider appProvider; private readonly IAppProvider appProvider;
private readonly IRuleEventRepository ruleEventsRepository; private readonly IRuleEventRepository ruleEventsRepository;
@ -58,6 +61,8 @@ namespace Squidex.Areas.Api.Controllers.Rules
{ {
var response = RuleElementRegistry.Actions.ToDictionary(x => x.Key, x => SimpleMapper.Map(x.Value, new RuleElementDto())); var response = RuleElementRegistry.Actions.ToDictionary(x => x.Key, x => SimpleMapper.Map(x.Value, new RuleElementDto()));
Response.Headers["Etag"] = RuleActionsEtag;
return Ok(response); return Ok(response);
} }
@ -75,6 +80,8 @@ namespace Squidex.Areas.Api.Controllers.Rules
{ {
var response = RuleElementRegistry.Triggers.ToDictionary(x => x.Key, x => SimpleMapper.Map(x.Value, new RuleElementDto())); var response = RuleElementRegistry.Triggers.ToDictionary(x => x.Key, x => SimpleMapper.Map(x.Value, new RuleElementDto()));
Response.Headers["Etag"] = RuleTriggersEtag;
return Ok(response); return Ok(response);
} }
@ -96,6 +103,8 @@ namespace Squidex.Areas.Api.Controllers.Rules
var response = entities.Select(RuleDto.FromRule); var response = entities.Select(RuleDto.FromRule);
Response.Headers["ETag"] = response.ToManyEtag(0);
return Ok(response); return Ok(response);
} }

2
src/Squidex/Areas/Api/Controllers/Schemas/Models/SchemaDetailsDto.cs

@ -108,7 +108,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models
/// <summary> /// <summary>
/// The version of the schema. /// The version of the schema.
/// </summary> /// </summary>
public int Version { get; set; } public long Version { get; set; }
public static SchemaDetailsDto FromSchema(ISchemaEntity schema) public static SchemaDetailsDto FromSchema(ISchemaEntity schema)
{ {

11
src/Squidex/app/shared/services/assets.service.ts

@ -195,9 +195,7 @@ export class AssetsService {
public uploadFile(appName: string, file: File, user: string, now: DateTime): Observable<number | AssetDto> { public uploadFile(appName: string, file: File, user: string, now: DateTime): Observable<number | AssetDto> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/assets`); const url = this.apiUrl.buildUrl(`api/apps/${appName}/assets`);
const req = new HttpRequest('POST', url, getFormData(file), { const req = new HttpRequest('POST', url, getFormData(file), { reportProgress: true });
reportProgress: true
});
return this.http.request<any>(req).pipe( return this.http.request<any>(req).pipe(
filter(event => filter(event =>
@ -276,12 +274,7 @@ export class AssetsService {
public replaceFile(appName: string, id: string, file: File, version: Version): Observable<number | Versioned<AssetReplacedDto>> { public replaceFile(appName: string, id: string, file: File, version: Version): Observable<number | Versioned<AssetReplacedDto>> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/assets/${id}/content`); const url = this.apiUrl.buildUrl(`api/apps/${appName}/assets/${id}/content`);
const req = new HttpRequest('PUT', url, getFormData(file), { const req = new HttpRequest('PUT', url, getFormData(file), { headers: new HttpHeaders().set('If-Match', version.value), reportProgress: true });
headers: new HttpHeaders({
'If-Match': version.value
}),
reportProgress: true
});
return this.http.request(req).pipe( return this.http.request(req).pipe(
filter(event => filter(event =>

Loading…
Cancel
Save