0

我无法让 Webrick 使用 servlet HTTPServlet::CGIHandler——我收到一个 EACCES 错误:

[2012-12-06 01:38:02] ERROR CGIHandler: /tmp/cgi-bin:
/Users/7stud/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/httpservlet/cgi_runner.rb:46:in `exec': Permission denied - /tmp/cgi-bin (Errno::EACCES)
    from /Users/7stud/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/httpservlet/cgi_runner.rb:46:in `<main>'
[2012-12-06 01:38:02] ERROR CGIHandler: /tmp/cgi-bin exit with 1
[2012-12-06 01:38:02] ERROR Premature end of script headers: /tmp/cgi-bin
localhost - - [06/Dec/2012:01:38:02 MST] "GET /cgi/my_prog.cgi HTTP/1.1" 500 326
- -> /cgi/my_prog.cgi

这是我设置的权限:

~/ruby_programs$ cd /
/$ ls -al tmp
lrwxr-xr-x@ 1 root  wheel  11 Jul  3  2011 tmp -> private/tmp

/$ cd tmp
/tmp$ ls -al
total 0
drwxrwxrwt  8 root   wheel  272 Dec  6 01:08 .
drwxr-xr-x@ 6 root   wheel  204 Mar 27  2010 ..
drwxr-xr-x  3 7stud  wheel  102 Dec  6 01:25 cgi-bin

/tmp$ cd cgi-bin/
/tmp/cgi-bin$ ls -al my_prog.cgi 
-rwxr-xr-x  1 7stud  wheel  123 Dec  6 01:09 my_prog.cgi

我的服务器程序(1.rb):

#!/usr/bin/env ruby
require 'webrick'
include WEBrick

port = 12_000
dir = Dir::pwd 

server = HTTPServer.new(
  :Port           => port,
  :DocumentRoot   => dir + "/html"
)

server.mount("/cgi", HTTPServlet::CGIHandler, "/tmp/cgi-bin")
puts "Listening on port: #{port}"

Signal.trap('SIGINT') { server.shutdown }
server.start

运行我的服务器程序:

~/ruby_programs$ ruby 1.rb 
[2012-12-06 01:37:58] INFO  WEBrick 1.3.1
[2012-12-06 01:37:58] INFO  ruby 1.9.3 (2012-04-20) [x86_64-darwin10.8.0]
Listening on port: 12000
[2012-12-06 01:37:58] INFO  WEBrick::HTTPServer#start: pid=4260 port=12000

我在浏览器中输入了这个地址:

http://localhost:12000/cgi/my_prog.cgi

这显示在我的浏览器中:

内部服务器错误

脚本头过早结束:/tmp/cgi-bin WEBrick/1.3.1 (Ruby/1.9.3/2012-04-20) at localhost:12000

这是我的 cgi 脚本(/tmp/cgi-bin/my_prog.cgi):

#!/usr/bin/env ruby

require 'cgi'
cgi = CGI.new
puts cgi.header
puts "<html><body>Hello Webrick</body></html>"
4

2 回答 2

1

就我而言,由于文件权限不正确和标题确实不正确,我遇到了类似的问题。CGI-script 的权限应该是这样的:

~/ruby_projects/cgi_webrick/cgi
ls -l
-rwxr-xr-x 1 me me  112 Sep 20 20:29 test.cgi

我的服务器代码看起来非常相似(放在 中~/ruby_projects/cgi_webrick/),但处理程序不同。

#!/usr/bin/env ruby

require 'webrick'

server = WEBrick::HTTPServer.new :Port => 1234 
server.mount "/", WEBrick::HTTPServlet::FileHandler , './'
trap('INT') { server.stop }
server.start

如果您运行 server script ruby my_server_script.cgi,它将提供来自根目录或其他目录的任何脚本。在我的情况下,我可以访问http://localhost:1234/cgi/test.cgi(放置在子文件夹中的脚本cgi)和http://localhost:1234/test.cgi(放置在启动服务器的根目录中)。

我的测试脚本:

#!/usr/bin/ruby

require 'cgi'

cgi = CGI.new
puts cgi.header
puts "<html><body>This is a test</body></html>"
于 2014-09-20T17:50:51.437 回答
1

我可以让 WEBrick 在根目录以外的目录中执行 cgi 文件的唯一方法是使用 HTTPServlet::FileHandler servlet:

port = 12_500
...

cgi_dir = File.expand_path("~/ruby_programs/cgi-bin")
server.mount("/cgi", HTTPServlet::FileHandler, cgi_dir)

然后用于执行位于 cgi_dir 中的 .cgi 文件的 url 是:

http://localhost:12500/cgi/my_prog.cgi

显然,当你写:

server = HTTPServer.new(
  :Port           => port,
  :DocumentRoot   => "./html"  #Regular files served/.cgi files executed out of this dir
)

Webrick 自动“挂载”一个 HTTPServlet::FileHandler 来处理对 :DocumentRoot 目录的请求,例如

http://localhost:12500/my_html.htm

它将提供来自 ./html 目录的文件(即一个名为 html 的目录,位于运行程序的目录下方)。HTTPServlet::FileHandler 也将执行该目录中的文件,如果它们具有 .cgi 扩展名。

如果您明确使用 mount() 将 HTTPServlet::FileHandler 添加到另一个目录,例如

cgi_dir = File.expand_path("~/ruby_programs/cgi-bin")
server.mount("/cgi", HTTPServlet::FileHandler, cgi_dir)

然后 WEBrick 还将提供该目录中的文件并执行该目录中具有 .cgi 扩展名的文件。

我还没有找到一种方法来将 WEBrick 配置为仅提供 :DocumentRoot 目录中的文件并且仅在另一个目录中执行 .cgi 文件。

请参阅此处的“Gnome WEBrick 指南”:

http://microjet.ath.cx/webrickguide/html/

于 2012-12-08T20:38:14.560 回答