• Downloading strangeness: downloaded file has no content

    From Tim Streater@21:1/5 to All on Sat Oct 1 14:50:40 2022
    For those requesting that a file be downloaded from my website, having
    selected a file (a .zip or a .dmg), the following is then executed:

    <font color="#000000">header('Content-Description: File Transfer');</font> header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . basename ($file) .
    '"');
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0'); header('Pragma: public');
    header('Content-Length: ' . filesize ($file));

    ob_clean ();
    flush ();
    readfile ($file);


    For most of the files to be downloaded, this works just fine. But for one of them, the downloaded file has zero content at the receiver's end: it is zero bytes long. The file on the server is correct - I can download it using an FTP client and drag/drop the file off the server and onto my desktop. Then it has the correct size/content.

    Any suggestions as to why this might be?

    --
    HAL 9000: Dave. Put down those Windows disks. Dave. DAVE!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From J.O. Aho@21:1/5 to Tim Streater on Sat Oct 1 18:47:31 2022
    On 01/10/2022 16.50, Tim Streater wrote:
    For those requesting that a file be downloaded from my website, having selected a file (a .zip or a .dmg), the following is then executed:

    <font color="#000000">header('Content-Description: File Transfer');</font> header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . basename ($file) . '"');
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize ($file));

    ob_clean ();
    flush ();
    readfile ($file);


    For most of the files to be downloaded, this works just fine. But for one of them, the downloaded file has zero content at the receiver's end: it is zero bytes long.

    It could be a missing
    header('Content-Description: File Transfer');

    or it could be the html in the beginning of the page that causes the
    browser to think the file data is part of the web page.


    Any suggestions as to why this might be?

    If you are just doing what you paste here, I would suggest a direct link
    to the file instead.

    --

    //Aho

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jerry Stuckle@21:1/5 to Tim Streater on Sat Oct 1 12:57:19 2022
    On 10/1/2022 10:50 AM, Tim Streater wrote:
    For those requesting that a file be downloaded from my website, having selected a file (a .zip or a .dmg), the following is then executed:

    <font color="#000000">header('Content-Description: File Transfer');</font> header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . basename ($file) . '"');
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize ($file));

    ob_clean ();
    flush ();
    readfile ($file);


    For most of the files to be downloaded, this works just fine. But for one of them, the downloaded file has zero content at the receiver's end: it is zero bytes long. The file on the server is correct - I can download it using an FTP
    client and drag/drop the file off the server and onto my desktop. Then it has the correct size/content.

    Any suggestions as to why this might be?


    Tim,

    What's in your PHP error log? It's always the first place I check when
    I have weird problems.

    Have you checked the contents of $file? Is it correct - including the
    path? What is the result of filesize($file)? What are the ownership
    and permissions on the file? Does the web server have read access to it?

    --
    ==================
    Remove the "x"'s from my email address
    Jerry Stuckle
    stucklex.jerryx@gmail.com
    ==================

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Streater@21:1/5 to J.O. Aho on Sat Oct 1 19:44:14 2022
    On 01 Oct 2022 at 17:47:31 BST, "J.O. Aho" <user@example.net> wrote:

    On 01/10/2022 16.50, Tim Streater wrote:
    For those requesting that a file be downloaded from my website, having
    selected a file (a .zip or a .dmg), the following is then executed:

    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . basename ($file) . '"');
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize ($file));

    ob_clean ();
    flush ();
    readfile ($file);


    For most of the files to be downloaded, this works just fine. But for one of >> them, the downloaded file has zero content at the receiver's end: it is zero >> bytes long.

    It could be a missing
    header('Content-Description: File Transfer');

    That header is present. It's the first one.

    or it could be the html in the beginning of the page that causes the
    browser to think the file data is part of the web page.

    In which case I'd expect none of the downloads to work, whereas they work for
    4 out of the 5 files. This whole approach has worked without issue for several years.

    Any suggestions as to why this might be?

    If you are just doing what you paste here, I would suggest a direct link
    to the file instead.

    The above code is the end of the chain during which the user makes their
    choice and has it validated. Before the above code there is some parameter checking and a bit of logging.

    --
    If socialism helps the poor, why are the poor in socialist countries so much poorer than the poor in capitalist countries?

    Mark

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Streater@21:1/5 to Jerry Stuckle on Sat Oct 1 19:48:52 2022
    On 01 Oct 2022 at 17:57:19 BST, Jerry Stuckle <stuckle.jerry@gmail.com> wrote:

    On 10/1/2022 10:50 AM, Tim Streater wrote:
    For those requesting that a file be downloaded from my website, having
    selected a file (a .zip or a .dmg), the following is then executed:

    <font color="#000000">header('Content-Description: File Transfer');</font> >> header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . basename ($file) .
    '"');
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize ($file));

    ob_clean ();
    flush ();
    readfile ($file);


    For most of the files to be downloaded, this works just fine. But for one of >> them, the downloaded file has zero content at the receiver's end: it is zero >> bytes long. The file on the server is correct - I can download it using an FTP
    client and drag/drop the file off the server and onto my desktop. Then it has
    the correct size/content.

    Any suggestions as to why this might be?

    Tim,

    What's in your PHP error log? It's always the first place I check when
    I have weird problems.

    Good question. I'll have to get on to the hosting provider or see whether with the tools I have access to, I can locate it. I was minded to contact them anyway, in case there's some file caching issue that requires a restart of whatever VM they're running for me.

    Have you checked the contents of $file? Is it correct - including the
    path? What is the result of filesize($file)?

    I log these items just before the first header is sent and they are as expected. Filesize is 131Mbytes (not easily overlooked).

    What are the ownership
    and permissions on the file? Does the web server have read access to it?

    This is worth checking too, no doubt about it. :-)

    --
    "... you must remember that if you're trying to propagate a creed of poverty, gentleness and tolerance, you need a very rich, powerful, authoritarian organisation to do it." - Vice-Pope Eric

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jerry Stuckle@21:1/5 to Tim Streater on Sat Oct 1 19:13:55 2022
    On 10/1/2022 3:48 PM, Tim Streater wrote:
    On 01 Oct 2022 at 17:57:19 BST, Jerry Stuckle <stuckle.jerry@gmail.com> wrote:

    On 10/1/2022 10:50 AM, Tim Streater wrote:
    For those requesting that a file be downloaded from my website, having
    selected a file (a .zip or a .dmg), the following is then executed:

    <font color="#000000">header('Content-Description: File Transfer');</font> >>> header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . basename ($file) . >>> '"');
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize ($file));

    ob_clean ();
    flush ();
    readfile ($file);


    For most of the files to be downloaded, this works just fine. But for one of
    them, the downloaded file has zero content at the receiver's end: it is zero
    bytes long. The file on the server is correct - I can download it using an FTP
    client and drag/drop the file off the server and onto my desktop. Then it has
    the correct size/content.

    Any suggestions as to why this might be?

    Tim,

    What's in your PHP error log? It's always the first place I check when
    I have weird problems.

    Good question. I'll have to get on to the hosting provider or see whether with
    the tools I have access to, I can locate it. I was minded to contact them anyway, in case there's some file caching issue that requires a restart of whatever VM they're running for me.

    Have you checked the contents of $file? Is it correct - including the
    path? What is the result of filesize($file)?

    I log these items just before the first header is sent and they are as expected. Filesize is 131Mbytes (not easily overlooked).

    What are the ownership
    and permissions on the file? Does the web server have read access to it?

    This is worth checking too, no doubt about it. :-)


    Tim,

    131Mbytes? That brings up another question. Is this the larges of the
    files? Does your hosting company have a file size limit?

    Jerry

    --
    ==================
    Remove the "x"'s from my email address
    Jerry Stuckle
    stucklex.jerryx@gmail.com
    ==================

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From J.O. Aho@21:1/5 to Tim Streater on Sun Oct 2 00:18:29 2022
    On 01/10/2022 21.44, Tim Streater wrote:
    On 01 Oct 2022 at 17:47:31 BST, "J.O. Aho" <user@example.net> wrote:

    On 01/10/2022 16.50, Tim Streater wrote:
    For those requesting that a file be downloaded from my website, having
    selected a file (a .zip or a .dmg), the following is then executed:

    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . basename ($file) . '"');
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize ($file));

    ob_clean ();
    flush ();
    readfile ($file);


    For most of the files to be downloaded, this works just fine. But for one of
    them, the downloaded file has zero content at the receiver's end: it is zero
    bytes long.

    It could be a missing
    header('Content-Description: File Transfer');

    That header is present. It's the first one.

    My bad, my brain just didn't want to see that line at all, as it had
    font-tag around it in the original post.

    Any suggestions as to why this might be?

    If you are just doing what you paste here, I would suggest a direct link
    to the file instead.

    The above code is the end of the chain during which the user makes their choice and has it validated. Before the above code there is some parameter checking and a bit of logging.

    Jerry had some good points, I will extend one of his suggestions, the
    file permission and ownership, don't forget to look at the directories
    too, specially if you are running on Linux, so if one directory in the
    path do not have the right privileges set for the web server, then it
    will not be able to access anything in the subdirectories and files,
    even if they would have the correct privileges.

    Most likely in this case you need to look that either group rx on
    directories and r on files, some web-hosting sadly have it even worse
    and require other setting to have rx for directories and r for files.
    You will need to compare with a file that works to download from the web
    site with the one that do not work.

    I hope that ftp you mention is actually an sftp, otherwise anyone who
    can sniff the traffic will be able to get your password in plain text.

    --

    //Aho

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From J.O. Aho@21:1/5 to Tim Streater on Sun Oct 2 12:14:13 2022
    On 01/10/2022 21.44, Tim Streater wrote:

    ob_clean ();

    This will just clean out the output buffer, so the max size would then
    be limited of the buffer size, think you need to switch to use
    ob_end_clean() which disables the output buffer and is recommended in
    the php documentation for readfile.


    readfile ($file);

    By the way, what value does the redfile return?
    Also do you get an exception?
    Could also be got to check the file exists and can be read

    If(file_exists($file)) is_file($file))
    {
    if(is_file($file)) {
    if(is_readable($file)) {
    try {
    $retval = readfile ($file);
    // log the retval to your logfile
    } catch (Exception $ex) {
    //log the exception here
    }
    } else {
    // log that file not readable
    }
    } else {
    // log file not really a file, most likely a directory
    }
    } else {
    // log the file do not exists
    }


    --

    //Aho

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Streater@21:1/5 to Jerry Stuckle on Sun Oct 2 16:01:51 2022
    On 02 Oct 2022 at 00:13:55 BST, Jerry Stuckle <stuckle.jerry@gmail.com> wrote:

    On 10/1/2022 3:48 PM, Tim Streater wrote:
    On 01 Oct 2022 at 17:57:19 BST, Jerry Stuckle <stuckle.jerry@gmail.com> wrote:

    On 10/1/2022 10:50 AM, Tim Streater wrote:
    For those requesting that a file be downloaded from my website, having >>>> selected a file (a .zip or a .dmg), the following is then executed:

    <font color="#000000">header('Content-Description: File Transfer');</font> >>>> header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . basename ($file) . >>>> '"');
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize ($file));

    ob_clean ();
    flush ();
    readfile ($file);

    For most of the files to be downloaded, this works just fine. But for one of
    them, the downloaded file has zero content at the receiver's end: it is zero
    bytes long. The file on the server is correct - I can download it using an FTP
    client and drag/drop the file off the server and onto my desktop. Then it has
    the correct size/content.

    Any suggestions as to why this might be?

    Tim,

    What's in your PHP error log? It's always the first place I check when
    I have weird problems.

    Good question. I'll have to get on to the hosting provider or see whether with
    the tools I have access to, I can locate it. I was minded to contact them
    anyway, in case there's some file caching issue that requires a restart of >> whatever VM they're running for me.

    Have you checked the contents of $file? Is it correct - including the
    path? What is the result of filesize($file)?

    I log these items just before the first header is sent and they are as
    expected. Filesize is 131Mbytes (not easily overlooked).

    What are the ownership
    and permissions on the file? Does the web server have read access to it? >>
    This is worth checking too, no doubt about it. :-)

    131Mbytes? That brings up another question. Is this the largest of the files? Does your hosting company have a file size limit?

    That is the largest of the files, and following Aho's suggestion about buffering seems to have fixed it, at least for using Safari under macOS to download. I'll now fire up my VMs to check under Win/Lin. Permissions were OK.

    Thanks for your help and suggestions. I've not used PHP for some years and had forgotten what-all I used to do for testing this setup.

    --
    Tim

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tim Streater@21:1/5 to J.O. Aho on Sun Oct 2 15:57:25 2022
    On 02 Oct 2022 at 11:14:13 BST, "J.O. Aho" <user@example.net> wrote:

    On 01/10/2022 21.44, Tim Streater wrote:

    ob_clean ();

    This will just clean out the output buffer, so the max size would then
    be limited of the buffer size, think you need to switch to use
    ob_end_clean() which disables the output buffer and is recommended in
    the php documentation for readfile.

    This solved the problem.

    readfile ($file);

    By the way, what value does the readfile return?
    Also do you get an exception?

    I think I must have got a real error or exception at this point, as code after the readfile to check the readfile return and also compare with filesize() was not executed. I've not heard back from the hosting provider at this point.

    Thanks for your help.

    --
    "The idea that Bill Gates has appeared like a knight in shining armour to lead all customers out of a mire of technological chaos neatly ignores the fact that it was he who, by peddling second-rate technology, led them into it in the first place."
    - Douglas Adams

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)