Skip to content

Commit

Permalink
Fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Aragas committed Oct 2, 2023
1 parent de64146 commit 44e7ed5
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ protected override void ConfigureModel(EntityTypeBuilder<IdEntity> builder)
{
builder.Property(x => x.FileId).HasColumnName("file_id").HasDefaultValueSql("hex(randomblob(3))");
builder.Property(x => x.CrashReportId).HasColumnName("crash_report_id");
builder.Property(x => x.Version).HasColumnName("version");
builder.Property(x => x.Created).HasColumnName("created");
builder.ToTable("id_entity").HasKey(x => x.FileId);

Expand Down
52 changes: 30 additions & 22 deletions src/BUTR.CrashReportServer/Controllers/CrashUploadController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
using System;
using System.Collections.Generic;
using System.IO.Pipelines;
using System.Net;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
Expand All @@ -33,12 +32,14 @@ public sealed record CrashReportUploadBody(CrashReportModel CrashReport, ICollec

private readonly ILogger _logger;
private readonly CrashUploadOptions _options;
private readonly JsonSerializerOptions _jsonSerializerOptions;
private readonly AppDbContext _dbContext;
private readonly GZipCompressor _gZipCompressor;

public CrashUploadController(ILogger<CrashUploadController> logger, IOptionsSnapshot<CrashUploadOptions> options, AppDbContext dbContext, GZipCompressor gZipCompressor)
public CrashUploadController(ILogger<CrashUploadController> logger, IOptionsSnapshot<CrashUploadOptions> options, IOptionsSnapshot<JsonSerializerOptions> jsonSerializerOptions, AppDbContext dbContext, GZipCompressor gZipCompressor)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_jsonSerializerOptions = jsonSerializerOptions.Value ?? throw new ArgumentNullException(nameof(jsonSerializerOptions));
_options = options.Value ?? throw new ArgumentNullException(nameof(options));
_dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
_gZipCompressor = gZipCompressor ?? throw new ArgumentNullException(nameof(gZipCompressor));
Expand All @@ -62,16 +63,8 @@ private async Task<string> GenerateFileId(CancellationToken ct)
}
*/

[AllowAnonymous]
[HttpPost("crash-upload.py")]
[Consumes("text/html")]
[ProducesResponseType(typeof(void), StatusCodes.Status200OK, "text/plain")]
[ProducesResponseType(typeof(void), StatusCodes.Status500InternalServerError, "application/problem+json")]
public async Task<IActionResult> CrashUploadAsync(CancellationToken ct)
private async Task<IActionResult> UploadHtmlAsync(CancellationToken ct)
{
if (Request.ContentLength is not { } contentLength || contentLength < _options.MinContentLength || contentLength > _options.MaxContentLength)
return StatusCode(StatusCodes.Status500InternalServerError);

Request.EnableBuffering();

var (valid, id, version, crashReportModel) = await CrashReportRawParser.TryReadCrashReportDataAsync(PipeReader.Create(Request.Body));
Expand All @@ -96,34 +89,49 @@ public async Task<IActionResult> CrashUploadAsync(CancellationToken ct)
return Ok($"{_options.BaseUri}/{idEntity.FileId}");
}

[AllowAnonymous]
[HttpPost("crashupload")]
[Consumes("application/json")]
[ProducesResponseType(typeof(void), StatusCodes.Status200OK, "text/plain")]
[ProducesResponseType(typeof(void), StatusCodes.Status500InternalServerError, "application/problem+json")]
public async Task<IActionResult> CrashUploadAsync([FromBody] CrashReportUploadBody body, CancellationToken ct)
private async Task<IActionResult> UploadJsonAsync(CancellationToken ct)
{
if (Request.ContentLength is not { } contentLength || contentLength < _options.MinContentLength || contentLength > _options.MaxContentLength)
if (await HttpContext.Request.ReadFromJsonAsync<CrashReportUploadBody>(_jsonSerializerOptions, ct) is not { CrashReport: { } crashReport, LogSources: { } logSources })
return StatusCode(StatusCodes.Status500InternalServerError);

if (await _dbContext.Set<IdEntity>().FirstOrDefaultAsync(x => x.CrashReportId == body.CrashReport.Id, ct) is { } idEntity)
if (await _dbContext.Set<IdEntity>().FirstOrDefaultAsync(x => x.CrashReportId == crashReport.Id, ct) is { } idEntity)
return Ok($"{_options.BaseUri}/{idEntity.FileId}");

var json = JsonSerializer.Serialize(body.CrashReport, new JsonSerializerOptions(JsonSerializerDefaults.Web)
var json = JsonSerializer.Serialize(crashReport, new JsonSerializerOptions(JsonSerializerDefaults.Web)
{
Converters = { new JsonStringEnumConverter() }
});
var html = CrashReportHtmlRenderer.AddData(CrashReportHtmlRenderer.Build(body.CrashReport, body.LogSources), json);
var html = CrashReportHtmlRenderer.AddData(CrashReportHtmlRenderer.Build(crashReport, logSources), json);

await using var compressedHtmlStream = await _gZipCompressor.CompressAsync(html.AsStream(), ct);
await using var compressedJsonStream = await _gZipCompressor.CompressAsync(json.AsStream(), ct);

idEntity = new IdEntity { FileId = default!, CrashReportId = body.CrashReport.Id, Version = body.CrashReport.Version, Created = DateTimeOffset.UtcNow, };
idEntity = new IdEntity { FileId = default!, CrashReportId = crashReport.Id, Version = crashReport.Version, Created = DateTimeOffset.UtcNow, };
await _dbContext.Set<IdEntity>().AddAsync(idEntity, ct);
await _dbContext.Set<JsonEntity>().AddAsync(new JsonEntity { Id = idEntity, CrashReportCompressed = compressedJsonStream.ToArray(), }, ct);
await _dbContext.Set<FileEntity>().AddAsync(new FileEntity { Id = idEntity, DataCompressed = compressedHtmlStream.ToArray(), }, ct);
await _dbContext.SaveChangesAsync(ct);

return Ok($"{_options.BaseUri}/{idEntity.FileId}");
}

[AllowAnonymous]
[HttpPost("crash-upload.py")]
[Consumes(typeof(CrashReportUploadBody), "application/json", "text/html")]
[ProducesResponseType(typeof(void), StatusCodes.Status200OK, "text/plain")]
[ProducesResponseType(typeof(void), StatusCodes.Status500InternalServerError, "application/problem+json")]
public Task<IActionResult> CrashUploadAsync(CancellationToken ct)
{
if (Request.ContentLength is not { } contentLength || contentLength < _options.MinContentLength || contentLength > _options.MaxContentLength)
return Task.FromResult<IActionResult>(StatusCode(StatusCodes.Status500InternalServerError));

switch (Request.ContentType)
{
case "application/json":
return UploadJsonAsync(ct);
case "text/html":
default:
return UploadHtmlAsync(ct);
}
}
}
6 changes: 6 additions & 0 deletions src/BUTR.CrashReportServer/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ public void ConfigureServices(IServiceCollection services)
opts.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
});
services.Configure<JsonSerializerOptions>(opts =>
{
opts.PropertyNameCaseInsensitive = true;
opts.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
opts.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
});
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
Expand Down
4 changes: 4 additions & 0 deletions src/BUTR.CrashReportServer/Utils/CrashReportRawParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public static class CrashReportRawParser
private static readonly byte[] ReportVersionMarkerStart = "' version='"u8.ToArray();
private static readonly byte[] ReportVersionMarkerEnd = "'>"u8.ToArray();
private static readonly byte[] ReportVersionMarkerEnd2 = "' >"u8.ToArray();
private static readonly byte[] ReportVersionMarkerEnd3 = "'/>"u8.ToArray();
private static readonly byte[] ReportVersionMarkerEnd4 = "' />"u8.ToArray();
private static readonly byte[] JsonModelMarkerStart = "<div id='json-model-data' class='headers-container'>"u8.ToArray();
private static readonly byte[] JsonModelMarkerEnd = "</div>"u8.ToArray();

