Uploading larger file than the memory limit fails

Created on 13 June 2023, about 1 year ago
Updated 26 November 2023, 10 months ago

Problem/Motivation

Uploading large files that are potentially bigger than the allowed memory limit can ran into out of memory problems, causing the file upload to fail.

Steps to reproduce

  • Set PHP upload_max_filesize and post_max_size to 550M.
  • Set PHP memory_limit to 256M.
  • Ensure that your webserver can accept a file with 500 MB. (In nginx it can be set as client_max_body_size 550M; in either http, server or location block.)
  • Install Drupal with standard profile.
  • Add a new file field to a node with the maximum upload size of 550 MB.
  • Generate a test file (dd if=/dev/urandom of=file.txt bs=500M count=1, also the size of the file should be somewhat less than the allowed in relation to Drupal, php and webserver).
  • Try to upload the generated file to the file field.
  • In my test setup there was no error message nor log entries, so the upload just silently fails, saving the node the file won't be saved.
    After upload the ajax response should contain the error message, something like: Allowed memory size of 268435456 bytes exhausted (tried to allocate 524288032 bytes).

Proposed resolution

Replace move_uploaded_file() with stream_copy_to_stream() in \Drupal\Core\File\FileSystem::moveUploadedFile().
If you check some public FOSS projects, like NextCloud's source code, you can see this is a widely used solution for moving files in a memory friendly way: https://github.com/search?q=repo%3Anextcloud%2Fserver+stream_copy_to_str...

Alternative considerations

rename() was also considered as an alternative solution but after some research, it turned out that Symfony used to use rename() but they replaced it because rename() worked inconsistently when the source and target filesystem was different (like when the target was NFS.

https://github.com/symfony/symfony/commit/447ff915df4dc896bb5e2f7dc069c9... ---> related PR: https://github.com/symfony/symfony/pull/6211

Related issues:
https://github.com/symfony/symfony/pull/5878
https://github.com/symfony/symfony/issues/6185

Remaining tasks

See #12 for question about adding tests.

User interface changes

API changes

Data model changes

Release notes snippet

🐛 Bug report
Status

Needs work

Version

11.0 🔥

Component
File system 

Last updated 1 day ago

Created by

🇭🇺Hungary yce

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024