Download a file to server from a url that require authentication

I am given a url when I am to enter my user credential and a CSV file can be saved or opened.
This work and I am able to see the content of the CSV file.
Now, I want to create a PHP script on my web server in which I can have the file be downloaded to a location I specify.

<?php
$username = 'userinfo';
$password = 'userpassword';

$remote_url = "https://test.com/report_template.do?CSV&jvar_report_id=1";

$context = stream_context_create(array(
    'http' => array(
        'header'  => "Authorization: Basic " . base64_encode("$username:$password")
    )
));

$fileName = file_get_contents($remote_url, false, $context);

$filePath = "csv/files/".$fileName;

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=\"$filePath \""); 
header("Content-type: text/csv");
header("Content-Transfer-Encoding: binary");
?>

Open in new window



What am I doing wrong?  Can someone please help?

Thanks,

lgduong
lgduongAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ray PaseurCommented:
I think these are two separate applications, and they can be built together to do the things you want.

First, here is how to password-protect a part (or all) of a web site.
http://www.experts-exchange.com/articles/2391/PHP-Client-Registration-Login-Logout-and-Easy-Access-Control.html

Second, here is how to force a download.
<?php // demo/force_download.php
/**
 * Show how to force a file download
 *
 * Choose a file to download, either via a hard-coded file path
 * or via a URL parameter like this
 *
 * path/to/demo/force_download.php?url=path/to/file.txt
 *
 * If you wanted to use the URL parameter, you might want to
 * (1) Secure the script with password protection
 * (2) replace the $url variable with something like this:
 * $url = $_GET['url'];
 *
 * If you use the URL parameter, be careful that the script
 * does not expose sensitive data on your server!
 */
error_reporting(E_ALL);


// WHAT FILE DO WE WANT TO DOWNLOAD?
$url = "http://www.IcoNoun.com/demo/short_text_file.txt";


// USE CASE
force_download($url);


// FUNCTION TO FORCE A DOWNLOAD FROM A FILE
function force_download($url, $filename=NULL)
{
    // GET THE DOWNLOAD FILE NAME
    if (empty($filename)) $filename = basename($url);

    // GET LENGTH AND FILE RESOURCE POINTER
    $hdr = get_headers($url, TRUE);
    $len = trim($hdr['Content-Length']);
    $fpr = fopen($url,'rb');

    // ON SUCCESS
    if ($fpr)
    {
        // THESE HEADERS ARE USED ON ALL BROWSERS
        header("Content-Type: application-x/force-download");
        header("Content-Disposition: attachment; filename=$filename");
        header("Content-length: $len");
        header("Expires: ".gmdate("D, d M Y H:i:s", mktime(date("H")+2, date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
        header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");

        // THIS HEADER MUST BE OMITTED FOR IE 6+
        if (FALSE === strpos($_SERVER["HTTP_USER_AGENT"], 'MSIE '))
        {
            header("Cache-Control: no-cache, must-revalidate");
        }

        // THIS IS THE LAST HEADER
        header("Pragma: no-cache");

        // FLUSH THE HEADERS TO THE BROWSER
        flush();

        // WRITE THE FILE
        fpassthru($fpr);
    }

    // ERROR
    else
    {
        trigger_error("Unable to open $url", E_USER_ERROR);
    }
}

Open in new window

lgduongAuthor Commented:
Ray,

I'm sorry.  Maybe I wasn't clear in my question.  I don't need to create password protected web page.  My site is already password protected and each page check for verification.  As for the force-download, will the file be downloaded to my local machine or will be downloaded to the web server that is running the script.  That is really what I want to do.  I want the php script to download the file from that remote url and save it on the web server.  For example, the php script (download.php) is run at this location on the webserver /www/var/html/run/download.php.  The csv file is then downloaded and save on the web server /www/var/html/files/filedownloaded.csv.
Ray PaseurCommented:
What is the original URL of the CSV file?
Exploring SharePoint 2016

Explore SharePoint 2016, the web-based, collaborative platform that integrates with Microsoft Office to provide intranets, secure document management, and collaboration so you can develop your online and offline capabilities.

Dave BaldwinFixer of ProblemsCommented:
"Authorization: Basic " is checked by Apache, the web server.  Web pages never see that. ??
Edward MillenCommented:
What sort of error are you getting?

Are you sure the remote server is actually using HTTP Basic authentication (rather than another method of requesting the username and password)?

Also, bear in mind that file_get_contents will return the actual full content of the remote URL, which you're currently putting into the $fileName variable and then using as a filename, so I don't think that's what you intended.

If you only want to save the file on your server, as mentioned in your subsequent comment, you don't need any of the header() lines.
You could simply do something like this (assuming your instance of PHP has the appropriate permissions to write to the given location):
$data = file_get_contents($remote_url, false, $context);
file_put_contents('/www/var/html/files/filedownloaded.csv', $data);

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
lgduongAuthor Commented:
Hello,

Sorry I just got back from time off.  That's why I haven't gotten back to this question.

Ray -- The original url would be the remote url (https://test.com/report_template.do?CSV&jvar_report_id=1).

Edward Millen - I made the following changes and the filedownloaded.csv does not appear in the directory /www/var/html/files/

$username = 'userinfo';
$password = 'userpassword';

$remote_url = "https://test.com/report_template.do?CSV&jvar_report_id=1";

$context = stream_context_create(array(
    'http' => array(
        'header'  => "Authorization: Basic " . base64_encode("$username:$password")
    )
));

$fileName = file_get_contents($remote_url, false, $context);

file_put_contents('/www/var/html/files/filedownloaded.csv', $fileName);

Open in new window

Ray PaseurCommented:
Are you sure that the correct URL is test.com?  It appears to be redirecting in a strange way, and a PHP script using file_get_contents() may not behave the way you want.

If that's not the correct URL, please tell us the correct URL so we can test with cURL.  Thanks.
lgduongAuthor Commented:
This was the correct solution. I had the path to download the file incorrectly.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.