[英]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.