backup.cgi: Read and deliver the requested backup in pieces

Message ID 20230510095203.2567-1-stefan.schantl@ipfire.org
State Accepted
Commit c797789c1f45dc76f4cf933ad3e3d24376c2b76e
Headers
Series backup.cgi: Read and deliver the requested backup in pieces |

Commit Message

Stefan Schantl May 10, 2023, 9:52 a.m. UTC
  Read-in the requested backup file line by line and directly deliver this
as stream to the client.

This fixes the problem with very big backups on systems with very
limited RAM, which resulted in an OOM kill of the CGI and delivery
process.

Fixes #13096.

Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org>
---
 html/cgi-bin/backup.cgi | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
  

Comments

Michael Tremer May 10, 2023, 10:11 a.m. UTC | #1
Reviewed-by: Michael Tremer <michael.tremer@ipfire.org>

> On 10 May 2023, at 10:52, Stefan Schantl <stefan.schantl@ipfire.org> wrote:
> 
> Read-in the requested backup file line by line and directly deliver this
> as stream to the client.
> 
> This fixes the problem with very big backups on systems with very
> limited RAM, which resulted in an OOM kill of the CGI and delivery
> process.
> 
> Fixes #13096.
> 
> Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org>
> ---
> html/cgi-bin/backup.cgi | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/html/cgi-bin/backup.cgi b/html/cgi-bin/backup.cgi
> index 1c01cb286..3888ccbff 100644
> --- a/html/cgi-bin/backup.cgi
> +++ b/html/cgi-bin/backup.cgi
> @@ -366,6 +366,13 @@ sub deliver_file() {
> 
> # Deliver content
> open(FILE, "<$file") or die "Unable to open $file: $!";
> - print <FILE>;
> +
> + # Read the file line by line and send it
> + # to the client.
> + while (<FILE>) {
> + print $_;
> + }
> +
> + # Close file handle.
> close(FILE);
> }
> -- 
> 2.30.2
>
  

Patch

diff --git a/html/cgi-bin/backup.cgi b/html/cgi-bin/backup.cgi
index 1c01cb286..3888ccbff 100644
--- a/html/cgi-bin/backup.cgi
+++ b/html/cgi-bin/backup.cgi
@@ -366,6 +366,13 @@  sub deliver_file() {
 
 	# Deliver content
 	open(FILE, "<$file") or die "Unable to open $file: $!";
-	print <FILE>;
+
+	# Read the file line by line and send it
+	# to the client.
+	while (<FILE>) {
+		print $_;
+	}
+
+	# Close file handle.
 	close(FILE);
 }