Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Headers in fpassthru() output

15 views
Skip to first unread message

Michael T. Davis

unread,
Feb 6, 2012, 9:40:07 PM2/6/12
to
So far, I've tested a call to fopen followed by a call to fpassthru
on a remote (http://...) JPEG file with PHP v4.4.7 in the "OSU Web Server"
running under OpenVMS V8.3 on an Alpha, and with PHP v5.3.4 in Apache v2.2.17
running under Mac OS X v10.6.8. The JPEG file is served by a Webcam. The
documentation (on php.net) for "http://" says the stream opened by fopen only
provides access to the body of the response. Why is it, then, that when I
call on fpassthru for the (JPEG URL) stream, I see the headers included in the
data returned?

The code looks basically like this:

$image = fopen ( "http://...jpg", "r" );
foreach ( $http_response_header as $header )
{
echo "{$header}\r\n";
}
echo "\r\n";
fpassthru ( $image );
fclose ( $image );

With the above, the headers are clearly visible at the beginning of the data,
rendering a lot of meaningless code in the browser window, rather than an
actual image. One work-around I've developed is...

$image = fopen ( "http://...jpg", "r" );
$inHeaders = 1;
while ( $inHeaders && ! feof ( $image ) )
{
$line = fgets ( $image );
echo $line;
$inHeaders = ( $line != "\r\n" );
}
if ( ! feof ( $image ) )
fpassthru ( $image );
fclose ( $image );

Can anyone explain why I'm seeing behavior counter to the documentation with
"fopen ( 'http://...' )" and "fpassthru (...)"? (FWIW, the purpose of the
code is to "proxy" a Webcam image that isn't directly available, so that as
far as the browser is concerned, the image is served by the web server
hosting this PHP code.)

Thanks,
Mike

M. Strobel

unread,
Feb 7, 2012, 3:48:37 AM2/7/12
to
I can't confirm the problem - no headers here:

strobel@s114-intel:~> php -a
Interactive shell

php > $h = fopen('http://php.net','r');
php > fpassthru ($h);
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>PHP: Hypertext Preprocessor</title>
...

Tested on an ubuntu 10.04 server.

/Str.

M. Strobel

unread,
Feb 7, 2012, 3:56:14 AM2/7/12
to
Am 07.02.2012 03:40, schrieb Michael T. Davis:
> So far, I've tested a call to fopen followed by a call to fpassthru
> on a remote (http://...) JPEG file with PHP v4.4.7 in the "OSU Web Server"
> running under OpenVMS V8.3 on an Alpha, and with PHP v5.3.4 in Apache v2.2.17
> running under Mac OS X v10.6.8. The JPEG file is served by a Webcam. The
> documentation (on php.net) for "http://" says the stream opened by fopen only
> provides access to the body of the response. Why is it, then, that when I
> call on fpassthru for the (JPEG URL) stream, I see the headers included in the
> data returned?
>
> The code looks basically like this:
>
> $image = fopen ( "http://...jpg", "r" );
> foreach ( $http_response_header as $header )
> {
> echo "{$header}\r\n";

You should not echo the headers, this will send your web server’s headers, and as
body your echoed headers.

Use header() function instead - http://de.php.net/manual/de/function.header.php

/Str.

"Álvaro G. Vicario"

unread,
Feb 7, 2012, 4:34:05 AM2/7/12
to
El 07/02/2012 3:40, Michael T. Davis escribió/wrote:
> So far, I've tested a call to fopen followed by a call to fpassthru
> on a remote (http://...) JPEG file with PHP v4.4.7 in the "OSU Web Server"
> running under OpenVMS V8.3 on an Alpha, and with PHP v5.3.4 in Apache v2.2.17
> running under Mac OS X v10.6.8. The JPEG file is served by a Webcam. The
> documentation (on php.net) for "http://" says the stream opened by fopen only
> provides access to the body of the response. Why is it, then, that when I
> call on fpassthru for the (JPEG URL) stream, I see the headers included in the
> data returned?
>
> The code looks basically like this:
>
> $image = fopen ( "http://...jpg", "r" );
> foreach ( $http_response_header as $header )
> {
> echo "{$header}\r\n";
> }
> echo "\r\n";
> fpassthru ( $image );
> fclose ( $image );
>
> With the above, the headers are clearly visible at the beginning of the data,
> rendering a lot of meaningless code in the browser window, rather than an
> actual image.

I don't know for sure what manual page you are quoting (you just point
to the PHP site) but the full quote at the page for the HTTP wrapper [1] is:

«The stream allows access to the body of the resource; the headers are
stored in the $http_response_header variable.»

... and that's exactly what you are doing: printing the values of the
$http_response_header variable [2].

[1] http://es2.php.net/manual/en/wrappers.http.php
[2] http://es2.php.net/manual/en/reserved.variables.httpresponseheader.php





> One work-around I've developed is...
>
> $image = fopen ( "http://...jpg", "r" );
> $inHeaders = 1;
> while ( $inHeaders&& ! feof ( $image ) )
> {
> $line = fgets ( $image );
> echo $line;
> $inHeaders = ( $line != "\r\n" );
> }
> if ( ! feof ( $image ) )
> fpassthru ( $image );
> fclose ( $image );
>
> Can anyone explain why I'm seeing behavior counter to the documentation with
> "fopen ( 'http://...' )" and "fpassthru (...)"?

Neither http://es.php.net/manual/en/function.fopen.php nor
http://es.php.net/fpassthru claim that $http_response_header should not
get populated...



--
-- http://alvaro.es - Álvaro G. Vicario - Burgos, Spain
-- Mi sitio sobre programación web: http://borrame.com
-- Mi web de humor satinado: http://www.demogracia.com
--

Michael T. Davis

unread,
Feb 7, 2012, 11:36:18 AM2/7/12
to

In article <jgqr6d$dlh$1...@dont-email.me>,
I'm referencing the English version of the documentation that you
are citing.

>
>
>
>
>
>> One work-around I've developed is...
>>
>> $image = fopen ( "http://...jpg", "r" );
>> $inHeaders = 1;
>> while ( $inHeaders&& ! feof ( $image ) )
>> {
>> $line = fgets ( $image );
>> echo $line;
>> $inHeaders = ( $line != "\r\n" );
>> }
>> if ( ! feof ( $image ) )
>> fpassthru ( $image );
>> fclose ( $image );
>>
>> Can anyone explain why I'm seeing behavior counter to the documentation with
>> "fopen ( 'http://...' )" and "fpassthru (...)"?
>
>Neither http://es.php.net/manual/en/function.fopen.php nor
>http://es.php.net/fpassthru claim that $http_response_header should not
>get populated...

I didn't claim that $http_response_header was invalid. As I
mentioned in the parenthetical at the end of the original post, I'm trying
to serve the JPEG image of a network Webcam from the host where I have the
PHP script, in order to make it appear as if the JPEG image comes from the
PHP-running host. This means I need to send the headers that come from
the response of the Webcam to the browser. I can certainly leverage
$http_response_header and push the contents to the broswer, but if I do
that--given the behavior I'm seeing--it seems I would still need to parse
the headers from the fopen call and "drop them on the floor" before sending
the "actual" body/image of what comes from the Webcam. If I'm going to
parse the headers, I figured I might as well do something with them, which
is why the work-around doesn't call on $http_response_header.

>
>
>
>--
>-- http://alvaro.es - Álvaro G. Vicario - Burgos, Spain
>-- Mi sitio sobre programación web: http://borrame.com
>-- Mi web de humor satinado: http://www.demogracia.com
>--

Regards,
Mike

M. Strobel

unread,
Feb 7, 2012, 11:50:22 AM2/7/12
to
Am 07.02.2012 17:36, schrieb Michael T. Davis:

> I didn't claim that $http_response_header was invalid. As I
> mentioned in the parenthetical at the end of the original post, I'm trying
> to serve the JPEG image of a network Webcam from the host where I have the
> PHP script, in order to make it appear as if the JPEG image comes from the
> PHP-running host. This means I need to send the headers that come from
> the response of the Webcam to the browser. I can certainly leverage
> $http_response_header and push the contents to the broswer, but if I do
> that--given the behavior I'm seeing--it seems I would still need to parse
> the headers from the fopen call and "drop them on the floor" before sending
> the "actual" body/image of what comes from the Webcam. If I'm going to
> parse the headers, I figured I might as well do something with them, which
> is why the work-around doesn't call on $http_response_header.
--cut
>
> Regards,
> Mike

This does not sound like you read and understood my answers.

Drop your workaround, and start sending the headers with the header() function using
$http_response_header.

/Str.

Michael T. Davis

unread,
Feb 7, 2012, 12:35:06 PM2/7/12
to

In article <9pd32e...@mid.uni-berlin.de>, "M. Strobel"
OK, this was my original code:

$image = fopen ( "http://...jpg", "r" );
foreach ( $http_response_header as $header )
{
echo "{$header}\r\n";
}
echo "\r\n";
fpassthru ( $image );
fclose ( $image );

The issue was apparently my use of `echo' to send the headers to the
browser. I took your direction literally, and it seems to work:

$image = fopen ( "http://...jpg", "r" );
foreach ( $http_response_header as $header )
{
header ( $header );
}
fpassthru ( $image );
fclose ( $image );

As I thought about it, my mistake was clear.

>
>/Str.

Thanks,
Mike

"Álvaro G. Vicario"

unread,
Feb 8, 2012, 4:10:13 AM2/8/12
to
El 07/02/2012 17:36, Michael T. Davis escribió/wrote:
>> I don't know for sure what manual page you are quoting (you just point
>> to the PHP site) but the full quote at the page for the HTTP wrapper [1] is:
>>
>> «The stream allows access to the body of the resource; the headers are
>> stored in the $http_response_header variable.»
>>
>> ... and that's exactly what you are doing: printing the values of the
>> $http_response_header variable [2].
>>
>> [1] http://es2.php.net/manual/en/wrappers.http.php
>> [2] http://es2.php.net/manual/en/reserved.variables.httpresponseheader.php
>
> I'm referencing the English version of the documentation that you
> are citing.

Well, the documentation I'm citing is already in English :)



>> Neither http://es.php.net/manual/en/function.fopen.php nor
>> http://es.php.net/fpassthru claim that $http_response_header should not
>> get populated...
>
> I didn't claim that $http_response_header was invalid. As I
> mentioned in the parenthetical at the end of the original post, I'm trying
> to serve the JPEG image of a network Webcam from the host where I have the
> PHP script, in order to make it appear as if the JPEG image comes from the
> PHP-running host. This means I need to send the headers that come from
> the response of the Webcam to the browser. I can certainly leverage
> $http_response_header and push the contents to the broswer, but if I do
> that--given the behavior I'm seeing--it seems I would still need to parse
> the headers from the fopen call and "drop them on the floor" before sending
> the "actual" body/image of what comes from the Webcam. If I'm going to
> parse the headers, I figured I might as well do something with them, which
> is why the work-around doesn't call on $http_response_header.

I think you already got it, according to your latest post in this
thread. You were probably getting confused by some CGI modules that send
the raw output as generated by the script, so you have to start printing
the HTTP headers plus a blank line. It's not the case in PHP: the output
of echo statements always goes to the response body.

M. Strobel

unread,
Feb 8, 2012, 5:38:50 AM2/8/12
to
:-0

Once you've got this you could proceed to optimize the headers / write your own -
cache? content-type?

/Str.
0 new messages