Ruby CGI重定向响应,无需等待脚本结束

时间:2011-05-06 13:03:57

标签: ruby http redirect cgi

我正在开发一个ruby CGI视频处理工具,并希望在点击start-ffmpeg-for-an-hour-long-encoding-spree按钮后将用户重定向到另一个位置。

以下是代码:

@cgi.out("status" => "302", "location" => @job.report_url) {''}
@cgi.out{''}
@job.start

这样做适用于Safari 5.0.5。但Firefox在重定向之前等待脚本完成他的工作。而且,如果你的脚本需要比Apache超时更长的时间,那么它可能永远不会发生。

我希望得到一个cin.close()方法的kinf。哪个存在!但是CGI :: Session方法与我无关。

这是另一个类似的问题......但不是重复!因为我需要在重定向后使用stdin,stdout和stderr Returning a response with Ruby CGI before script is finished?

那么,如何使用相同的脚本在 执行其他任务之前发送完整的CGI响应

4 个答案:

答案 0 :(得分:1)

解决此类问题的常用方法是将应用程序分成两个进程。

  1. cgi部分
  2. 处理部分
  3. 处理部分通常是等待来自众多cgi部分的消息的应用程序的单个实例。 cgi部分只是向处理部分提交请求。可以随意进行通信,但通常使用作业/消息队列完成。

    这样,只要将作业提交到队列,您就可以重定向用户,处理部分最终将转发您的视频转码。

    另一个优点是,一堆并发请求不会使您的计算机过载数十次并发转码操作。您还可以相对轻松地将处理部件移动到一台或多台机器上(取决于您选择的通信形式)/

    快速web search将向您展示数十个示例。

答案 1 :(得分:1)

某些浏览器(如Firefox)在处理数据之前填充缓冲区。

在家庭测试中,我通过发送4096个空格来完成这个技巧:

@cgi.out("status" => "302", "location" => @job.report_url) { ' ' * 4096 }
@job.start

更新:以下是我的完整测试代码:

#!/usr/bin/ruby

require 'cgi'

# change the line below to test; e.g.: buf = ''
buf = ' ' * 4096

cgi = CGI.new
cgi.out('status' => '302', 'location' => 'http://www.example.com') { buf }

sleep 10

puts 'end'

显然,'end'永远不会出现,因为浏览器之前已被重定向。

buf为空时,Firefox会在重定向之前等待10秒。当它“满”(即4K空格)时,浏览器会立即重定向。在Ubuntu 10.04中使用Firefox 4.0,在Windows 7中使用Firefox 4.0.1进行测试。

答案 2 :(得分:1)

尝试将Content-Length标头设置为0,而不是发送空缓冲区。 对于off请求处理,Kernel#fork应该有帮助。

经过一些测试。这是需要做的。 Content-Length由cgi.out正确设置。您只需传递一个空字符串将其设置为0。

另外,正如我在评论中所述,关闭stdout有效地关闭了连接服务器端。 我用lighttpd + ree,firefox和chrome测试了这段代码。

require 'cgi'    
cgi = CGI.new
cgi.out('status' => '302', 'location' => 'http://www.google.com') { "" }
$stdout.close

# here we do a very very long task
sleep 30
exit 0

答案 3 :(得分:1)

好吧,终于明白了。

但它看起来更像是黑客而不是真正的解决方案:

@cgi.out("status" => "303", "Connection" => "close", "Content-Length" => 1, "Location" => @job.report_url) {' '}
@job.start

有两个关键因素可以使它发挥作用,两者都需要:

  1. Content-Lenght设置为大于0的值.1适用于一个内容空间。
  2. Connection设为close。这很尴尬,因为理论上这在HTTP 1.1 Keep Alive连接中可能完全正常。但这似乎触发了Firefox 4中的页面呈现。
  3. 在作业提交的POST请求(HTTP 303)之后,我已切换到更正确的303 See Other响应。但这没有任何效果,它对302响应也很有效。