我想在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
Run Code Online (Sandbox Code Playgroud)
我们的想法是从命令行运行此脚本,提供另一个脚本,该脚本将在其标准输入上获取请求,并在其标准输出上返回完整响应.
到目前为止一切都那么好,但事实证明它非常脆弱,因为它在第二个请求中突破了错误:
/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
Run Code Online (Sandbox Code Playgroud)
知道如何改进上面的代码足以方便使用吗?
版本:Ubuntu 9.10(2.6.31-20-generic),Ruby 1.8.7(2009-06-12 patchlevel 174)[i486-linux]
问题似乎出现在子脚本中,因为问题中的父脚本在我的框中运行(Debian Squeeze,Ruby 1.8.7 patchlevel 249):
我创建了虚拟子脚本bar.rb:
#!/usr/bin/ruby1.8
s = $stdin.read
$stderr.puts s
print s
Run Code Online (Sandbox Code Playgroud)
然后我运行你的脚本,传递给虚拟脚本的路径:
$ /tmp/foo.rb /tmp/bar.rb
Run Code Online (Sandbox Code Playgroud)
我用wget命中了它:
$ wget localhost:8080/index
Run Code Online (Sandbox Code Playgroud)
并看到了虚拟脚本的输出:
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
Run Code Online (Sandbox Code Playgroud)
我也看到wget收到它发送的内容:
$ cat index
GET /index HTTP/1.0
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Host: localhost:8080
Connection: Keep-Alive
Run Code Online (Sandbox Code Playgroud)
无论我用wget击中它多少次,它的工作方式都是一样的.
| 归档时间: |
|
| 查看次数: |
4931 次 |
| 最近记录: |