4

This was working last night, but I must have accidentally changed something, because it isn't now.

What I am trying to do should be clear from these headers:

Content-Disposition: attachment;filename=english_customizable.xml
Location: http://tortoisewrath.com/files/2.xml

However, when this header is sent, the Content-Disposition part doesn't work after the redirect.

...Why?

Tortoise
  • 208
  • 3
  • 11
  • 2
    Those two headers need to be on separate lines, is that a posting mistake or genuine? – sg3s Jun 22 '12 at 19:55
  • @sg3s Sorry for the late reply; I was testing that. I didn't know that they needed to be on separate lines; however, I can't figure out how to make them be on separate lines in PHP. I'll work on that... – Tortoise Jun 22 '12 at 20:05
  • Well, I got that to work, but the Content-Disposition doesn't work now. I've updated my question with the new problem. – Tortoise Jun 22 '12 at 20:07
  • 1
    Actually, it’s not entirely clear for me what you are trying to accomplish. – Gumbo Jun 22 '12 at 20:14

1 Answers1

2

What you're trying to do is inadvisable check this question; Header Location + Content Disposition

Content-Disposition + Location header

But you can do it, to make it work you will have to buffer your whole response before sending it. You can do this with output buffering

Else the browser may interpret the Location header before the file is downloaded. It's sketchy either way, so you shouldn't want to do this.

Please note that forcing 'save as' using Content-Disposition: attachment; will make sure the client doesn't go/navigate anywhere, so the method below on its own should be fine in any case.

Streaming a file in php

To just quote a guy who has his brains in the right place:

// To use header() with 'content-type', why don't you use mime_content_type() function rather than checking the type on the basis of extension? 
// Example code: 

<?php 
$file="test.docx"; 
header("Pragma: public"); 
header('Content-disposition: attachment; filename='.$file); 
header("Content-type: ".mime_content_type($file)); 
header('Content-Encoding: identity'); 
ob_clean(); 
flush(); 
readfile($file); 
?> 

// Use $file to map to whichever type of file. 
// Note: the mime types should already be defined in apache settings

Source: http://www.php.net/manual/en/function.header.php#107581

Note that the original answer used Content-Transfer-Encoding which doesn't actually exist in HTTP. The comment below that source explains it: http://www.php.net/manual/en/function.header.php#107044

Community
  • 1
  • 1
sg3s
  • 9,411
  • 3
  • 36
  • 52
  • I hereby 302 you to the asker's comment on the accepted answer for that question: How will that go with ~ 300mb movie files :\? – Tortoise Jun 22 '12 at 20:14
  • @Tortoise well, it won't, probably. That's my point about it being sketchy. And that is probably why it doesn't work 'anymore'. – sg3s Jun 22 '12 at 20:16
  • Is there any means by which to call a `Content-Disposition: attachment` or equivalent on a file without buffering it? (As stated in the question, I'm pretty sure this was working in one way or another yesterday...) – Tortoise Jun 22 '12 at 20:20
  • @Tortoise yes, first make sure output buffering is **disabled** then you can just `echo file_get_contents(/* file path here */)` and it should stream the file directly to the client. This does mean you can't use the `Location` header though. – sg3s Jun 22 '12 at 20:22
  • The `Location` header wasn't entirely necessary; the necessary part was streaming the file to the client. I'll let you know how well this works. – Tortoise Jun 22 '12 at 20:24
  • @Tortoise I updated my answer based on that question, since I found a method someone had thought about for more than two seconds. – sg3s Jun 22 '12 at 20:34
  • YES YES YES YES YES YES YES YES THANK YOU (By the way, I thought about that for a full _three_ seconds, thank you very much.) – Tortoise Jun 22 '12 at 20:34
  • There is no Content-Transfer-Encoding header field in HTTP. – Julian Reschke Jun 22 '12 at 21:11
  • @JulianReschke I know, my bad for blindly copying an answer from somewhere else, fixed :) – sg3s Jun 22 '12 at 21:29