0

I've put together a download script (called file.php) using headers and readfile(), the actual download logic being as follows:

header("Content-type: " . mime_content_type($path));
header("Content-Length: " . filesize($path));
header('Content-Disposition: attachment; filename="' . $fileName . '"');
ob_clean();
flush();
readfile($path);

Before this, there's about 30 lines of mysqli-access, to get the file info from db. Only one block of php, no html output (except for the occasional echo upon exception, but they're not called).

This works splendid in my local environment, the file is force-downloaded correctly. However, when I upload it to my site (shared hosting), it opens the files directly in the browser, which won't work.

I've played around quite a bit with it, and found that if I put only the logic above in a separate file (with the addition of query params for the variables needed), it works.

I don't like it, but decided to roll with it. To that end I replaced the download-logic in my file.php with header("Location: download.php?path={path}&fileName={fileName});", where download.php contains only the download logic.

Again, works splendid locally, but once I've put it on the host, it does not work. However, this time it's the header("Location:..."); that doesn't work. Accessing download.php directly does.

So I've come to the conclusion that the problem is with the headers not taking effect, rather than the download code itself. I'm using headers in other scripts, and they work fine, it's just this one script.

I've seen various explanations as to why this might happen, but can't find any that apply to this situation, especially not since it works in one environment but not the other.

Any ideas would be most welcome.

  • try using the full file path in the header, rather than just the page – BizzyBob Jan 15 '17 at 21:48
  • @BizzyBob Tried that, doesn't make any difference unfortunately. Using just the page works elsewhere on the site, too. – Nationalbear Jan 15 '17 at 21:54
  • What is a content-type for this response? Why are you using `ob_clean` and `flush`? – Mateusz Woźniak Jan 15 '17 at 21:54
  • Can you please post the code where you call `header("Location: …")`? Also, do you have full error reporting on? Just to be sure you’re not missing some “invisible” error. – lxg Jan 15 '17 at 21:56
  • @MateuszWoźniak `ob_clean` and `flush` is something I added to correct some problem I had once. Not sure what exactly, since this is a side-project that has been a while in the running. Removing them makes no difference for the better though. – Nationalbear Jan 15 '17 at 22:03
  • Can you post whole file? – Mateusz Woźniak Jan 15 '17 at 22:05
  • 2
    I'd bet that if you did activate error reporting and/or checked your logs, you'd see the good old "headers already sent" warning… – deceze Jan 15 '17 at 22:06
  • @deceze Correct, boy I do feel foolish now. Turns out it was a runaway whitespace that got me. The fact that it worked locally threw me off some, still not sure why that is. My bad. – Nationalbear Jan 15 '17 at 22:10
  • That *is* explicitly addressed in the duplicate too… – deceze Jan 15 '17 at 22:11

0 Answers0