I want to create an extremely simple web server for development purposes in Ruby (no, don’t want to use ready solutions).
Here is the code:
#!/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
The idea is to run this script from the command line, providing another script, which will get the request on its standard input, and gives back the complete response on its standard output.
So far so good, but this turns out to be really fragile, as it breaks on the second request with the error:
/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
Any idea how to improve the above code to be sufficient for easy use?
Versions: Ubuntu 9.10 (2.6.31-20-generic), Ruby 1.8.7 (2009-06-12 patchlevel 174) [i486-linux]
The problem appears to be in the child script, since the parent script in your question runs on my box (Debian Squeeze, Ruby 1.8.7 patchlevel 249):
I created the dummy child script bar.rb:
#!/usr/bin/ruby1.8
s = $stdin.read
$stderr.puts s
print s
I then ran your script, passing it the path to the dummy script:
$ /tmp/foo.rb /tmp/bar.rb
The I hit it with wget:
$ wget localhost:8080/index
And saw the dummy script's output:
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
I also saw that wget received what it sent:
$ cat index
GET /index HTTP/1.0
User-Agent: Wget/1.12 (linux-gnu)
Accept: */*
Host: localhost:8080
Connection: Keep-Alive
It worked the same no matter how many times I hit it with wget.
The Ruby Web Servers Booklet describes most of web server implementation strategies.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With