Browse Source

#848 Download file from server and send it user

Download remote backup from the storage server and saves file to local server. And allow user to download file normally
When download has been completed it will delete the file. In case big files / slow connections the file will life will be extended.
Jaap Marcus 5 years ago
parent
commit
ee9aec6148
3 changed files with 214 additions and 2 deletions
  1. 1 0
      CHANGELOG.md
  2. 187 0
      bin/v-download-backup
  3. 26 2
      web/download/backup/index.php

+ 1 - 0
CHANGELOG.md

@@ -40,6 +40,7 @@ All notable changes to this project will be documented in this file.
 - Improved "Forgot password" function prevent brute forcing.
 - Update Backup counter propperly when v-delete-user-backup ran.
 - Dropped support for Debian 8 according to EOL.
+- Improved Backup function. 
 
 ## [1.1.1] - 2020-03-24 - Hotfix
 ### Features

+ 187 - 0
bin/v-download-backup

@@ -0,0 +1,187 @@
+#!/bin/bash
+# info: Download backup
+# options: BACKUP 
+#
+# The function download back-up from remote server
+
+
+#----------------------------------------------------------#
+#                    Variable&Function                     #
+#----------------------------------------------------------#
+
+# Import Hestia variable for cron launch
+source /etc/profile
+
+# Argument definition
+backup=$1
+
+# Define backup dir
+if [ -z "$BACKUP" ]; then
+    BACKUP=/backup
+fi
+
+# Includes
+source $HESTIA/func/main.sh
+source $HESTIA/func/domain.sh
+source $HESTIA/func/ip.sh
+source $HESTIA/func/db.sh
+source $HESTIA/func/rebuild.sh
+source $HESTIA/conf/hestia.conf
+
+# Defining FTP command function
+ftpc() {
+    /usr/bin/ftp -n $HOST $PORT <<EOF
+    quote USER $USERNAME
+    quote PASS $PASSWORD
+    lcd $BACKUP
+    binary
+    $1
+    $2
+    $3
+    quit
+EOF
+}
+
+# FTP backup download function
+ftp_download() {
+    source $HESTIA/conf/ftp.backup.conf
+    if [ -z "$PORT" ]; then
+        PORT='21'
+    fi
+    if [ -z $BPATH ]; then
+        ftpc "get $1"
+    else
+        ftpc "cd $BPATH" "get $1"
+    fi
+}
+
+# SFTP command function
+sftpc() {
+    expect -f "-" <<EOF "$@"
+        set timeout 60
+        set count 0
+        spawn /usr/bin/sftp -o StrictHostKeyChecking=no \
+            -o Port=$PORT $USERNAME@$HOST
+        expect {
+            "password:" {
+                send "$PASSWORD\r"
+                exp_continue
+            }
+            -re "Couldn't|(.*)disconnect|(.*)stalled|(.*)not found" {
+                set count \$argc
+                set output "Disconnected."
+                set rc $E_FTP
+                exp_continue
+            }
+            -re ".*denied.*(publickey|password)." {
+                set output "Permission denied, wrong publickey or password."
+                set rc $E_CONNECT
+            }
+            -re "\[0-9]*%" {
+                exp_continue
+            }
+            "sftp>" {
+                if {\$count < \$argc} {
+                    set arg [lindex \$argv \$count]
+                    send "\$arg\r"
+                    incr count
+                } else {
+                    send "exit\r"
+                    set output "Disconnected."
+                    if {[info exists rc] != 1} {
+                        set rc $OK
+                    }
+                }
+                exp_continue
+            }
+            timeout {
+                set output "Connection timeout."
+                set rc $E_CONNECT
+            }
+        }
+        if {[info exists output] == 1} {
+            puts "\$output"
+        }
+    exit \$rc
+EOF
+}
+
+# SFTP backup download function
+sftp_download() {
+    source $HESTIA/conf/sftp.backup.conf
+    if [ -z "$PORT" ]; then
+        PORT='22'
+    fi
+    cd $BACKUP
+    if [ -z $BPATH ]; then
+        sftpc "get $1" > /dev/null 2>&1
+    else
+        sftpc "cd $BPATH" "get $1" > /dev/null 2>&1
+    fi
+
+}
+
+# Google backup download function
+google_download() {
+    source $HESTIA/conf/google.backup.conf
+    gsutil="$HESTIA/3rdparty/gsutil/gsutil"
+    export BOTO_CONFIG="$HESTIA/conf/.google.backup.boto"
+    ${gsutil} cp gs://$BUCKET/$BPATH/$1 $BACKUP/ > /dev/null 2>&1
+    if [ "$?" -ne 0 ]; then
+        check_result "$E_CONNECT" "gsutil failed to download $1"
+    fi
+}
+
+
+#----------------------------------------------------------#
+#                    Verifications                         #
+#----------------------------------------------------------#
+
+args_usage='BACKUP'
+check_args '1' "$#" "$args_usage"
+is_format_valid 'backup'
+
+#----------------------------------------------------------#
+#                       Action                             #
+#----------------------------------------------------------#
+
+# Checking local backup
+if [ ! -e "$BACKUP/$backup" ]; then
+    if [[ "$BACKUP_SYSTEM" =~ "google" ]]; then
+        google_download $backup
+        downloaded='yes'
+    fi
+    if [[ "$BACKUP_SYSTEM" =~ "sftp" ]] && [ -z "$downloaded" ]; then
+        sftp_download $backup
+        downloaded='yes'
+    fi
+    if [[ "$BACKUP_SYSTEM" =~ "ftp" ]] && [ -z "$downloaded" ]; then
+        ftp_download $backup
+        downloaded='yes'
+    fi
+    if [ -z "$downloaded" ]; then
+        check_result $E_NOTEXIST "backup file $backup doesn't exist in '${BACKUP}' folder"
+    else
+        chmod 0640 $BACKUP/$backup
+        chown admin:admin $BACKUP/$backup
+    fi
+fi
+
+echo "
+#!/bin/bash
+# Reset at timer every 15 min after 1st hour if the file is still downloading / Check if hestia-ng is still accessing $BACKUP/$backup
+
+if lsof $BACKUP/$backup | grep hestia-ng; then
+at -f /$BACKUP/$backup.sh now + 15 minutes
+else 
+    rm $BACKUP/$backup;
+    rm $BACKUP/$backup.sh;
+fi" >  $BACKUP/$backup.sh;
+
+at -f /$BACKUP/$backup.sh now + 60 minutes
+#----------------------------------------------------------#
+#                       Hestia                             #
+#----------------------------------------------------------#
+
+
+exit

