Skip to content

Instantly share code, notes, and snippets.

@therealadam
Created April 28, 2012 19:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save therealadam/2521407 to your computer and use it in GitHub Desktop.
Save therealadam/2521407 to your computer and use it in GitHub Desktop.
# Postbin
# -------
# A postbin for your localhost.
#
# Usage
# =====
#
# It's a Unix program. You run it from a shell.
#
# $ ./postbin [-p PORT]
#
# I Heart Principles!!!
# =====================
#
# * Retain all the information about each HTTP request. More knowledge is more
# power.
# * Display each request in a useful way. It should be easy to see what's going
# on with your application by looking at application output or by using the web
# interface.
# * Fast. Quick startup, quick responses. This means small dependencies and
# less-clever code.
# * Easy to distribute. The ideal distribution is one file you put in your path
# and then use. The almost-ideal distribution is something like a homebrew
# recipe. An acceptable distribution is a gem.
require 'time'
require 'rack'
require 'leveldb'
class Postbin
def initialize(db_path)
@db = LevelDB::DB.new(db_path)
end
def call(env)
req = Rack::Request.new(env)
if req.post?
save_request(req)
send_ok
else
list_posts
end
end
def save_request(req)
timestamp = generate_timestamp
blob = extract_metadata(req)
@db[timestamp] = blob
end
def generate_timestamp
Time.now.utc.to_i.to_s
end
def extract_metadata(req)
derp = {
url: req.path,
headers: req.env.select { |k, v| k =~ /^HTTP_/ },
body: req.body.read
}
Marshal.dump(derp)
end
def send_ok
Rack::Response.new("OK")
end
def list_posts
posts = db.map do |key, value|
timestamp = Time.at(key.to_i)
req = Marshal.load(value)
p req
headers = req.fetch(:headers, {}).map do |key, value|
"#{key}: #{value}"
end
%Q{
---
#{timestamp}
#{req[:path]}
#{headers.join("\n")}
#{req[:body]}
}
end
body = posts.join("\n")
Rack::Response.new(body, 200, {"Content-Type" => "text/plain"})
end
def db
@db
end
end
if __FILE__ == $0
Rack::Server.start(
:app => Postbin.new('/tmp/posts'),
:Port => 8080
)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment