2

I cannot seem to figure this issue out. I'm downloading a file (Moodle .mbz extension) using PHP with HTTP headers. The file is first downloaded from Amazon S3 to a server using the aws php sdk, which works fine. The issue is downloading the file from the server to another workstation. No matter what I seem to change, the md5 checksums for the file on the workstation and the file on the server do not match. Clients cannot restore the .mbz file they have downloaded to their workstation. It seems something is happening to the file to change it in some way but I cannot figure out what.

I have referenced: 1. this tutorial 2. This similar SO question and various other resources via google. I'm desperate, please help if you can. I have ensured compression is off in the httpd.conf file. Turned debugging completely off in php.ini. I can replicate the issue in both my development and staging environment.

Here's the code for the direct download:

<?php
    if(!file_exists($filename))
    { 
        // file does not exist
        die('file '.$filename.' not found');
    } else 
    {
 $this->load->model('Job_model', 'job');
 $save_as = $this->job->get_file_name_from_key($filename);
        header("Content-Type: application/octet-stream");
        header("Content-Disposition: attachment; filename=\"$save_as\"");
        header("Expires: 0");
        header("Pragma: public");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Content-Length: " . filesize($filename));
        readfile($filename);
}

Using PHP with codeigniter framework, if that's relevant.

Thank you!

Edit: An octal dump of the first 16 bytes shows that 4 spaces are being appended to the beginning of the file downloaded using the above code vs the file on the server.

Kara
  • 21
  • 4
  • 1
    Just to confirm: if you download it with some other program the digest is fine? So you are really saying: why can't I get my code to download in MD5 compliant manner? – benc Nov 05 '18 at 20:46
  • @benc I'm sorry, I'm not sure I'm exactly understanding you. The file pulled directly from the server is valid (restores fine in Moodle), the file downloaded using the code I posted (a download button in a web application I built on the server) seems to somehow change the file such that it is no longer a "valid" file that will restore to moodle. This method of downloading is supposed to make downloading for ITCs easier but somehow the file is being mutated. I was just using the checksum difference as a means of showing that difference. I hope that explains what I meant better! – Kara Nov 05 '18 at 21:25
  • Yeah, thats what I needed to know. If you download with `curl` or `wget` does it have the 4 spaces? If it does not, then you need to look at the file writing docs and figure out the PHP internals. – benc Nov 06 '18 at 06:21

2 Answers2

0

This is not so much an answer as a suggestion for an experiment.

I'm wondering if there is a mime problem. I found this file which, on line 145, describes the mime type for 'mbz' as 'application/vnd.moodle.backup'. Maybe by changing the Content-Type header, you can get better results.

As I understand it, 'mbz' is basically a zip file. So try adding the following to the bottom of /application/config/mimes.php.

'mbz' => array('application/vnd.moodle.backup', 'application/zip'),

If you want to cover all the bases you could expand the definition to

'mbz' => array('application/vnd.moodle.backup', 'application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'),

Which takes all the possibilites for a zip type and makes the "default" 'application/vnd.moodle.backup'. I'd try the simpler version first.

Try this header

 header("Content-Type: application/vnd.moodle.backup");
DFriend
  • 8,869
  • 1
  • 13
  • 26
0

So I found this question, specifically the answer from MrPanda. I went through all the helpers and libraries (that I had written) I called/initialized in my controller and deleted any white space after the closing php tag. Problem solved. Thank you to the users who tried helping me! Two days of frustration finally come to a close.

Kara
  • 21
  • 4
  • Happy you found the solution. You might want to consider removing the closing php tags wherever you can. Read the third paragraph of [this page of PHP documentation](http://php.net/manual/en/language.basic-syntax.phptags.php) for rationale. – DFriend Nov 07 '18 at 21:01
  • More thoughts on removing closing PHP tags [HERE](https://stackoverflow.com/questions/4410704/why-would-one-omit-the-close-tag) – DFriend Nov 07 '18 at 21:03