class AlittleLess::RackApp

Constants

ID_CHARS
SLOW_GET_THRESOLD

Public Class Methods

call(env) click to toggle source
# File lib/a_little_less/rack_app.rb, line 8
def self.call env
    new(env).call
end
new(env) click to toggle source
# File lib/a_little_less/rack_app.rb, line 12
def initialize env
    @env = env
end

Public Instance Methods

call() click to toggle source
# File lib/a_little_less/rack_app.rb, line 16
def call
    req = build_req
    req.id = rand_id
    resp = req.resp

    t0 = Time.now
    run_safe { log_req req }

    begin
        AlittleLessApp.new(req).conversation!
    rescue => e
        loge e
        Bugsnag.notify e
        resp.status = 500
    end

    resp.headers['X-Runtime'] = Time.now - t0
    run_safe { log_resp req }
    handle_body req, resp

    [
        resp.status,
        resp.headers,
        resp.body
    ]
end

Private Instance Methods

build_req() click to toggle source
# File lib/a_little_less/rack_app.rb, line 142
def build_req
    OpenStruct.new(
        http_method: @env['REQUEST_METHOD'].downcase.to_sym,
        uri: clean_uri,
        params: params,
        env: @env,
        resp: build_resp,
        post_parts: Rack::Multipart.parse_multipart(@env),
        referer: @env['HTTP_REFERER'],
        ua: @env['HTTP_USER_AGENT']
        # body: @env['rack.input'].tmp # for file uploads non multipart
    )
end
build_resp() click to toggle source
# File lib/a_little_less/rack_app.rb, line 156
def build_resp
    OpenStruct.new(
        status: 200,
        headers: {},
        body: nil
    )
end
clean_uri() click to toggle source
# File lib/a_little_less/rack_app.rb, line 136
def clean_uri
    uri = @env['REQUEST_URI']
    uri.sub! /^(https?)?:\/\/[^\/]+/i, ''
    Rack::Utils.unescape uri
end
debug?() click to toggle source
# File lib/a_little_less/rack_app.rb, line 76
def debug?
    #true
end
get_content_type(path) click to toggle source
# File lib/a_little_less/rack_app.rb, line 64
def get_content_type path
    return unless File.exists? path
    require 'filemagic'
    unless defined? @@file_magic
        @@file_magic = FileMagic.open(:mime)
    end
    content_type = @@file_magic.file path
    if content_type =~ /^\S+\/\S+; charset=\S+$/i
        content_type
    end
end
handle_body(req, resp) click to toggle source
# File lib/a_little_less/rack_app.rb, line 49
def handle_body req, resp
    h = resp.headers

    if resp.body.is_a?(Hash) or resp.body.is_a?(Array)
        h['Content-Type'] = 'application/json'
        resp.body = [resp.body.to_json]
    end

    if p = h['X-Sendfile'].presence and h['Content-Type'].blank?
        if c = get_content_type(p)
            h['Content-Type'] = c
        end
    end
end
log_req(req) click to toggle source
# File lib/a_little_less/rack_app.rb, line 80
def log_req req
    if debug?
        logi "--ENV--\n#{ @env.to_yaml }\n--/ENV--"
    end
    logi [
        "Q #{req.id}",
        req.http_method.upcase,
        req.uri
    ].join(" ")
end
log_resp(req) click to toggle source
# File lib/a_little_less/rack_app.rb, line 91
def log_resp req
    resp = req.resp
    status = resp.status.to_i
    success = status >= 200 && status < 400

    file = if success
        if status >= 300
            resp.headers['Location']
        else
            resp.headers['X-Sendfile'].to_s
        end
    end

    status_str = resp.status.to_s
    if success
        status_str = status_str.send (status >= 300 ? :cyan : :green)
    end

    log_line = [
        "A #{req.id}",
        status_str,
        log_runtime(resp.headers['X-Runtime'], req.http_method),
        file
    ].join(" ")

    if success
        logi log_line
    else
        loge log_line.red
    end
end
log_runtime(xrt, met) click to toggle source
# File lib/a_little_less/rack_app.rb, line 123
def log_runtime xrt, met
    rt = xrt.to_f
    rts = '%.6f' % rt
    color = :light_red if met == :get && rt > SLOW_GET_THRESOLD
    color ? rts.colorize(color) : rts
end
params() click to toggle source
# File lib/a_little_less/rack_app.rb, line 130
def params
    Rack::Utils
        .parse_nested_query(@env['QUERY_STRING'])
        .symbolize_keys
end
rand_id() click to toggle source
# File lib/a_little_less/rack_app.rb, line 45
def rand_id
     4.times.map{ ID_CHARS.sample }.join
end