How can I give download access to files outside public_html directory?

前端 未结 3 961
囚心锁ツ
囚心锁ツ 2021-01-06 08:46

I have files stored outside the public_html folder for security purposes. However, I would like to link to specific files somehow where a user could download one of these fi

相关标签:
3条回答
  • 2021-01-06 09:22

    Another standard way to do this is using mod_xsendfile -- it will allow a web application to have the web server send a file as its output by specifying the path in a header (X-SendFile).

    0 讨论(0)
  • 2021-01-06 09:47

    You can do this with "php download handler":

    You can use method like this one to return file contents and file information headers to users browser, just make sure that nothing else is outputted before this.

    I suggest that you put this to separate file and call that for example download.php.

    function returnFile( $filename ) {
        // Check if file exists, if it is not here return false:
        if ( !file_exists( $filename )) return false;
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        // Suggest better filename for browser to use when saving file:
        header('Content-Disposition: attachment; filename='.basename($filename));
        header('Content-Transfer-Encoding: binary');
        // Caching headers:
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        // This should be set:
        header('Content-Length: ' . filesize($filename));
        // Clean output buffer without sending it, alternatively you can do ob_end_clean(); to also turn off buffering.
        ob_clean();
        // And flush buffers, don't know actually why but php manual seems recommending it:
        flush();
        // Read file and output it's contents:
        readfile( $filename );
        // You need to exit after that or at least make sure that anything other is not echoed out:
        exit;
    }
    

    Extending it for basic use:

    // Added to download.php
    if (isset($_GET['file'])) {
        $filename = '/home/username/public_files/'.$_GET['file'];
        returnFile( $filename );
    }
    

    Warning:

    This is basic example and does not take into account that user may try to take some evil advantages of $_GET that is not properly sanitized.

    This means basically that user can for example retrieve passwd file or some other sensitive information if certain conditions apply.

    For example, retrieving /etc/passwd:

    Just point browser to http://server.com/download.php?file=../../../etc/passwd and server returns that file. So before real use you should find out how to properly check and sanitize any user supplied arguments.

    0 讨论(0)
  • 2021-01-06 09:49

    It is not possible to for paths outside the public_html.

    mod_rewrite only rewrites the request, but the path still should be available to the users.

    0 讨论(0)
提交回复
热议问题