0

I have an internal proxy that fetches data from my own server and displays to the client. I wanted to keep the proxy side code minimal, and thought that just sending the data got from the content server as-it-is to the client will work for all media types. It is working fine for HTML/TEXT code. However, not for images. I am unable to understand why.

Here is the proxy side code:

$curl_url="http//myserver.com/someimage.jpg";
//Open connection
$curl_handle = curl_init();
curl_setopt($curl_handle,CURLOPT_COOKIE,session_name()."=".session_id().";");
//Set the url, number of POST vars, POST data
curl_setopt($curl_handle, CURLOPT_URL, $curl_url);
curl_setopt($curl_handle, CURLOPT_POST, count($_POST));
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $_POST);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_AUTOREFERER, TRUE);
curl_setopt($curl_handle, CURLOPT_HEADER, 0);
/// curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $curl_request_headers);
/// Above is actually uncommented but omitting details for brevity. They are just 
/// HTTP headers passed by the client
curl_setopt($curl_handle, CURLOPT_ENCODING, "identity");

//Execute post
$result = curl_exec($curl_handle);

//Close connection
curl_close($curl_handle);

echo $result;

Why does above not display images correctly? (Is it not possible to make the proxy like a dummy bridge - that it does not interpret the result sent by the server but just pass it on and still make it work for all content/media types?). Can someone suggest the cleanest solution?


Notes:

1) The content server handles all files through a php script, and is correctly passing the header using header('Content-Type: image/jpeg');

It works fine if I access directly from the server. However from the proxy, it does not work (browser displays binary data).

2) I don't understand CURLOPT_HEADER very well either.

If I use

curl_setopt($curl_handle, CURLOPT_HEADER, 1);

browser tries to download gzipped data (for text as well as images).

If I use

curl_setopt($curl_handle, CURLOPT_HEADER, 0);

browser displays text/images correctly, but not image data.


These are the response headers shown by Google Chrome, when I access the image in the browser via the proxy (direct link).

Response Headers
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:2576
Content-Type:text/html
Date:Mon, 29 Nov 2010 18:03:52 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive:timeout=15, max=100
Pragma:no-cache
Server:Apache/2.2.14 (Ubuntu)
Vary:Accept-Encoding
X-Powered-By:PHP/5.3.2-1ubuntu4.5

The response headers when I access image directly on the content server:

Accept-Ranges:bytes
Connection:Keep-Alive
Content-Length:3669
Content-Type:image/jpeg
Date:Mon, 29 Nov 2010 18:07:25 GMT
ETag:"1802b6-e55-49633c9623e40"
Keep-Alive:timeout=15, max=96
Last-Modified:Mon, 29 Nov 2010 16:44:33 GMT
Server:Apache/2.2.11 (Ubuntu) PHP/5.2.6-3ubuntu4.6 with Suhosin-Patch mod_ssl/2.2.11 OpenSSL/0.9.8g

I have a feeling this is due to the Content-type being GZIP via the proxy. Can someone please help me understand this: Aren't images GZIPPed by apache by default? (I agree savings might be less). If not, then is CURL (the proxy) Gzipping the data? Shouldn't CURLOPT_ENCODING, "identity" prevent it? How do I fix?

1
  • Spencer's continued comments helped me solve the problem. With CURLOPT_HEADER=1, I was not parsing the headers correctly and with CURLOPT_HEADER=0, I was not trying to give the correct header back to the client even. Commented Nov 29, 2010 at 19:15

2 Answers 2

1

You need to send the proper headers using header to tell the browser the correct content-type, otherwise it assumes it is just plaintext.

Sign up to request clarification or add additional context in comments.

9 Comments

My server is passing the header using header('Content-Type: image/jpeg'); (the image is served via PHP on the server). It works fine if I access directly from the server. However, through the above proxy, it doesn't work. Also please see my added note in the ques.
Ok, so, how is this set up? I'm assuming your HTML output has something like <img src="someimage_proxy.php" />, or what?
And is it displaying the binary output, or just a blank page? Edit Whoops, just saw that you already mentioned that. I'm not really sure, but use the Net panel in Firebug to see the headers that are being sent/received.
CURLOPT_HEADER controls whether the response headers are included in $result. Setting this to 1 would probably make your life a bit easier, as you wouldn't have to worry about sending the right Content-type on your own.
@JP19 Ok, your proxy response headers have "Content-type: text/html". That's the problem. It may be that Apache's MIME types are screwed up, I'm not too knowledgeable about that, though.
|
0

Well, You're getting the image as a string via Curl, so when you echo $result, you're printing the data for the image as opposed to rendering <img src="..." />

1 Comment

If I were to access http//myserver.com/someimage.jpg directly in the browser, my server would give back binary data to the browser (no <img src....>). (Actually, on encountering <img src..>, the browser would make the request for the file).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.