Forcing download of a file corrupts some bytes

When using the code below, a specific file is forced to download (so not showed in the browser).

      $quoted = sprintf('"%s"', addcslashes(basename($download), '"\\'));
      $size = filesize($download);
      $finfo = finfo_open(FILEINFO_MIME_ENCODING);

      header("Content-Description: File Transfer");
      header("Content-Transfer-Encoding: " . finfo_file($finfo, $download));
      header("Connection: Keep-Alive");
      header("Expires: 0");
      header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
      header("Pragma: public");
      header("Content-Length: " . $size);
      header("Content-disposition: attachment; filename=" . $quoted);
      readfile($download);
      exit();

This script works perfect, but not when called from without a Kirby environment;

It does download the file, and the bits and bytes seems to be the same, but there are extreme little differences which causes the file to be corrupt (so can’t be openend).

I’ve setup a test-environment, downloading the picture below…

The output from a plain server (FileDiff on the left) is okay, but when called from a Kirby environment, there are slightly differences (on the right, in the FileDiff screen).

Any idea what Kirby is doing, while reading the raw contents of a file? I’ve tried several scripts on three server-types - but none of them work in Kirby…

Well, that’s strange. I would have expected something like a “headers already sent” warning that’s corrupting the file, but just 6 arbitrary changed bytes are weird. Have you verified that it’s not the diff tool by calculating the checksums of the two files?

Also, do you know about f::download()? It basically does the same thing as your code but is a native Kirby function. :wink:

It’s not the headers - it’s really the six bytes (in this example) that differs.

I didn’t know f::download() - I’ll check it out; but my solution also shows stats / graphs / etc… for every download (including trends, ip-addresses, referrers, etc…).

Thx! Will update here when the plug-in is ready :stuck_out_tongue:


f::download() does - indeed - the same, even the file corruption is the same :slight_smile:

I have found a workaround;

  1. Parse the file variable in a Kirby environment.
  2. Set a header (from the Kirby environment) to a page outside of the environment, with the file as a variable in the URL.
  3. The page (outside the environment) knows - due to the variable - which file is queried and downloads it as a raw file.
  4. This works perfect :slight_smile:

The weirdest thing is, when downloading a PDF file - all the text in the PDF is shown okay, but the images are cleared…

Needed this option for this project;

Kirby Download Monitor

(Still won’t work the official way).

I think it has something to do with the issues mentioned on this page;

https://github.com/ian-cox/Kirby-MinifyHTML

I did disable all plugins, the problem remains… but I guess it’s something like that.

- edit - Indeed this plug-in did corrupt the downloads; I installed a fresh version of Kirby, everythings works… I install the plug-in; downloads became corrupt.

I decided to remove the plug-in and switched to Kirby KRB - which has a minifier that “respects” forced downloads (so no minifying).