Прокси-скрипт на PHP для обхода отсутствующего crossdomain.xml - отсутствие мелких настроек - PullRequest
0 голосов
/ 08 октября 2010

1-й фон - чтобы вы увидели, что я не пытаюсь ничего вредоносного: у меня есть флеш-приложение в российской социальной сети vkontakte.ru, которое отображает аватары пользователей. До сих пор мой файл .swf размещался на их домене, так что выборка и масштабирование аватаров работали хорошо.

Теперь я бы хотел переключить мое приложение на тип iframe, чтобы .swf был размещен на моем домене, и поэтому я больше не могу масштабировать аватары в моем .swf: ни в моем домене, ни "*" не указаны в http://vkontakte.ru/crossdomain.xml, поэтому .swf может загружать и отображать аватары, но больше не может их масштабировать (доступ к myLoader.content вызывает SecurityError).

Я решил написать прокси-скрипт на PHP, который будет извлекать изображение, указанное в параметре scripts ? Img = , а затем просто передать его в стандартный вывод (после некоторых проверок и без сохранения чего-либо):

<?php

define('MAX_SIZE', 1024 * 1024);

$img = $_GET['img'];
if (strpos($img, '..') !== false ||
    !preg_match(',^http://[\w.]*vkontakte\.ru/[\w./?]+$,i', $img))
        exit();

$opts = array(
        'http'=>array(
                'method' => 'GET',
                'header' => "Accept-language: en\r\n" .
                            "Cookie: foo=bar\r\n"
        )
);

$ctx = stream_context_create($opts);
stream_context_set_params($ctx, array('notification' => 'callback'));
$fp = fopen($img, 'r', false, $ctx);
fpassthru($fp);
fclose($fp);

function callback($code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) {
        if ($code == STREAM_NOTIFY_FILE_SIZE_IS && $bytes_max > MAX_SIZE)
                exit();

        if ($code == STREAM_NOTIFY_PROGRESS && $bytes_transferred > MAX_SIZE)
                exit();

        if ($code == STREAM_NOTIFY_MIME_TYPE_IS) {
                $mime = strtolower($message);
                switch($message) {
                        case 'image/gif':
                        case 'image/png':
                        case 'image/jpg':
                        case 'image/jpeg':
                                // XXX this doesn't work XXX
                                header('Content-Type: ' . $mime);
                                break;
                        default:
                                exit();
                }
        }
}

?>

Моя проблема в том, что заголовок $ mime никогда не печатается (или печатается слишком поздно?).

Когда я получаю, например, мой аватар напрямую: http://cs971.vkontakte.ru/u59751265/a_7567890a.jpg затем я вижу заголовок Content-Type: image / jpeg , отправляемый в браузер.

Но когда я получаю его через свой прокси-скрипт, я не вижу этот заголовок.

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

И в качестве дополнительного вопроса: я беспокоюсь, что мой .swf будет не единственным приложением, вызывающим мой proxy.php, но я не могу найти хороший способ его обезопасить (возможно, такого способа нет) - Я не могу хранить секрет в моем .swf и в .php - потому что .swf можно разобрать.

Спасибо, Алекс

1 Ответ

0 голосов
/ 08 октября 2010

Я считаю, что ваше первое предположение верно, вы отправили заголовок слишком поздно или не получили ожидаемых заголовков MIME.

Прежде всего попробуйте зарегистрировать пантомимы, используя file_put_contents, затем, если вы обнаружите, что уже слишком поздно, чтобы быть полезным, вы можете посмотреть буферизацию вывода .

Если, однако, вы вообще не попали в заголовок, возможно, вы находитесь в неверном контексте , возможно, HTTP?

На ваш бонусный вопрос; страница iframe размещается на сервере, на этом сервере вы, вероятно, работаете с PHP, создайте сеанс с session_start(), установите $_SESSION['gotvisit'] = TRUE (или что-то в этом роде). Затем извлеките идентификатор сеанса, используя $id = session_id(), этот идентификатор теперь можно передавать на флэш-память со стандартными переменными флэш-памяти. Сделайте, чтобы flash передал эту переменную в запросе изображения, затем в вашем скрипте img сделайте;

session_id($_GET['ses']);
session_start();
if(!isset($_SESSION['gotvisit']))
    die('no access');

Удачи вам.

...