Writing a Simple Web Server in Ruby

I want to create an extremely simple web server for development in Ruby (no, I do not want to use ready-made 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 by providing another script that will receive a request for its standard input and return the full response to its standard output.

So far, so good, but it turned out to be very fragile as it aborts the second request with an 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 would be sufficient for usability?

Versions: Ubuntu 9.10 (2.6.31-20-generic), Ruby 1.8.7 (2009-06-12 patchlevel 174) [i486-linux]

+5
source share
3 answers

script, script (Debian Squeeze, Ruby 1.8.7 patchlevel 249):

script bar.rb:

#!/usr/bin/ruby1.8

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

script, script:

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

wget:

$ wget localhost:8080/index

script :

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.

+4
+3

With Ruby Webrick Lib, you have a simple library for building a web server.

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

+1
source

All Articles