I use PHP to redirect downloads from my site, mainly by reading the remote stream and repeating it from my site (it was a utility that I quickly developed when I needed downloads to bypass the firewall).
The last thing I checked, everything is fine. I wanted to add functionality yesterday and found that the returned stream is now preceded by 4 empty characters. I can’t understand where they came from. No matter what happens, the uploaded file always starts with (4 spaces provided by the mode of viewing invisible characters in Notepad ++) and otherwise does not change.
[Edit] In response to the comment: these spaces are not part of the source file. To test this behavior, I downloaded the source file (JPG for a simple test), then downloaded it through a proxy and split the two. 4 bytes, which can be eliminated by removing the first four characters of the proxy file. Of course, until I allow diff, the proxy file is not applicable.
[Edit2] These characters are also not a specification. Remember, there are 4 of them. Wikipedia tells us the UTF-8 specification would be a 3-byte length:
The presentation of the UTF-8 specification is a sequence of bytes 0xEF,0xBB,0xBF. A text editor or web browser that incorrectly interprets text as ISO-8859-1 or CP1252 will display characters for this .
Now I can’t come up with any changes I made to the code that could explain this new behavior. Maybe an update in PHP? I don't have phpinfo on this server yet (it will get one today), but it works on the updated Ubuntu 14.04.
I think I will have to redo the code to solve it. Only I do not know how to do this. Maybe someone could try?
Below is the code:
function download($url, $filename, $mimetype) {
header('Content-Type: ' . $mimetype['mime']);
header("Content-Disposition: attachment; filename=$filename");
IOUtils::readfile($url);
}
In IOUtils:
<?php
class IOUtils {
public static function readfile($path) {
$handle = fopen($path, 'rb');
while (!feof($handle)) {
echo fread($handle, 8192);
ob_flush();
}
fclose($handle);
}
}
?>
Before calling the function, downloadnothing is displayed. This will obviously fail, as it headercannot be called up as soon as the conclusion has begun. This means that this happens while reading $handleor writing it to the stream.