Skip to content

Instantly share code, notes, and snippets.

@strickinato
Created July 31, 2018 18:18
Show Gist options
  • Save strickinato/ac321ceb8030b7677dee84eb303a2282 to your computer and use it in GitHub Desktop.
Save strickinato/ac321ceb8030b7677dee84eb303a2282 to your computer and use it in GitHub Desktop.
A basic http server key/value store
require 'socket'
# Wrapper for a key / value store that acts as our database
class DataStore
def initialize
@store = {}
end
def set(key, value)
@store[key] = value
end
def get(key)
@store[key]
end
def to_s
@store.to_s
end
end
# Encapsulate all the logic for request handling
class ResponseBuilder
# Matches "GET /set?xxx=yyy ...and anything beyond"
SETTER_REGEX = /\AGET \/set\?(\S*)=(\S*).*/
# Matches "GET /get?key=xxx ...and anything beyond"
GETTER_REGEX = /\AGET \/get\?key=(\S*).*/
def initialize(request, datastore)
@request = request
@datastore = datastore
end
def response
case @request
when SETTER_REGEX
key, value = $1, $2
@datastore.set(key, value)
build_http "#{ key } set to #{ value }", 200
when GETTER_REGEX
key, value = $1, @datastore.get($1)
if value
build_http value, 200
else
build_http "#{ key } was not found", 500
end
else
build_http "Not a valid request", 500
end
end
private
# Some quick dirty HTTP response building
def build_http(response, code)
<<-HTTP
HTTP/1.1 #{ code } OK\r
Content-Type: text/plain\r
Content-Length: #{response.bytesize}\r
Connection: close\r
\r
#{ response }
HTTP
end
end
# Setup the server and database
server = TCPServer.new('localhost', 4000)
datastore = DataStore.new
loop do
socket = server.accept
request = socket.gets
response = ResponseBuilder.new(request, datastore).response
socket.print response
socket.close
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment