PHP中的代理脚本可以避免丢失crossdomain.xml - 缺少小调整

时间:2010-10-08 08:44:34

标签: php actionscript loader crossdomain.xml

第一个背景 - 所以你看,我没有尝试任何恶意:我在俄罗斯社交网络vkontakte.ru有一个显示用户头像的flash应用程序。到目前为止,我的.swf文件已在其域中托管,因此获取和缩放头像效果很好。

现在我想将我的应用转换为iframe类型,以便.swf将托管在我的域中,因此我无法再扩展我的.swf中的头像:我的域名, http://vkontakte.ru/crossdomain.xml中也没有列出“*”,因此.swf可以下载并显示头像,但不能再缩放它们(访问myLoader.content会引发SecurityError)。

我决定在PHP中编写一个代理脚本来获取脚本?img = 参数中指定的图像,然后将其传递给stdout(经过一些检查并且不存储任何内容) :

<?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可以被反汇编。

谢谢你,Alex

1 个答案:

答案 0 :(得分:0)

我相信你的第一个假设是正确的,你发送标题太晚了,或者你没有得到你期望的mime标题。

首先尝试使用file_put_contents记录哑剧,然后如果您发现任何用途确实为时已晚,您可以查看output buffering

但是,如果您根本没找到标题,那么您可能会在wrong context,也许是HTTP?

您的奖金问题; iframe的页面托管在服务器上,在该服务器上,您可能正在运行PHP,使用session_start()创建会话,设置$_SESSION['gotvisit'] = TRUE(或类似的东西)。然后使用$id = session_id()检索会话ID,此ID现在可以通过标准Flash变量传递给您的Flash。让Flash在图像请求中传递该变量,然后在你的img脚本中执行;

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

祝你好运。