Created
April 28, 2012 19:12
-
-
Save therealadam/2521407 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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