Webrick或Thin运行(非ruby)静态网站

时间:2013-05-07 08:53:01

标签: ruby webserver thin webrick asp.net-development-serv

由于ASP.NET开发服务器(VS2012)不允许我们访问LAN上的URL(!!)并且我没有权限配置IIS,因此我尝试使用WEBrick来启动静态网站,获得LAN访问权限。我正在Windows上运行带有vagrant的Ubuntu。

在我的静态网站的根目录中,我创建了一个文件app.rb,其中包含以下内容:

#app.rb

require 'rubygems'
require 'rack'

class App
  def call(env)
    return [200, {"Content-Type" => "text/html"}, "index.html"]
  end
end

Rack::Handler::WEBrick.run(App.new, :Port => 8080)

当我运行服务器时; ruby app.rb,并浏览到http://localhost:8080,它给了我这个错误:

ERROR NoMethodError: undefined method `each' for "index.html":String
    /usr/local/rvm/gems/ruby-1.9.3-p392/gems/rack-1.4.5/lib/rack/handler/webrick.rb:71:in `service'
    /usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/1.9.1/webrick/httpserver.rb:138:in `service'
    /usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/1.9.1/webrick/httpserver.rb:94:in `run'
    /usr/local/rvm/rubies/ruby-1.9.3-p392/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread'

有没有办法使用WEBrick或Thin来运行静态(HTML / JS)网站?

修改

我遵循了Stuart的建议并将代码更改为:

return [200, {"Content-Type" => "text/html"}, ["index.html"]]

现在,当我浏览到URL时,它会将“index.html”呈现为字符串,而不是呈现文件内容。

2 个答案:

答案 0 :(得分:2)

serving a folder over HTTP with WEBrick有一种简单的方法。

至于Rack,它本身并不处理服务文件。您必须通过HTTP读取要提供的文件,并为Rack提供文件的内容,为此您可以尝试这种快速而肮脏的解决方案:

def call(env)
  contents = File.open("index.html") { |f| f.read }
  return [200, {"Content-Type" => "text/html"}, [contents]]
end

答案 1 :(得分:1)

您的响应正文必须包含在数组中:

    return [200, {"Content-Type" => "text/html"}, ["Hello, World!"]]

请注意[周围的]"Hello, World!"。有关为什么需要Array包装器的说明,请参阅:

  

Why is rack response body an array not a string?

特别是Python WSGI specification的这一部分:

  

对于大型文件,或者对于HTTP流的专门用途(例如多部分“服务器推送”),应用程序可能需要以较小的块提供输出(例如,以避免将大文件加载到存储器中)。有时也会出现这样的情况,即响应的一部分可能很耗时,但是提前发送响应的部分会很有用。

     

在这些情况下,应用程序通常会返回迭代器(通常是生成器迭代器),它以逐块方式生成输出。这些块可能会被破坏以与多个部分边界(用于“服务器推送”)一致,或者在耗时的任务之前(例如读取磁盘文件的另一个块)。

该规范引用了Python,但Ruby Rack应用程序中的模拟将HTTP响应主体包装在一个数组(或响应each方法的任何Enumerable)中。

编辑:要解决原始问题的编辑问题,关于如何专门提供index.html文件,您可以通过读取文件并在Rack响应中输出其内容来实现:< / p>

    return [200, {"Content-Type" => "text/html"}, [File.read("index.html")]]

编辑2 :虽然上述内容仅适用于显示index.html,但如果要提供整个静态资源目录(JS,CSS等),可以尝试使用Rack::Static中间件。{{3}}有关详细信息,请参阅其文档,但我认为您尝试做的事情可以通过以下方式完成:

require 'rack/static'
use Rack::Static, :urls => {"/" => 'index.html'}