PHP curl неправильно обрабатывает изображения

У меня есть внутренний прокси, который извлекает данные с моего собственного сервера и отображает их клиенту. Я хотел, чтобы код на стороне прокси был минимальным, и думал, что простая отправка данных, полученных с сервера контента, клиенту как есть, будет работать для всех типов мультимедиа. Он отлично работает для кода HTML/TEXT. Однако не для изображений. Я не могу понять, почему.

Вот код прокси-сервера:

$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;

Почему выше не отображаются изображения правильно? (Разве нельзя сделать прокси-сервер похожим на фиктивный мост, чтобы он не интерпретировал результат, отправленный сервером, а просто передал его и по-прежнему работал для всех типов контента/медиа?). Может ли кто-нибудь предложить самое чистое решение?


Примечания:

1) Контент-сервер обрабатывает все файлы через php-скрипт и правильно передает заголовок, используя header('Content-Type: image/jpeg');

Он отлично работает, если я обращаюсь напрямую с сервера. Однако с прокси не работает (браузер отображает бинарные данные).

2) Я тоже не очень хорошо понимаю CURLOPT_HEADER.

Если я использую

curl_setopt($curl_handle, CURLOPT_HEADER, 1);

браузер пытается загрузить сжатые данные (как текст, так и изображения).

Если я использую

curl_setopt($curl_handle, CURLOPT_HEADER, 0);

Браузер правильно отображает текст/изображения, но не данные изображения.


Это заголовки ответов, которые показывает Google Chrome, когда я получаю доступ к изображению в браузере через прокси (прямая ссылка).

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

Заголовки ответа, когда я обращаюсь к изображению непосредственно на сервере контента:

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

У меня такое ощущение, что это связано с тем, что Content-type является GZIP через прокси. Может кто-нибудь, пожалуйста, помогите мне понять это: изображения не сжаты apache по умолчанию? (Согласен, экономия может быть меньше). Если нет, то CURL (прокси) сжимает данные? Разве CURLOPT_ENCODING, «идентификация» не должны этому препятствовать? Как исправить?


person Community    schedule 29.11.2010    source источник
comment
Постоянные комментарии Спенсера помогли мне решить проблему. С CURLOPT_HEADER=1 я неправильно анализировал заголовки, а с CURLOPT_HEADER=0 я даже не пытался вернуть клиенту правильный заголовок.   -  person    schedule 29.11.2010


Ответы (2)


Вам нужно отправить правильные заголовки, используя header, чтобы сообщить браузеру правильный тип контента, иначе он предполагает, что это просто текст.

person Spencer Hakim    schedule 29.11.2010
comment
Мой сервер передает заголовок с помощью header('Content-Type: image/jpeg'); (изображение подается через PHP на сервере). Он отлично работает, если я обращаюсь напрямую с сервера. Однако через вышеуказанный прокси это не работает. Также, пожалуйста, смотрите мою добавленную заметку в вопросе. - person ; 29.11.2010
comment
Хорошо, а как это устроено? Я предполагаю, что ваш вывод HTML имеет что-то вроде <img src="someimage_proxy.php" /> или что? - person Spencer Hakim; 29.11.2010
comment
Я получаю доступ к someimage_proxy.php прямо в браузере. - person ; 29.11.2010
comment
И он отображает двоичный вывод или просто пустую страницу? Редактировать Упс, только что увидел, что вы уже упомянули об этом. Я не совсем уверен, но используйте панель «Сеть» в Firebug, чтобы увидеть заголовки, которые отправляются/получаются. - person Spencer Hakim; 29.11.2010
comment
Хорошо, позвольте мне отладить заголовки. Кстати, можете ли вы предложить правильную настройку для CURLOPT_HEADER (1 или 0)? - person ; 29.11.2010
comment
CURLOPT_HEADER определяет, включаются ли заголовки ответов в $result. Установка этого значения в 1, вероятно, сделает вашу жизнь немного проще, так как вам не придется беспокоиться об отправке правильного Content-type самостоятельно. - person Spencer Hakim; 29.11.2010
comment
добавил заголовки. любая подсказка? это из-за кодировки gzip? - person ; 29.11.2010
comment
Может быть, я не знаю, как конкретно настроен ваш сервер. - person Spencer Hakim; 29.11.2010
comment
@ JP19 Хорошо, ваши заголовки ответов прокси имеют Content-type: text/html. Это проблема. Возможно, типы MIME Apache испорчены, хотя я не слишком разбираюсь в этом. - person Spencer Hakim; 29.11.2010

Ну, вы получаете изображение в виде строки через Curl, поэтому, когда вы повторяете $result, вы печатаете данные для изображения, а не рендерите <img src="..." />

person Antonio Torres    schedule 29.11.2010
comment
Если бы я обращался к http//myserver.com/someimage.jpg непосредственно в браузере, мой сервер возвращал бы браузеру бинарные данные (без ‹img src....›). (На самом деле, при обнаружении ‹img src..› браузер сделает запрос на файл). - person ; 29.11.2010