【问题标题】:Writing a simple webserver in Ruby用 Ruby 编写一个简单的网络服务器
【发布时间】:2010-03-10 13:10:53
【问题描述】:

我想在 Ruby 中为开发目的创建一个极其简单的 Web 服务器(不,不想使用现成的解决方案)。

代码如下:

#!/usr/bin/ruby

require 'socket'

server = TCPServer.new('127.0.0.1', 8080)

while connection = server.accept
  headers = []
  length  = 0

  while line = connection.gets
    headers << line

    if line =~ /^Content-Length:\s+(\d+)/i
      length = $1.to_i
    end

    break if line == "\r\n"
  end

  body = connection.readpartial(length)

  IO.popen(ARGV[0], 'r+') do |script|
    script.print(headers.join + body)
    script.close_write
    connection.print script.read
  end

  connection.close
end

想法是从命令行运行此脚本,提供另一个脚本,该脚本将在其标准输入上获取请求,并在其标准输出上返回完整的响应。

到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求中中断并出现错误:

/usr/bin/serve:24:in `write': Broken pipe (Errno::EPIPE)
    from /usr/bin/serve:24:in `print'
    from /usr/bin/serve:24
    from /usr/bin/serve:23:in `popen'
    from /usr/bin/serve:23

知道如何改进上述代码以使其易于使用吗?

版本:Ubuntu 9.10(2.6.31-20-generic)、Ruby 1.8.7(2009-06-12 补丁级别 174)[i486-linux]

【问题讨论】:

  • Joó,由于您和我得到的结果如此不同,也许您应该在问题中添加您的 Ruby 和操作系统版本。

标签: ruby webserver


【解决方案1】:

问题似乎出在子脚本中,因为您问题中的父脚本在我的盒子上运行(Debian Squeeze,Ruby 1.8.7 patchlevel 249):

我创建了虚拟子脚本 bar.rb:

#!/usr/bin/ruby1.8

s = $stdin.read
$stderr.puts s
print s

然后我运行您的脚本,将路径传递给虚拟脚本:

$ /tmp/foo.rb /tmp/bar.rb

我用 wget 击中了它:

$ wget localhost:8080/index

并看到了虚拟脚本的输出:

GET /index HTTP/1.0^M
User-Agent: Wget/1.12 (linux-gnu)^M
Accept: */*^M
Host: localhost:8080^M
Connection: Keep-Alive^M
^M

我还看到 wget 收到了它发送的内容:

$ cat index
GET /index HTTP/1.0
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Host: localhost:8080
Connection: Keep-Alive

无论我用 wget 打多少次,它的效果都是一样的。

【讨论】:

  • 我尝试了您的子脚本,但它在第一次运行时抛出了错误。也许这里有一些操作系统级别的差异。
  • 好的,我找到了问题所在。它在子脚本中:我只是打印了一个基本的 HTTP 响应,而您先阅读了标准输入。现在的问题是为什么必须这样做。
【解决方案2】:

Ruby Web Servers Booklet 描述了大多数 Web 服务器实施策略。

【讨论】:

    【解决方案3】:

    使用 Ruby Webrick Lib,您可以轻松构建 Web 服务器。

    http://www.ruby-doc.org/stdlib/libdoc/webrick/rdoc/

    【讨论】:

      猜你喜欢
      • 2011-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-24
      • 1970-01-01
      • 1970-01-01
      • 2011-09-14
      • 2015-10-24
      相关资源
      最近更新 更多