+ 26 - 2
web/download/backup/index.php

@@ -5,9 +5,33 @@ session_start();
 include($_SERVER['DOCUMENT_ROOT']."/inc/main.php");
 $backup = basename($_GET['backup']);
 
+$downloaded = false;
 // Check if the backup exists
 if (!file_exists('/backup/'.$backup)) {
-    exit(0);
+    //try to download
+    if ((!empty($_SESSION['user'])) && ($_SESSION['user'] != 'admin')) {
+        if (strpos($backup, $user.'.') === 0) {
+            exec(HESTIA_CMD."v-download-backup " . escapeshellarg($backup), $output, $return_var);
+            check_return_code($return_var,$output);
+            unset($output);
+            if(!$_SESSION['error_msg']){
+                $downloaded = true;
+            }
+        }else{
+            exit(0);
+        }
+    }else{
+        exec(HESTIA_CMD."v-download-backup " . escapeshellarg($backup),$output, $return_var);
+        check_return_code($return_var,$output);
+        unset($output);
+        if(!$_SESSION['error_msg']){
+            $downloaded = true;
+        }
+    }
+    if (!file_exists('/backup/'.$backup)) {
+        exit(0);
+        $downloaded = false;
+    }
 }
 
 // Data
@@ -23,4 +47,4 @@ if ((!empty($_SESSION['user'])) && ($_SESSION['user'] != 'admin')) {
         header("Content-Disposition: attachment; filename=\"".$backup."\";" ); 
         header("X-Accel-Redirect: /backup/" . $backup);
     }
-}
+}