2010-10-08 21 views
0

1er le fond - de sorte que vous voyez, que je ne cherche rien de malicieux: J'ai une application flash dans le réseau social russe vkontakte.ru qui affiche avatars d'utilisateur. Jusqu'à présent, mon fichier .swf a été hébergé sur leur domaine, de sorte que la récupération et mise à l'échelle avatars a bien fonctionné. Maintenant, je voudrais changer mon application à un type iframe, de sorte que le fichier .swf sera hébergé sur mon domaine et donc je ne suis plus capable de faire évoluer les avatars dans mon .swf: ni mon domaine , ni "*" sont listés dans http://vkontakte.ru/crossdomain.xml et ainsi le .swf peut télécharger et afficher les avatars, mais ne peut plus les mettre à l'échelle (accéder à myLoader.content renvoie SecurityError).script proxy en PHP pour contourner crossdomain.xml manquant - tweaks mineurs manquants

J'ai décidé d'écrire un script de proxy en PHP qui chercher l'image spécifiée dans les scripts img = paramètres puis juste passer à la stdout (après quelques contrôles et sans enregistrer quoi que ce soit):

<?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(); 
       } 
     } 
} 

?> 

Mon problème est que l'en-tête $ mime n'est jamais imprimé (ou est imprimé trop tard?).

Quand je vais chercher par exemple mon avatar directement: http://cs971.vkontakte.ru/u59751265/a_7567890a.jpg puis-je voir le Content-Type : tête image/jpeg envoyé au navigateur. Mais quand je le récupère via mon script proxy, je ne vois pas cet en-tête.

Peut-être devrais-je mieux utiliser une fonction différente à la place de fopen()? Je ne suis pas très compétent en PHP. Aussi je suis inquiet si fopen() peut être trompé dans le service des fichiers locaux à partir de mon serveur web. En guise de question supplémentaire: Je crains que mon .swf ne soit pas la seule application à appeler mon proxy.php, mais je ne peux pas trouver un bon moyen de le sécuriser (peut-être qu'il n'y en a pas)) - Je ne peux pas stocker un secret dans mon .swf et dans le .php - parce que le .swf peut être démonté.

Merci, Alex

Répondre

0

Je crois que votre première hypothèse est juste, vous envoyez l'en-tête trop tard ou vous ne recevez pas les en-têtes de mime que vous attendez. Tout d'abord essayer d'enregistrer les mimes en utilisant file_put_contents, puis si vous découvrez qu'il est en effet trop tard pour être utile, vous pouvez regarder output buffering.

Si toutefois vous n'obtenez pas à l'en-tête du tout, vous pourriez être dans le wrong context, HTTP peut-être?

Pour votre question de bonus; la page de l'iframe est hébergée sur un serveur, sur ce serveur vous exécutez probablement PHP, créez une session avec session_start(), réglez $_SESSION['gotvisit'] = TRUE (ou quelque chose comme ça). Puis récupérez l'identifiant de session en utilisant $id = session_id(), cet identifiant que vous pouvez maintenant passer à votre flash avec des variables flash standard. Avez-flash passer cette variable dans la demande de l'image, la prochaine fois dans votre script img, faire;

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

Bonne chance à vous.