HangarMC / Hangar

A plugin repository used for paper plugins
https://hangar.papermc.io/
MIT License
246 stars 65 forks source link

Large avatar uploads trigger cryptic error #1162

Open DeJayDev opened 1 year ago

DeJayDev commented 1 year ago

Observed/problematic behavior

When trying to upload a 2.87MB photo as an avatar (sorry), the avatar fails to upload and tells me the maximum size is approx 10TB. The UI doesn't signal this error either, just a generic "Error while saving avatar". The UI also doesn't mention a file size limit at all, if there is one :)

{
    "message": "File too large - files have to be less than 10000000MB in size",
    "messageArgs": [],
    "isHangarApiException": true,
    "httpError": {
        "statusCode": 413
    }
}

Expected behavior

At the very least, the proper error (or a higher file size limit <3)

Steps to reproduce

1) You'll need a large PNG, here's one that's about 47MB hosted on the Discord CDN.

2) Try to make it your profile picture, any crop'll do. -> Here's a link to set your avatar

Other

No response

DeJayDev commented 1 year ago

There appear to be two different filesize caps, one provided by the API and another by the UI.

The UI's 10mb warning kicks in when uploading the 50MB sample file provided: image

This makes sense, as the file is most definitely over 10MB. However, it's possible that the frontend allows the upload of a file that's sometimes rejected for being over 10MB on the API. Sometimes, the web app succeeds in cropping the image and the file is fine - others, you get the generic "Error while saving avatar".

My testing involved switching between the source image of my GitHub avatar and this equally large (3.05MB) file, hosted on the GitHub CDN, picking a mostly random full size crop of the image and submitting it.

As it's not a 100% reproducible case, here's a video :) - the API response in the console error you'll see is below and the stack trace linked here

https://user-images.githubusercontent.com/19671604/235033263-c4059ed7-f787-454a-bd31-16b7bb30283a.mp4

{
    "message": "File too large - files have to be less than 10MB in size",
    "messageArgs": [],
    "isHangarApiException": true,
    "httpError": {
        "statusCode": 413
    }
}
Rushmead commented 1 year ago

I've now determined this to be an issue with the toBlob call on the Cropper canvas element. If you do not tell it what type of image it is, it automatically converts it to a PNG (see both https://github.com/fengyuanchen/cropper/issues/542 and https://github.com/advanced-cropper/vue-advanced-cropper/issues/41) . This can cause the file size to increase dramatically before going to the server (I saw a 3.2MB JPEG become a 12MB PNG).

The solution that most people seem to take is to use the magic bytes at the beginning of the file to determine what kind of image the source is, apparently the mime type in the file object is determined based on the file extension, not the actual file contents (see https://github.com/advanced-cropper/vue-advanced-cropper/issues/41#issuecomment-653804898). This seems like the easiest solution at the moment, but perhaps not the most elegant.