Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@ShopifyEng
Last active December 30, 2021 18:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ShopifyEng/c09cf3ce7cc506a778c5b46cc36a3aa9 to your computer and use it in GitHub Desktop.
Save ShopifyEng/c09cf3ce7cc506a778c5b46cc36a3aa9 to your computer and use it in GitHub Desktop.
How to Build a Web App with and without Rails Libraries
# mirth-4.rb
# Data persistence with YAML store:
# Use YAML to save the birthdays that
# can be reused when the server restarts
require 'socket'
# Require the library to use YAML::Store
require 'yaml/store'
server = TCPServer.new(1337)
# Attain file store from a YAML file
store = YAML::Store.new("mirth.yml")
loop do
client = server.accept
request_line = client.readline
method_token, target, version_number = request_line.split
case [method_token, target]
when ["GET", "/show/birthdays"]
response_status_code = "200 OK"
content_type = "text/html"
response_message = "<ul>\n"
# Get all the birthdays data in a hash object
all_birthdays = {}
store.transaction do
all_birthdays = store[:birthdays]
end
all_birthdays.each do |birthday|
response_message << "<li> #{birthday[:name]}</b> was born on #{birthday[:date]}!</li>\n"
end
response_message << "</ul>\n"
response_message << <<~STR
<form action="/add/birthday" method="post" enctype="application/x-www-form-urlencoded">
<p><label>Name <input type="text" name="name"></label></p>
<p><label>Birthday <input type="date" name="date"></label></p>
<p><button>Submit birthday</button></p>
</form>
STR
when ["POST", "/add/birthday"]
response_status_code = "303 See Other"
content_type = "text/html"
response_message = ""
all_headers = {}
while true
line = client.readline
break if line == "\r\n"
header_name, value = line.split(": ")
all_headers[header_name] = value
end
body = client.read(all_headers['Content-Length'].to_i)
require 'uri'
new_birthday = URI.decode_www_form(body).to_h
# Store the user-input birthday data
# back into the YAML store
store.transaction do
store[:birthdays] << new_birthday.transform_keys(&:to_sym)
end
else
response_status_code = "200 OK"
response_message = "✅ Received a #{method_token} request to #{target} with #{version_number}"
content_type = "text/plain"
end
http_response = <<~MSG
#{version_number} #{response_status_code}
Content-Type: #{content_type}; charset=#{response_message.encoding.name}
Location: /show/birthdays
#{response_message}
MSG
client.puts http_response
client.close
end
---
:birthdays:
- :name: Gma
:date: 01/01/2021
- :name: Tom
:date: 02/01/2021
- :name: Sesame
:date: 03/01/2021
@s4na
Copy link

s4na commented Dec 30, 2021

Thank you for the great blog!

I found the typo.
In order for the program to work correctly, there needs to be a line break on the next line after Location: /show/birthdays which is on line 77.


Best regards,
s4na

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment