标签: x-sendfile

使用PHP提供文件的最快方法

我正在尝试组合一个接收文件路径的函数,识别它是什么,设置适当的头,并像Apache一样提供服务.

我这样做的原因是因为我需要在提供文件之前使用PHP来处理有关请求的一些信息.

速度至关重要

virtual()不是一个选项

必须在共享托管环境中工作,用户无法控制Web服务器(Apache/nginx等)

这是我到目前为止所得到的:

File::output($path);

<?php
class File {
static function output($path) {
    // Check if the file exists
    if(!File::exists($path)) {
        header('HTTP/1.0 404 Not Found');
        exit();
    }

    // Set the content-type header
    header('Content-Type: '.File::mimeType($path));

    // Handle caching
    $fileModificationTime = gmdate('D, d M Y H:i:s', File::modificationTime($path)).' GMT';
    $headers = getallheaders();
    if(isset($headers['If-Modified-Since']) && $headers['If-Modified-Since'] == $fileModificationTime) {
        header('HTTP/1.1 304 Not Modified');
        exit();
    }
    header('Last-Modified: '.$fileModificationTime);

    // Read the file
    readfile($path);

    exit();
}

static function mimeType($path) {
    preg_match("|\.([a-z0-9]{2,4})$|i", $path, $fileSuffix);

    switch(strtolower($fileSuffix[1])) …
Run Code Online (Sandbox Code Playgroud)

php performance file-io x-sendfile

93
推荐指数
4
解决办法
5万
查看次数

Django - 了解X-Sendfile

我一直在研究使用Django进行访问控制的文件下载.我的目标是完全阻止对文件的访问,除非由特定用户访问.我已经读过,当使用Django时,X-Sendfile是实现这一目标的首选方法之一(基于其他SO问题等).我对使用Xang Sendfile和Django的基本理解是:

  1. 用户请求URI以获取受保护的文件
  2. Django应用程序根据URL决定返回哪个文件,并检查用户权限等.
  3. Django应用程序返回HTTP响应,并将"X-Sendfile"标头设置为服务器的文件路径
  4. Web服务器找到该文件并将其返回给请求者(我假设Web服务器也沿途除去了'X-Sendfile'标题)

与直接从Django中删除文件相比,X-Sendfile似乎是一种更有效的方法来实现受保护的下载(因为我可以依赖Nginx来提供文件,而不是Django),但是给我留下两个问题:

  1. 我对X-Sendfile的解释至少是抽象的正确吗?
  2. 它是否真的安全,假设我没有提供正常的前端HTTP访问(例如http://www.example.com/downloads/secret-file.jpg)到文件存储的目录(即,不要不要把它保存在我的public_html目录中)?或者,精通技术的用户是否可以检查标题等,并以反向工程方式访问文件(然后分发)?
  3. 它在性能上是否真的有很大差异?我是否会通过直接从Django提供8b块150Mb文件的下载来使我的应用程序服务器陷入困境,或者这种类型是无问题的?我问的原因是因为如果两个版本接近相等,Django版本会更好,因为我有能力用Python做事,比如记录完成的下载次数,下载的带宽等.

提前致谢.

python django x-sendfile download protected-resource

30
推荐指数
1
解决办法
8765
查看次数

在Ruby on Rails中,在send_file方法之后从服务器中删除该文件

我使用以下代码在Rails中发送文件.

if File.exist?(file_path)
  send_file(file_path, type: 'text/excel') 
  File.delete(file_path)
end

在这里,我试图发送文件,并在成功发送后从服务器中删除该文件.但我面临的问题是,删除操作是在发送执行时执行的,因为我在浏览器中看不到任何内容.

所以在Rails中有任何方法,一旦send_file操作完成,从服务器删除文件.

任何有关这方面的帮助将受到高度赞赏.

谢谢,
Chetan

ruby ruby-on-rails file x-sendfile

30
推荐指数
2
解决办法
1万
查看次数

在Apache/PHP中使用X-Sendfile

我似乎找不到很多关于X-Sendfile或PHP示例代码的文档(有一些rails代码).

以前有人用过它,会介意快速提供代码片段和简要说明吗?

php apache x-sendfile

20
推荐指数
1
解决办法
3万
查看次数

Rails + X-Sendfile为Ipad提供大型视频

我有一个应用程序服务大(几百MB)的视频文件,它在桌面浏览器上完美运行,在Apache上使用Rails + X-Sendfile.一个重要的要求是这些视频必须是私有的,并且只对已登录的用户可见,因此这就是我使用Rails为其提供服务的原因.

一切都与其他设备完美配合.我以这种方式提供视频:

response.headers["X-Sendfile"]=  filename
send_file filename, :disposition => :inline, :stream => true, :x_sendfile => true
Run Code Online (Sandbox Code Playgroud)

但是Ipad的请求需要字节范围头.解决方案(不能完美运行)是这样的:

size = File.size(filename)
bytes = Rack::Utils.byte_ranges(request.headers, size)[0]
offset = bytes.begin
length = bytes.end  - bytes.begin

response.header["Accept-Ranges"]=  "bytes"
response.header["Content-Range"] = "bytes #{bytes.begin}-#{bytes.end}/#{size}"

send_data IO.binread(filename,length, offset), :type => "video/mp4", :stream => true, :disposition => 'inline', :file_name => filename 
Run Code Online (Sandbox Code Playgroud)

有了这个解决方案,我遇到了大于50mb视频的问题,而且更重要的是,我给了rails一个不应该有的责任.通过x-sendfile模块处理流的繁重负载应该是apache.但我不知道如何.该send_data方法没有x-sendfile参数,涉及send_file方法的解决方案不起作用.

我发现这两个问题与我的相似,但它们不起作用:rails media file stream通过send_data或send_file方法接受字节范围请求,通过rails向Ipad提供mp4文件的正确方法是什么?

关于发生了什么的任何线索?我几周以来一直在努力,我需要让它发挥作用.欢迎其他可行的解决方案.

ruby-on-rails x-sendfile video-streaming ipad ruby-on-rails-4

15
推荐指数
1
解决办法
981
查看次数

通过Rails 2.3通过Nginx提供大型文件使用x-sendfile

假设我有一个由nginx提供的Rails 2.3.2应用程序,并由mongrel提供服务,其中我需要通过Rails提供大型静态文件(以控制对它的访问).我希望Rails应用程序将文件传输委托给nginx,以避免阻止mongrel实例.

可用的信息似乎是矛盾和不完整的.这篇文章展示了如何用Apache做到这一点,并暗示它也可以用ngninx完成 - 但没有例子.这篇文章这篇文章展示了如何使用一个显然Rails 2.3使得不必要的插件来实现它.这篇文章表明可能毕竟不支持带有nginx的x-sendfile.

对于Rails现在可以自行完成的事情,我宁愿不要使用插件.

有没有人使用没有插件和Rails 2.3/nginx/mongrel的x-sendfile式行为?如果没有,那么使用插件(和/或monkeypatch)和Rails 2.3/nginx/mongrel的最佳文档是什么?

mongrel ruby-on-rails x-sendfile nginx

11
推荐指数
1
解决办法
6764
查看次数

尝试通过X-Sendfile传送mp4时,iOS 10不会发送会话ID

我有一个PHP文件,唯一的工作是检查用户是否登录+如果设置了会话变量,然后通过nginx X-Sendfile传递文件.它可以在任何桌面浏览器上完美运行,以前可以在任何移动浏览器上运行 - 但在任何只有mp4的ios 10浏览器上都会失败.对我来说没什么意义的是,如果我评论该die()行,它会按预期工作,但PHP代码应该永远不会进入该行.

<?php
require_once('authConfig.php');
$userInfo = $auth0->getUser();
session_start();
include('cururl.php');
$murl = curPageURL();
parse_str($murl, $result);
$filename=$result['file'];
$folder=$result['folder'];
if (!$userInfo || !isset($_SESSION[$folder])) {
        header('Location:login.php');
        die();
}
$file="/var/www/uploads/" . $folder . "/" . $filename;
$aliasedFile = '/protected/' . $folder .'/' . $filename; 
$realFile = $file; 
header('Cache-Control: public, must-revalidate');
header('Pragma: no-cache');
header('Content-Type: ' . mime_content_type($file));
header('Content-Length: ' .(string)(filesize($realFile)) );
header('X-Accel-Redirect: ' . $aliasedFile);
exit;
?>
Run Code Online (Sandbox Code Playgroud)

我可以$_SESSION[$folder]通过将代码更改为:

if(isset($_SESSION[$folder])){
   echo "OK";
   die();
} 
Run Code Online (Sandbox Code Playgroud)

更新:这是来自iPhone的访问日志.它应该有权访问该文件.

10.0.0.1 forwarded for ..., 10.0.0.1 …
Run Code Online (Sandbox Code Playgroud)

php x-sendfile nginx ios10

10
推荐指数
1
解决办法
517
查看次数

Nginx错误日志中的消息"X-Accel-Mapping标头丢失"

我在Ubuntu 8.04上使用Nginx 1.0.0和Passenger 3.0.7运行Rails 3站点.

在我的Nginx error.log中,我开始看到X-Accel-Mapping header missing相当多的消息.谷歌搜索导致我的文档Rack::Sendfile,并在Nginx的文档.

现在,我的应用程序可以通过多个域访问,我send_file在我的应用程序中使用它来提供特定于他们请求的域的一些文件,例如,如果你来domain1.com/favicon.ico我查找favicon in public/websites/domain1/favicon.ico.这工作正常,我认为我不需要/想要让Nginx参与并创建一些私有区域,我存储这些文件,正如Rack::Sendfile文档中的示例所示.

我怎样才能摆脱错误信息?

rack x-sendfile nginx sendfile

9
推荐指数
1
解决办法
8975
查看次数

rails media file stream通过send_data或send_file方法接受字节范围请求

我有以下问题.声音在公共文件夹中隐藏,因为只有某些用户应该有权访问声音文件.所以我做了一个特定的方法,它就像一个声音网址,但首先计算,是否允许当前用户访问此文件.

该文件由send_data方法发送.问题是,如果它工作得很好我工作得很慢...我用来播放声音的jplayer插件的开发者告诉我,我应该能够接受字节范围请求以使其正常工作...

如何通过发送带有send_data或send_file的文件在rails控制器中执行此操作?

谢谢你,马库斯

ruby-on-rails x-sendfile http-headers sendfile

9
推荐指数
1
解决办法
6766
查看次数

使用URL参数和XSendFile在浏览器中缓存图像

我试图建立一个站点,以便用户只能访问自己的图像和音频文件。为此,我在URL中使用了变量,例如:

 <img src="/public/get_file.php?type=image&file=pic001.png" />
Run Code Online (Sandbox Code Playgroud)

在前端,我正在使用React JS(不确定这对这个问题是否重要)。但是在后端,PHP脚本将验证用户已登录(仅通过检查一个简单的SESSION变量),并在用户的数据目录中查找该文件(基于其SESSION变量中的用户ID)。如果存在,它将使用XSendFile将其返回给用户。

我遇到的问题是,每次用户尝试访问文件时,在加载文件之前都会有一些延迟。这告诉我它们可能没有被浏览器缓存。

为什么文件没有被缓存?它与URL参数有关还是与PHP / XSendFile的使用有关?

如何允许我的文件(图像/音频)被缓存?

更新资料

根据要求,这里是我的get_file.php:

<?php

        session_start();

        if (empty($_SESSION['auth']['id'])){
                exit;
        }

        require_once("../../api_modules/settings.php");

        $developer_id = $_SESSION['auth']['id'];

        $type = preg_replace('/[^-a-zA-Z0-9_]/', '', $_GET['type']);
        $file = preg_replace('/[^-a-zA-Z0-9_\.]/', '', $_GET['file']);

        $file = preg_replace('/[\.]{2,}/', '', $file);

        $project_id = preg_replace('/[^0-9]/', '', $_GET['project_id']);
        $developer_id = preg_replace('/[^0-9]/', '', $developer_id);

        if ($type == "image")
                $file = FILEPATH ."files/$developer_id/$project_id/images/thumbs/88x88/$file";
        else if ($type == "full_image")
                $file = FILEPATH ."files/$developer_id/$project_id/images/originals/$file";
        else if ($type == "audio"){
                $file = FILEPATH ."files/$developer_id/$project_id/audio/$file";
        }
        else {
                exit;
        }


        header("X-Sendfile: …
Run Code Online (Sandbox Code Playgroud)

php apache x-sendfile browser-cache reactjs

9
推荐指数
1
解决办法
185
查看次数