Search code examples
http-headerscontent-disposition

Content-disposition: how does it find a file?


In PHP I am using

header('Content-Disposition: attachment;filename="mysong.mp3"');

to force download a certain file.

In one of the cases it happened that the file size was zero bytes (even though the file exists and is 3MB). That's why I asked myself: how does the filename parameter get the file actually? There's no path given to reach it, even if it's nested inside multiple folders.

I didn't find anything useful in this RFC nor anywhere else. I'm probably asking something obvious that I missed.


Solution

  • The Content-Disposition: attachment;filename="mysong.mp3" header tells the browser to not try to display the body of the response but to save it in a file; the value "mysong.mp3" is a suggestion for the file name but the browsers usually ask the user about what name to use (and provide "mysong.mp3" as default).

    This line of code does not read any file from disk and it does not send any content back to the browser. Your code have to do this. It can read the content from a file or generate it on the fly or produce it by any other means; it's entirely up to you.

    For example, if you have the content in a file you can do something like this:

    $filepath = '/foo/bar/file.mp3';          // put the correct file path and name here
    
    header('Content-Disposition: attachment;filename="mysong.mp3"');
    header('Content-Length: '.filesize($filepath));
    readfile($filepath);
    

    The Content-Length header is not required but it is useful for the browser to produce a nice progress bar, estimate the remaining time and know, at the end of the transfer, if the file transferred successfully (when it receives the announced number of bytes) or something went wrong (received less bytes).