我正在使用传统的 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 脚本时, session 不存在。
如果我将 URL 中的扩展名更改为 .PHP 或者我什至添加了一个查询参数,Varnish 将被绕过并且 PHP 脚本可以获得 session 。没问题吧?我只会在我的请求中添加一个无意义的查询参数!
问题在于:我通过该系统提供的媒体文件是通过编译后的 SWF 文件请求的,我对这些文件的控制权为零。它们是由第三方软件生成的,我没有希望添加或更改它们请求的 URL。
我还有其他选择吗?
更新:我应该指出,我已经通过 RackSpace 支持验证了此行为,他们表示对此无能为力。
最佳答案
如果请求的 Flash 应用遵循重定向,我会尝试在第一个请求上使用重定向来回答并重写第二个请求,例如
GET .../29.jpg
到
header("Status: 302 Moved temporarily");
header("Location: .../r.php?i=29.jpg&random=872938729348");
然后您的 r.php 在第二次请求时传送文件。
如果不是(顺便说一句。总是),我会明确地发送 header 以及交付 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() 只发送 header 。
我发现使用 ob_start() 也更可靠,因为 PHP 文件中的空格可能会在添加 header 时导致恼人的错误。
关于php - 如果 URL 具有某些文件扩展名,RackSpace Cloud 会删除 $_SESSION,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2248702/
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
从给定URL下载文件并立即将其上传到AmazonS3的更直接的方法是什么(+将有关文件的一些信息保存到数据库中,例如名称、大小等)?现在,我既不使用Paperclip,也不使用Carrierwave。谢谢 最佳答案 简单明了:require'open-uri'require's3'amazon=S3::Service.new(access_key_id:'KEY',secret_access_key:'KEY')bucket=amazon.buckets.find('image_storage')url='http://www.ex
我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr