Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Rev 2 of my cowsay serv.
require 'socket'
module CowSay
class Server
def initialize(port)
# Create the underlying socket server
@server = TCPServer.new(port)
puts "Listening on port #{@server.local_address.ip_port}"
end
def start
# TODO Currently this server can only accept one connection at at
# time. Do I want to change that so I can process multiple requests
# at once?
Socket.accept_loop(@server) do |connection|
handle(connection)
connection.close
end
end
# Find a value in a line for a given key
def find_value_for_key(key, document)
retval = nil
re = /^#{key} (.*)/
md = re.match(document)
if md != nil
retval = md[1]
end
retval
end
# Parse the document that is sent by the client and convert it into a
# hash table.
def parse(document)
commands = Hash.new
message_value = find_value_for_key("MESSAGE", document)
if message_value == nil then
$stderr.puts "ERROR: Empty message"
end
commands[:message] = message_value
body_value = find_value_for_key("BODY", document)
if body_value == nil then
commands[:body] = "default"
else
commands[:body] = body_value
end
commands
end
def handle(connection)
# TODO Read is going to block until EOF. I need to use something
# different that will work without an EOF.
request = connection.read
# The current API will accept a message only from netcat. This
# message is what the cow will say. Soon I will add support for
# more features, like choosing your cow.
# Write back the result of the hash operation
connection.write process(parse(request))
end
def process(commands)
# TODO Currently I can't capture STDERR output. This is
# definitely a problem when someone passes a bogus
# body file name.
`cowsay -f #{commands[:body]} "#{commands[:message]}"`
end
end
end
server = CowSay::Server.new(4481)
server.start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment