Я хочу создать чрезвычайно простой веб-сервер в целях разработки в Ruby (не, не хотят использовать готовые решения).
Вот код:
#!/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
Какая-либо идея, как улучшить вышеупомянутый код, чтобы быть достаточным для легкого использования?
Версии: (2.6.31-20-универсальная) Ubuntu 9.10, Ruby 1.8.7 (12.06.2009 уровней установки патча 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
Затем я запустил ваш скрипт, передав ему путь к фиктивному скрипту:
$ /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.
Буклет Ruby Web Servers описывает большинство стратегий реализации веб-серверов.
С Ruby Webrick Lib у вас есть простая библиотека для создания веб-сервера.