1

i have a database where are stored all email in raw mode.

I extract data with good library https://github.com/php-mime-mail-parser/php-mime-mail-parser, in particular attachments.

Now, from html page i have:

 $.ajax({ 
        async: false,
        type: "POST",
        url: "/mail/get/attachment",
        data: {
            'idMail'    : idMail,
            'filename'  : filename
        },
        success: function(data){

            cl(data);

        },
        error: function(data){       

        }
        }).done(function (data) {

    });

this call my method php:

    $parser = new PhpMimeMailParser\Parser();
    $parser->setText($mail['rawContent']);
    $attachments = $parser->getAttachments();

    foreach ($attachments as $attachment) {
        if ($attachment->getFilename() == $filename){

            $file = $attachment->getContent();
            $size = strlen($file);

            @ob_start('');


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

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

Request and Response of script

As evidenced by the response, everything seems correct but none response show.

  • The filesize of attachment is correct...i have only string for calculate it. I don't want download on filesystem.

  • If i change the ajax client request from "async: false" into "async : true" the chrome console give me the error "net::ERR_CONTENT_LENGTH_MISMATCH".

Where i wrong ?

I don't want to get to the point of having to download the messages on the server every time and then use a simple url to recover it since I already have everything in the database.

What solution can i use?

Thanks!

## UPDATE
ob_clean();
echo $file;
flush();

This procedure return this in console but the download not start.

enter image description here

Michele
  • 262
  • 2
  • 9
  • 1
    Where do your store the attachment binary data? In the server file system or in the database? readfile() takes an filename as argument and outputs the content. This only works if the binary data is accessable via an supported URL (e.g. file://). If you have the binary in the database (as I understand your "I have everything in the database") then you have to echo the file content. – simirimia May 05 '20 at 15:51
  • Yes, i have a field that contain full raw email content. I get only one attachment per request for download. I try to echo the file content but the download not start and the content return in the return console. – Michele May 05 '20 at 18:28
  • Ah, sorry, I was too focused on the lib and didn't take care of ajax. Check: https://stackoverflow.com/questions/20830309/download-file-using-an-ajax-request. In short: do you need ajax? Without it is simpler. If there is a good reason for it, check some of the answers and what they are doing in the .then() clause. – simirimia May 06 '20 at 09:23

1 Answers1

0

I just had a quick look at the library. Attachment::getContent() returns the actual content. So you need to:

ob_clean();
echo $file;
flush()

As stated in my firts comment, readfile() takes a URL pointing to a file, not the file content.

If you really need to download the file via Ajax, check download file using an ajax request. The easy way is doing it without Ajax.

BTW: I doubt this will work with multiple attachments. You can only send one file per request.

simirimia
  • 409
  • 2
  • 9