我在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文档中的示例所示.
我怎样才能摆脱错误信息?
我正在编写一个处理图像(大数据)的应用程序服务器.我正在尝试将图像数据发送回客户端时最小化副本.我需要发送给客户的处理过的图像位于从jemalloc获得的缓冲区中.我想到将数据发送回客户端的方法是:
1)简单的写呼叫.
// Allocate buffer buf.
// Store image data in this buffer.
write(socket, buf, len);
Run Code Online (Sandbox Code Playgroud)
2)我通过mmap而不是jemalloc获取缓冲区,虽然我认为jemalloc已经使用mmap创建了缓冲区.然后我做一个简单的写电话.
buf = mmap(file, len); // Imagine proper options.
// Store image data in this buffer.
write(socket, buf, len);
Run Code Online (Sandbox Code Playgroud)
3)我像以前一样通过mmap获取缓冲区.然后我使用sendfile发送数据:
buf = mmap(in_fd, len); // Imagine proper options.
// Store image data in this buffer.
int rc;
rc = sendfile(out_fd, file, &offset, count);
// Deal with rc.
Run Code Online (Sandbox Code Playgroud)
似乎(1)和(2)可能会做同样的事情,因为jemalloc可能首先通过mmap分配内存.但我不确定(3).这真的会带来任何好处吗?本文关于Linux零拷贝方法的图4 表明使用sendfile可以防止进一步的拷贝:
没有数据被复制到套接字缓冲区.相反,只有具有关于数据的下落和长度信息的描述符被附加到套接字缓冲区.DMA引擎将数据直接从内核缓冲区传递到协议引擎,从而消除了剩余的最终副本.
如果一切顺利,这似乎是一场胜利.我不知道我的mmaped缓冲区是否算作内核缓冲区.另外我不知道什么时候重新使用这个缓冲区是安全的.由于fd和length是唯一附加到套接字缓冲区的东西,我假设内核实际上异步地将这些数据写入套接字.如果它执行sendfile的返回表示什么?我怎么知道何时重用这个缓冲区?
所以我的问题是:
我尝试使用以下代码将文件发送到客户端:
router.get('/get/myfile', function (req, res, next) {
res.sendFile("/other_file_name.dat");
});
Run Code Online (Sandbox Code Playgroud)
它的工作正常但我需要用户从网址下载此文件时:
http://mynodejssite.com/get/myfile
Run Code Online (Sandbox Code Playgroud)
浏览器中的文件名必须是"other_file_name.dat"而不是"myfile".
我正在使用的代码:
在视图文件中:
<%= link_to "Download", download_image_path(image) %>
Run Code Online (Sandbox Code Playgroud)
在控制器中:
def download
@image = Image.find(params[:id])
send_file "#{RAILS_ROOT}/public" + @image.attachment.url
end
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:
Cannot read file /Users/mohit/projects/my_app/public/system/attachments/4/original/Screen Shot 2011-11-04 at 3.14.03 PM.png?1320582022
Run Code Online (Sandbox Code Playgroud)
PS:双重检查,文件存在.服务器上的相同问题,适用于所有相应控制器中的所有文件(图像,pdf,视频).
sendfile()可用于将数据从"文件"描述符传输到"套接字"描述符,以便从机器A到机器B获取数据.是否可以将接收端的数据从"套接字"描述符获取到文件具有类似的零拷贝语义?我认为sendfile()这里没有帮助,因为sendfile()需要数据源是"页面/缓冲区"缓存.我的理解是否正确?splice()在这种情况下可以帮忙吗?
我想使用expressjs的sendfile从脚本文件的父目录发送文件.我试图做的是这样的:
app.get('/', function(req, res){
res.sendfile('../../index.html');
});
Run Code Online (Sandbox Code Playgroud)
我得到一个禁止的错误,因为很明显,sendfile不信任路径遍历.到目前为止,我一直无法弄清楚如何更改通过sendfile发送的文件的目录.任何提示?
编辑:发帖时我有点累,实际上它很容易.我会把它留在这里以防万一其他人偶然发现这件事.sendfile有一个选项参数,允许你这样做,如下所示:
app.get( '/', function( req, res ){
res.sendfile('index.html', { root: "../../"});
});
Run Code Online (Sandbox Code Playgroud) 我正在使用send_fileSinatra应用程序:
get '/update/dl/:upd' do
filename ="/uploads/#{params[:upd]}"
send_file(filename, :filename => "t.cer", :type => "application/octet-stream")
end
Run Code Online (Sandbox Code Playgroud)
/uploads/它不是公开的文件夹,它在app dir上.当我尝试使用localhost:4567/update/dl/some_fileChrome时,它返回404,就像使用Firefox一样,当看到标题时,它是404.但是如果我尝试使用Safari,它会下载文件.所以我觉得我的代码(和Safari的代码有问题,但让我们把它留给Apple:P).可能有什么不对?谢谢!
我有点被困在这里了。我正在客户端使用 Angular 4 编写一个 Web 应用程序,在服务器端使用 Node/Express/Mongo 编写一个 REST API,并使用 Auth0 API 进行身份验证。
在服务器端,我提供静态文件和所有到 Angular 的路由,如下所示:
const distDir = __dirname + "/dist/";
app.use(express.static(distDir));
app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname + '/dist/index.html'));
});
Run Code Online (Sandbox Code Playgroud)
如果没有为所有 Angular 应用程序提供服务的 app.get 方法,我会收到 404 错误(例如无法 GET /callback)。
问题是 sendFile 发送一个 html 文件,无论调用是什么。在我的应用程序中,第一个调用是针对 js 文件的,如“网络”选项卡 (auth0.min.js) 中所示。所以我得到这个错误:
ERROR SyntaxError: Unexpected token < in JSON at position 0
at JSON.parse (<anonymous>)
at e.CPp0.t.json (vendor.b69a8a4fa217eba4fba0.bundle.js:1)
at e.project (main.0e8acae237e497f792ab.bundle.js:1)
at e._next (vendor.b69a8a4fa217eba4fba0.bundle.js:1)
at e.T14+.e.next (vendor.b69a8a4fa217eba4fba0.bundle.js:1)
at XMLHttpRequest.s (vendor.b69a8a4fa217eba4fba0.bundle.js:1)
at e.invokeTask (polyfills.043084ca495430fc14f3.bundle.js:1) …Run Code Online (Sandbox Code Playgroud) Apache 文档包含以下 EnableSendfile 语句:
使用网络安装的 DocumentRoot(例如,NFS、SMB、CIFS、FUSE),内核可能无法通过自己的缓存为网络文件提供服务。[1]
Apache 2.4 和 Nginx 的默认配置禁用了 sendfile()。
我试图找到一些具体的东西来描述在 Linux 上将 sendfile() 与 NFS 文件系统一起使用时的确切问题。在内核 3.10.0-327.36.3 (CentOS 7) 上运行一个最小的测试程序验证 sendfile() 在源位于 NFS 上时确实有效,并且它确实从页面缓存中读取(第一次运行很慢,随后很快, drop_caches 使其再次变慢,即从源重新读取)。我尝试使用高达 1G 的文件大小,一切似乎都正常。我假设一定有一些情况可以揭示错误行为,但我想确切地知道那是什么。
为了进行比较,有一些关于 VirtualBox 卷在 sendfile()[2] 中存在的问题的文档,但我找不到类似的内容涵盖 Apache,或者如何复制有问题的配置。
我想知道是否有一种方法可以通过跳转服务器使用 SFTP 将文件发送到远程计算机。如下图所示,首先需要 SSH 连接,然后是 SFTP 连接。
我的主要问题出现在 SSH 连接之后,我的工作空间已更改,并且我无法检索成功执行 SFTP 所需的文件。我尝试过以下代码:
ssh jump-server-user@ip-jump-server 'echo "put /source/files /remote/files" | sftp -v remote-machine-user@ip-remote-machine'
Run Code Online (Sandbox Code Playgroud)
但这不起作用。
我尝试执行一个简单的命令,例如pwd使用 SFTP 连接,并且它有效,所以我认为这里的问题是工作区如何变化。
可能有一个更简单的解决方案,但我无法在跳转服务器-远程计算机连接上使用 SSH,并且无法将本地文件存储在跳转服务器中以便稍后将它们发送到远程计算机。