Last active
December 13, 2015 23:29
-
-
Save wobh/4991690 to your computer and use it in GitHub Desktop.
A simple rack app with response builder hack.
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
| require 'pathname' | |
| require 'pp' | |
| class HTTPResponseBuilder | |
| STATUS_CODES = {100 => "Continue", | |
| 101 => "Switching Protocols", | |
| 200 => "OK", | |
| 201 => "Created", | |
| 202 => "Accepted", | |
| 203 => "Non-Authoritative Information", | |
| 204 => "No Content", | |
| 205 => "Reset Content", | |
| 206 => "Partial Content", | |
| 300 => "Multiple Choices", | |
| 301 => "Moved Permanently", | |
| 302 => "Found", | |
| 303 => "See Other", | |
| 304 => "Not Modified", | |
| 305 => "Use Proxy", | |
| 307 => "Temporary Redirect", | |
| 400 => "Bad Request", | |
| 401 => "Unauthorized", | |
| 402 => "Payment Required", | |
| 403 => "Forbidden", | |
| 404 => "Not Found", | |
| 405 => "Method Not Allowed", | |
| 406 => "Not Acceptable", | |
| 407 => "Proxy Authentication Required", | |
| 408 => "Request Time-out", | |
| 409 => "Conflict", | |
| 410 => "Gone", | |
| 411 => "Length Required", | |
| 412 => "Precondition Failed", | |
| 413 => "Request Entity Too Large", | |
| 414 => "Request-URI Too Large", | |
| 415 => "Unsupported Media Type", | |
| 416 => "Requested range not satisfiable", | |
| 417 => "Expectation Failed", | |
| 500 => "Internal Server Error", | |
| 501 => "Not Implemented", | |
| 502 => "Bad Gateway", | |
| 503 => "Service Unavailable", | |
| 504 => "Gateway Time-out", | |
| 505 => "HTTP Version not supported"} | |
| def valid_code? (code) | |
| STATUS_CODES.has_key?(code) | |
| end | |
| def set_code (code) | |
| if valid_code?(code) || code.nil? | |
| @code = code | |
| else | |
| raise("Invalid HTTP status code input: #{code}") | |
| end | |
| end | |
| def add_head (field_name, field_value) | |
| @head[field_name] = field_value | |
| end | |
| def add_head_content_type (mime_type) | |
| # TODO: check valid mime-types | |
| add_head("Content-Type", mime_type) | |
| end | |
| def add_head_content_length (length) | |
| add_head("Content-Length", length.to_s) | |
| end | |
| def date_rfc_1123 () | |
| datetime = Time.now | |
| datetime.gmtime.strftime("%a, %d %b %Y %H:%M:%S GMT") | |
| end | |
| def add_head_date (date=date_rfc_1123) | |
| add_head("Date", date) | |
| end | |
| def add_data (data) | |
| @data.push(data) | |
| end | |
| def initialize (code=nil, head={}, data=[]) | |
| @code = set_code(code) | |
| @head = head | |
| @data = data | |
| end | |
| def to_rack_plain (status_code) | |
| unless valid_code?(status_code) | |
| raise("Invalid HTTP status code input: #{status_code}") | |
| end | |
| set_code(status_code) | |
| text = STATUS_CODES[@code] | |
| @data.push(text) | |
| add_head_content_length(text.bytesize) | |
| add_head_content_type("text/plain") | |
| add_head_date() | |
| return [@code, @head, @data] | |
| end | |
| def to_rack () | |
| unless valid_code?(@code) | |
| raise("Invalid HTTP status code: #{@code}") | |
| end | |
| @data = @data.join | |
| add_head_content_length(@data.bytesize) | |
| add_head_date() | |
| return [@code, @head, [@data]] | |
| end | |
| end | |
| #FIXME: use Rack::Response | |
| class App | |
| @@mime_type_of_ext = {".ico" => "image/vnd.microsoft.icon", | |
| ".text" => "text/plain", | |
| ".txt" => "text/plain", | |
| ".html" => "text/html", | |
| ".htm" => "text/html"} | |
| def get_file (reqs, resp) | |
| pp "reqs.path = " + reqs.path | |
| fp = Pathname.new("." + reqs.path) | |
| case fp.to_s | |
| when "./" | |
| fp = Pathname.new("./index.html") | |
| when "./favicon.ico" | |
| fp = Pathname.new("./Images/favicon.ico") | |
| end | |
| # FIXME: use Rack::File | |
| # dn = File.dirname(fp) | |
| # fn = File.basename(fp) | |
| # ex = File.extname(fp) | |
| pp "filepath = " + fp.to_s | |
| pp "dirname = " + fp.dirname.to_s | |
| pp "basename = " + fp.basename.to_s | |
| pp "extension = " + fp.extname.to_s | |
| if fp.exist? | |
| resp.set_code(200) | |
| fp.open('r') do |fd| | |
| resp.add_data(fd.read) | |
| end | |
| else | |
| return resp.to_rack_plain(404) | |
| end | |
| resp.add_head_content_type(@@mime_type_of_ext[fp.extname.to_s]) | |
| # pp resp.to_rack | |
| return resp.to_rack | |
| end | |
| def call (env) | |
| resp = HTTPResponseBuilder.new() | |
| reqs = Rack::Request.new(env) | |
| get_file(reqs, resp) | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment