0

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

现在我想将我的应用程序切换到 iframe 类型,以便 .swf 将托管在我的域中,因此我无法再缩放我的 .swf 中的头像:既不是我的域,也不是“* " 在http://vkontakte.ru/crossdomain.xml中列出,因此 .swf 可以下载和显示头像,但不能再缩放它们(访问 myLoader.content 会引发 SecurityError)。

我决定用 PHP 编写一个代理脚本,它将获取脚本?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() 是否会被骗从我的 Web 服务器提供本地文件。

作为一个额外的问题:我担心我的 .swf 将不是唯一调用我的 proxy.php 的应用程序,但我想不出保护它的好方法(也许没有这样的方法) - 我可以不要在我的 .swf 和 .php 中存储秘密 - 因为 .swf 可以反汇编。

谢谢你,亚历克斯

4

1 回答 1

0

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

首先尝试使用 记录 mime file_put_contents,然后如果您发现确实为时已晚,无法使用,您可以查看output buffering

但是,如果您根本没有到达标题,那么您可能处于错误的上下文中,也许是 HTTP?

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

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

祝你好运。

于 2010-10-08T09:37:47.070 回答