繁体   English   中英

如果URL具有某些文件扩展名,则RackSpace Cloud剥离$ _SESSION

[英]RackSpace Cloud Strips $_SESSION if URL Has Certain File Extensions

情况

我正在使用传统的LAMP堆栈(RackSpace的云同时具有Windows和LAMP堆栈)在RackSpace云上为客户端创建一个视频培训站点。 我在此站点上提供的视频和其他媒体文件需要受到保护,因为我的客户需要付费才能访问它们。 没有像这样的DRM或有趣的事情,实质上,我们将文件存储在Web根目录之外,并使用PHP验证用户的身份,然后用户才能使用mod_rewrite通过PHP运行请求来访问文件。

假设用户在此URL请求文件:

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

我正在使用mod_rewrite将该URL重写为:

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

这是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();

?>

问题

首先,我说这对我来说非常有效。 在本地测试机上,它就像一个魅力。 但是,一旦部署到云中,它将停止工作。 经过一些调试后,结果发现,如果对云的请求具有某些文件扩展名,例如.JPG,.PNG或.SWF(即通常为静态媒体文件的扩展名),则该请求将路由到一个名为Varnish的缓存系统。 这种路由的最终结果是,当整个过程进入我的PHP脚本时,该会话就不存在了。

如果我将URL中的扩展名更改为.PHP或什至添加了查询参数,那么Varnish将被绕过,PHP脚本可以获取会话。 没问题吧? 我只会在我的请求中添加一个毫无意义的查询参数!

麻烦之处是:我通过该系统提供的媒体文件是通过对我具有零控制权的已编译SWF文件请求的。 它们是由第三方软件生成的,我不希望添加或更改它们所请求的URL。

我还有其他选择吗?

更新:我应该注意,我已经在RackSpace支持下验证了此行为,他们说他们对此无能为力。

如果请求的Flash应用程序正在执行重定向,那么我将尝试对第一个请求进行重定向并重写第二个请求,例如

GET .../29.jpg

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

然后,您的r.php会在第二个请求中传递文件。

如果不是(总是如此),我将显式发送标头,并提供Varnish接受并相应执行的静态文件,例如

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");

并且:我将放置exit(); 在您的第一个header()语句之后输入命令,以确保脚本的其余部分没有执行。 header()仅发送标题。

我发现使用ob_start()也更加可靠,因为PHP文件中的空格可能会在添加标头时导致令人讨厌的错误。

我也有同样的情况,我已经联系了Rackspace,希望得到更好的答案。

我有一个! 他们整理了一个常见问题解答,概述了六种绕过/修改缓存的方法:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM