sample/dualstack-httpd.rb


DEFINITIONS

This source file includes following functions.


   1  # simple httpd
   2  
   3  # The code demonstrates how a multi-protocol daemon should be written.
   4  
   5  require "socket"
   6  require "thread"
   7  
   8  port = 8888
   9  res = Socket.getaddrinfo(nil, port, nil, Socket::SOCK_STREAM, nil, Socket::AI_PASSIVE)
  10  sockpool = []
  11  names = []
  12  threads = []
  13  
  14  res.each do |i|
  15    s = TCPserver.new(i[3], i[1])
  16    n = Socket.getnameinfo(s.getsockname, Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV).join(" port ")
  17    sockpool.push s
  18    names.push n
  19  end
  20  
  21  (0 .. sockpool.size - 1).each do |i|
  22    mysock = sockpool[i]
  23    myname = names[i]
  24    STDERR.print "socket #{mysock} started, address #{myname}\n"
  25    threads[i] = Thread.start do          # Thread.start cannot be used here!
  26      ls = mysock # copy to dynamic variable
  27      t = Thread.current
  28      STDERR.print "socket #{myname} listener started, pid #{$$} thread #{t}\n"
  29      while TRUE
  30        as = ls.accept
  31        Thread.start do
  32          STDERR.print "socket #{myname} accepted, thread ", Thread.current, "\n"
  33          s = as  # copy to dynamic variable
  34          str = ''
  35          while line = s.gets
  36            break if line == "\r\n" or line == "\n"
  37            str << line
  38          end
  39          STDERR.print "socket #{myname} got string\n"
  40          s.write("HTTP/1.0 200 OK\n")
  41          s.write("Content-type: text/plain\n\n")
  42          s.write("this is test: my name is #{myname}, you sent:\n")
  43          s.write("---start\n")
  44          s.write(str)
  45          s.write("---end\n")
  46          s.close
  47          STDERR.print "socket #{myname} processed, thread ", Thread.current, " terminating\n"
  48        end
  49      end
  50    end
  51  end
  52  
  53  for t in threads
  54    t.join
  55  end