Expand Down Expand Up @@ -87,6 +89,8 @@ private static bool TryReadCrashReportData(ref ReadOnlySequence<byte> buffer, ou
var idxEnd = -1;
if (line.Slice(idxVersionStart + ReportVersionMarkerStart.Length).IndexOf(ReportVersionMarkerEnd) is var idxVersionEnd and not -1) idxEnd = idxVersionEnd;
if (line.Slice(idxVersionStart + ReportVersionMarkerStart.Length).IndexOf(ReportVersionMarkerEnd2) is var idxVersionEnd2 and not -1) idxEnd = idxVersionEnd2;
if (line.Slice(idxVersionStart + ReportVersionMarkerStart.Length).IndexOf(ReportVersionMarkerEnd3) is var idxVersionEnd3 and not -1) idxEnd = idxVersionEnd3;
if (line.Slice(idxVersionStart + ReportVersionMarkerStart.Length).IndexOf(ReportVersionMarkerEnd4) is var idxVersionEnd4 and not -1) idxEnd = idxVersionEnd4;
if (idxEnd == -1) return false;

if (!Utf8Parser.TryParse(line.Slice(idxVersionStart + ReportVersionMarkerStart.Length, idxEnd), out version, out _)) return false;
Expand Down

0 comments on commit 44e7ed5

Please sign in to comment.