How to use $phpVm->header()?
BSLFE
Joined: 2008-08-04
Posts: 13 |
![]() |
I'm looking at the DownloadItemView class and I'm trying to understand how it manages to send custom HTTP headers to the client. From what I understood, the photo.tpl template creates a link to the DownloadItem view which then handles the HTTP header creation. However, I cannot do the same in my custom module, although I have copied the code from the DownloadItemview class and modified it for my needs. It's identical except for the "Content-Disposition" header. This is how I think it works: Is there a step I am missing which the DownloadItem class does? Any help will be appreciated! |
|
alecmyers
Joined: 2006-08-01
Posts: 4342 |
![]() |
what is your code doing then? |
|
BSLFE
Joined: 2008-08-04
Posts: 13 |
![]() |
It does nothing after it sent the binary data, just like the DownloadItem view class. |
|
alecmyers
Joined: 2006-08-01
Posts: 4342 |
![]() |
I mean, you haven't explained your problem very well. Quote:
I cannot do the same in my custom module Perhaps if you elaborate on that someone might be able to provide some help. |
|
BSLFE
Joined: 2008-08-04
Posts: 13 |
![]() |
I'm not asking about my custom module but I'd like to understand the DownloadItem view class. I hope I can solve my problem myself once I understood DownloadItem view. |
|
alecmyers
Joined: 2006-08-01
Posts: 4342 |
![]() |
What is it that you don't understand about the class? |
|
BSLFE
Joined: 2008-08-04
Posts: 13 |
![]() |
BSLFE wrote:
I'm looking at the DownloadItemView class and I'm trying to understand how it manages to send custom HTTP headers to the client. From what I understood, the photo.tpl template creates a link to the DownloadItem view which then handles the HTTP header creation. |
|
alecmyers
Joined: 2006-08-01
Posts: 4342 |
![]() |
You know, for someone who's asking for support you might trying being a bit less "smart", and bit more keen to help those who are prepared to help you. Quote:
'm trying to understand how it manages to send custom HTTP headers to the client. I'm looking at DownloadItem.inc now, and its use of the $phpVm seems fairly straightforward. It sends a custom header every time you call $phpVm->header(...) as you can verify by looking at GalleryPhpVm.class file. I can't believe that you haven't already worked that out, so I'm at a loss to understand what kind of extra understanding you're asking for. So, let me ask again - I could quote myself but I won't descend to it - what is it that you don't understand about the class? |
|
BSLFE
Joined: 2008-08-04
Posts: 13 |
![]() |
I have worked out that $phpVm->header() sends headers of course, however my module doesn't do that. It sends out "text/html" for the content-type when instead binary data is being sent. I know the renderImmediate function is meant for such modules that are supposed to deliver custom output and thus custom headers. As far as I know I have shaped my module exactly after the Downloaditem class, but the Downloaditem class must have do something different that I cannot derive from looking at the code alone. I understand, once the user clicks on the link to download an image, the Downloaditem view is the only "code" involved in delivering this image, correct? Or are there other steps before the Downloaditem class? |
|
alecmyers
Joined: 2006-08-01
Posts: 4342 |
![]() |
Quote:
I understand, once the user clicks on the link to download an image, the Downloaditem view is the only "code" involved in delivering this image, correct? Or are there other steps before the Downloaditem class? No, all gallery accesses (including a url with ...g2_view=core.DownloadItem... in it) go through main.php, so obviously there's more code than just one class involved. The content type is sent in this line, in _sendFile(...): $phpVm->header('Content-type: ' . $data['mimeType']); and $data['mimeType'] is previously derived via this line, in the class's renderImmediate function: $ret = $this->_sendFile(array('derivativePath' => $path, 'mimeType' => $item->getMimeType(), 'pseudoFileName' => $pseudoFileName)); |
|
BSLFE
Joined: 2008-08-04
Posts: 13 |
![]() |
Of course I know that main.php is a vital part of every gallery2 process. What I meant was that at some point DownloadItem gets "control" over the HTTP header output and I wonder what it does in order to get to that point. I think I have understood the DownloadItem code but I must be missing something else that's not part of DownloadItem which causes my problems. About the mime type: yes I know what DownloadItem does in order to determine the mime-type out of the gallery item. I have specified the HTTP header Content-type according to my output data but still the client receives the text/html header. So I'm searching for something else in the gallery2 code (but not it in DownloadItem) which permits DownloadItem to manipulate the HTTP headers. I'd be thrilled to learn what that could be |
|
alecmyers
Joined: 2006-08-01
Posts: 4342 |
![]() |
Quote:
DownloadItem gets "control" over the HTTP header output No - it just outputs the headers one by one, in real time, so to speak, each time the header(...) function is called. The phpVm->header(..) function directly calls the php function header(). Nothing more complicated than that. Quote:
I'm searching for something else in the gallery2 code (but not it in DownloadItem) which permits DownloadItem to manipulate the HTTP headers. There's nothing that sophisticated. Do some basic debugging, change the code in obvious ways, print strings to the output, change the headers at the point you think they're being output to a bit of random text to make sure that's where they're coming from, follow the excution flow with echo statements etc. Usual stuff. EDIT: thought: see the php page http://uk2.php.net/header which has this comment "The optional replace parameter indicates whether the header should replace a previous similar header,..." - maybe you're somehow sending two sets of headers in error? |
|
BSLFE
Joined: 2008-08-04
Posts: 13 |
![]() |
After days that turned into weeks of searching and questioning myself I finally found the solution to my problem and it's quite stupid IMO I don't know if this is a "feature" or security measure or a bug but I hope I will save someone else the time of dealing with this problem. |
|
alecmyers
Joined: 2006-08-01
Posts: 4342 |
![]() |
It's neither a bug nor a security feature - it's correct operation. If you include even a single character (including whitespace) before the opening "<?php" or after the closing "?>" of any .php or .inc file then php sends that/those characters directly as output, as if it were regular html. Once output is sent, it's too late to call header(..) http://uk.php.net/header contains this in pretty much the first paragraph: Quote:
Remember that header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP. It is a very common error to read code with include(), or require(), functions, or another file access function, and have spaces or empty lines that are output before header() is called. The same problem exists when using a single PHP/HTML file. If you are displaying errors in php (such as by putting Gallery into debug mode), you get a "headers already sent" warning in the output stream. It also shows up in the php/apache error log. Glad you found the problem. |
|