Question

La situation

Je suis en train de créer un site de formation vidéo pour un client sur le Cloud Rackspace en utilisant la pile LAMP traditionnelle (nuage de Rackspace a à la fois Windows et des piles de lampe). Les vidéos et autres fichiers multimédias que je suis au service sur ce site doivent être protégés en tant que mon client facture d'argent pour y accéder. Il n'y a pas de DRM ou d'affaires drôle comme ça, essentiellement nous stockons de fichiers en dehors de la racine Web et d'utiliser PHP pour authentifier l'utilisateur avant de pouvoir accéder aux fichiers en utilisant mod_rewrite pour exécuter la demande par PHP.

Alors disons que l'utilisateur demande un fichier à l'adresse suivante:

http://www.example.com/uploads/preview_image/29.jpg

J'utilise mod_rewrite pour réécrire cette URL pour:

http://www.example.com/files.php?path=%2Fuploads%2Fpreview_image%2F29.jpg

Voici une version simplifiée du script files.php:

<?php
// Setups the environment and sets $logged_in
// This part requires $_SESSION
require_once('../../includes/user_config.php');

if (!$logged_in) {
    // Redirect non-authenticated users
    header('Location: login.php');
}

// This user is authenticated, continue

$content_type = "image/jpeg";

// getAbsolutePathForRequestedResource() takes 
// a Query Parameter called path and uses DB
// lookups and some string manipulation to get
// an absolute path. This part doesn't have
// any bearing on the problem at hand
$file_path = getAbsolutePathForRequestedResource($_GET['path']);

// At this point $file_path looks something like
// this: "/path/to/a/place/outside/the/webroot"

if (file_exists($file_path) && !is_dir($file_path)) {
    header("Content-Type: $content_type");
    header('Content-Length: ' . filesize($file_path));
    echo file_get_contents($file_path);
} else {
    header('HTTP/1.0 404 Not Found'); 
    header('Status: 404 Not Found');
    echo '404 Not Found';
}
exit();

?>

Le problème

Permettez-moi de commencer par dire que cela fonctionne parfaitement pour moi. Sur les machines de test locales, il fonctionne comme un charme. Cependant, une fois déployé sur le nuage, il cesse de fonctionner. Après un certain débogage il se avère que si une demande vers le cloud a certaines extensions de fichiers tels que .JPG, .PNG ou .SWF (à savoir les extensions de fichiers multimédias généralement statiques.) La demande est acheminée vers un système de cache appelé Varnish. Le résultat final de ce routage est qu'au moment où ce processus fait à mon script PHP la session n'est pas présent.

Si je change l'extension dans l'URL .php ou si j'ajoute même un paramètre de requête Varnish est contournée et le script PHP peut obtenir la session. Aucun droit de problème? Je vais juste ajouter un paramètre de requête de sens à mes demandes!

Voici le hic: Les fichiers multimédias que je suis au service par le biais de ce système sont demandés par les fichiers SWF compilés que j'ai le contrôle sur zéro. Ils sont générés par des logiciels tiers et je ne l'espoir d'ajouter ou de modifier les URL qu'ils demandent.

Y at-il d'autres options que j'ai à ce sujet?

Mise à jour:. Je dois souligner que j'ai vérifié ce comportement avec le soutien Rackspace et ils ont dit qu'il n'y a rien qu'ils puissent faire à ce sujet

Était-ce utile?

La solution

Si l'application flash demandant suit réoriente, je voudrais essayer de répondre avec une redirection sur la première demande et réécrire la seconde, par exemple.

GET .../29.jpg

à

header("Status: 302 Moved temporarily");
header("Location: .../r.php?i=29.jpg&random=872938729348");

Ensuite, votre r.php fournit le fichier sur la deuxième demande.

Dans le cas contraire (BTW. Toujours), j'envoyer explicitement les en-têtes ainsi que la livraison des fichiers statiques qui accepte Varnish et agit en conséquence, quelque chose comme

header("Cache-Control: no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");

: Je place la commande exit(); après votre première déclaration de header() être sûr que le reste du script est pas exécuté. header() envoie seulement les en-têtes.

Je trouve également d'utiliser plus fiable ob_start() comme des espaces dans votre fichier PHP peut conduire à des erreurs gênantes lors de l'ajout des en-têtes.

Autres conseils

J'ai la même situation, et je l'ai contacté Rackspace dans l'espoir d'une meilleure réponse.

Je suis un! Ils ont mis sur pied une FAQ décrivant une demi-douzaine de façons de contourner / modifier la mise en cache:

http://cloudsites.rackspacecloud.com/index.php/How_can_I_bypass_the_cache%3F

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top