Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1028,8 +1028,10 @@ public async Task TestUploadFullPackage_PathTraversalAttackFails(string suspicio
Assert.False(response.IsSuccessStatusCode);
}

[Fact]
public async Task TestUploadFullPackage_FailsIfSizeTooLarge()
[Theory]
[InlineData(50 * 1024 * 1024)]
[InlineData(200000001)]
public async Task TestUploadFullPackage_FailsIfSizeTooLarge(long size)
{
using var db = await DatabaseAccess.GetConnectionAsync();
await db.ExecuteAsync("INSERT INTO `phpbb_users` (`user_id`, `username`, `username_clean`, `country_acronym`, `user_permissions`, `user_sig`, `user_occ`, `user_interests`) VALUES (1000, 'test', 'test', 'JP', '', '', '', '')");
Expand All @@ -1042,7 +1044,7 @@ public async Task TestUploadFullPackage_FailsIfSizeTooLarge()
var request = new HttpRequestMessage(HttpMethod.Put, "/beatmapsets/241526");

using var content = new MultipartFormDataContent($"{Guid.NewGuid()}----");
byte[] data = new byte[50 * 1024 * 1024];
byte[] data = new byte[size];
new Random(1337).NextBytes(data);
var stream = new MemoryStream();

Expand All @@ -1059,7 +1061,7 @@ public async Task TestUploadFullPackage_FailsIfSizeTooLarge()

var response = await Client.SendAsync(request);
Assert.False(response.IsSuccessStatusCode);
Assert.Contains("The beatmap package is too large.", (await response.Content.ReadFromJsonAsync<ErrorResponse>())!.Error);
Assert.Contains("too large", (await response.Content.ReadFromJsonAsync<ErrorResponse>())!.Error);
}

[Fact]
Expand Down
18 changes: 2 additions & 16 deletions osu.Server.BeatmapSubmission/BeatmapSubmissionController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -493,22 +493,8 @@ private void checkPackageSize(long packageSizeBytes, BeatmapPackageParseResult p
if (packageSizeBytes > allowableSizeBytes)
{
throw new InvariantException($"The beatmap package is too large. "
+ $"The size of the package with the requested changes applied is {humaniseSize(packageSizeBytes)}. "
+ $"The maximum allowable size is {humaniseSize(allowableSizeBytes)}.");
}

static string humaniseSize(double sizeBytes)
{
string humanisedSize;

if (sizeBytes < 1024)
humanisedSize = $@"{sizeBytes}B";
else if (sizeBytes < 1024 * 1024)
humanisedSize = $@"{sizeBytes / 1024:#.0}kB";
else
humanisedSize = $@"{sizeBytes / 1024 / 1024:#.0}MB";

return humanisedSize;
+ $"The size of the package with the requested changes applied is {FormatUtils.HumaniseSize(packageSizeBytes)}. "
+ $"The maximum allowable size is {FormatUtils.HumaniseSize(allowableSizeBytes)}.");
}
}

Expand Down
22 changes: 22 additions & 0 deletions osu.Server.BeatmapSubmission/FormatUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

namespace osu.Server.BeatmapSubmission
{
public class FormatUtils
{
public static string HumaniseSize(double sizeBytes)
{
string humanisedSize;

if (sizeBytes < 1024)
humanisedSize = $@"{sizeBytes}B";
else if (sizeBytes < 1024 * 1024)
humanisedSize = $@"{sizeBytes / 1024:#.0}kB";
else
humanisedSize = $@"{sizeBytes / 1024 / 1024:#.0}MB";

return humanisedSize;
}
}
}
9 changes: 9 additions & 0 deletions osu.Server.BeatmapSubmission/ModelStateValidationFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using osu.Server.BeatmapSubmission.Models.API.Responses;

namespace osu.Server.BeatmapSubmission
{
Expand All @@ -28,7 +29,15 @@ public void OnActionExecuting(ActionExecutingContext context)
continue;

foreach (var error in value.Errors)
{
if (string.IsNullOrEmpty(key) && (error.ErrorMessage.Contains("Request body too large") || error.ErrorMessage.Contains("Multipart body length limit")))
{
context.Result = new ErrorResponse($"Request body too large. Size must be lower than {FormatUtils.HumaniseSize(Program.ABSOLUTE_REQUEST_SIZE_LIMIT_BYTES)}.").ToActionResult();
return;
}

errorList.Add($"{{ field: \"{key}\", message: \"{error.ErrorMessage}\", exception: \"{error.Exception}\" }}");
}
}

logger.LogError($"""
Expand Down