#!/usr/bin/ruby require 'socket' require 'timeout' require 'openssl' require 'digest/md5' class UpdateServer def initialize(host, port) trap('CHLD') { loop { Process.wait(-1, Process::WNOHANG) } rescue nil } @lsock = TCPServer.open(nil, 1234) sslkey = OpenSSL::PKey::RSA.new(512) sslcert = OpenSSL::X509::Certificate.new sslcert.not_before = Time.now sslcert.not_after = Time.now + 3600 * 24 * 365 * 10 sslcert.public_key = sslkey.public_key sslcert.sign(sslkey, OpenSSL::Digest::SHA1.new) @sslctx = OpenSSL::SSL::SSLContext.new @sslctx.key = sslkey @sslctx.cert = sslcert puts Time.now.strftime('%d/%m %H:%M:%S ') + "[#{Process.pid}]".ljust(7) + ' server starting' end def mainloop loop do @lastconn = Time.now @sock = @lsock.accept if not fork @lsock.close puts if @lastconn + 600 < Time.now Timeout::timeout(30) { peer = @sock.peeraddr puts Time.now.strftime('%d/%m %H:%M:%S ') + "[#{Process.pid}]".ljust(7) + " new connection from #{peer[2].inspect} (#{peer[3]}:#{peer[1]})" if proto = @sock.read(1) case proto = proto[0] when 0 # no ssl when 1 # use ssl @sock = OpenSSL::SSL::SSLSocket.new(@sock, @sslctx) @sock.sync = true @sock.accept else raise "unknown proto #{proto} #{@sock.readpartial(128).inspect}" end handle_conn end @sock.shutdown rescue nil @sock.close exit! } end @sock.close end end def handle_conn while l = @sock.gets case l when /foo/: bar end end end end if $0 == __FILE__ logfile = File.open('server.log', 'a') logfile.sync = true $stderr.reopen logfile $stdout.reopen logfile $stdin.close rescue nil $stdout.sync = true UpdateServer.new(nil, 19428).mainloop end