lib/cuba.rb in cuba-3.4.0 vs lib/cuba.rb in cuba-3.5.0

- old
+ new

@@ -1,10 +1,17 @@ require "rack" require "time" class Cuba + SLASH = "/".freeze + EMPTY = "".freeze + SEGMENT = "([^\\/]+)".freeze + DEFAULT = "text/html; charset=utf-8".freeze + class Response + LOCATION = "Location".freeze + attr_accessor :status attr :body attr :headers @@ -25,16 +32,16 @@ def write(str) s = str.to_s @length += s.bytesize - @headers["Content-Length"] = @length.to_s + @headers[Rack::CONTENT_LENGTH] = @length.to_s @body << s end def redirect(path, status = 302) - @headers["Location"] = path + @headers[LOCATION] = path @status = status end def finish [@status, @headers, @body] @@ -124,11 +131,11 @@ # of this whole `call!` method will be the # rack response tuple, which is exactly what we want. catch(:halt) do instance_eval(&@blk) - res.status = 404 + not_found res.finish end end def session @@ -179,13 +186,13 @@ # are carried out by #consume. yield(*captures) if res.status.nil? if res.body.empty? - res.status = 404 + not_found else - res.headers["Content-Type"] ||= "text/html; charset=utf-8" + res.headers[Rack::CONTENT_TYPE] ||= DEFAULT res.status = 200 end end halt(res.finish) @@ -193,34 +200,34 @@ end # @private Used internally by #on to ensure that SCRIPT_NAME and # PATH_INFO are reset to their proper values. def try - script, path = env["SCRIPT_NAME"], env["PATH_INFO"] + script, path = env[Rack::SCRIPT_NAME], env[Rack::PATH_INFO] yield ensure - env["SCRIPT_NAME"], env["PATH_INFO"] = script, path + env[Rack::SCRIPT_NAME], env[Rack::PATH_INFO] = script, path end private :try def consume(pattern) - matchdata = env["PATH_INFO"].match(/\A\/(#{pattern})(\/|\z)/) + matchdata = env[Rack::PATH_INFO].match(/\A\/(#{pattern})(\/|\z)/) return false unless matchdata path, *vars = matchdata.captures - env["SCRIPT_NAME"] += "/#{path}" - env["PATH_INFO"] = "#{vars.pop}#{matchdata.post_match}" + env[Rack::SCRIPT_NAME] += "/#{path}" + env[Rack::PATH_INFO] = "#{vars.pop}#{matchdata.post_match}" captures.push(*vars) end private :consume - def match(matcher, segment = "([^\\/]+)") + def match(matcher, segment = SEGMENT) case matcher when String then consume(matcher.gsub(/:\w+/, segment)) when Regexp then consume(matcher) when Symbol then consume(segment) when Proc then matcher.call @@ -238,24 +245,28 @@ # end def extension(ext = "\\w+") lambda { consume("([^\\/]+?)\.#{ext}\\z") } end - # Used to ensure that certain request parameters are present. Acts like a - # precondition / assertion for your route. + # Ensures that certain request parameters are present. Acts like a + # precondition / assertion for your route. A default value can be + # provided as a second argument. In that case, it always matches + # and the result is either the parameter or the default value. # # @example # # POST with data like user[fname]=John&user[lname]=Doe # on "signup", param("user") do |atts| # User.create(atts) # end - def param(key) - lambda { captures << req[key] unless req[key].to_s.empty? } - end + # + # on "login", param("username", "guest") do |username| + # # If not provided, username == "guest" + # end + def param(key, default = nil) + value = req[key] || default - def header(key) - lambda { env[key.upcase.tr("-","_")] } + lambda { captures << value unless value.to_s.empty? } end # Useful for matching against the request host (i.e. HTTP_HOST). # # @example @@ -277,11 +288,11 @@ def accept(mimetype) lambda do accept = String(env["HTTP_ACCEPT"]).split(",") if accept.any? { |s| s.strip == mimetype } - res["Content-Type"] = mimetype + res[Rack::CONTENT_TYPE] = mimetype end end end # Syntactic sugar for providing catch-all matches. @@ -301,11 +312,11 @@ # # GET / # on root do # res.write "Home" # end def root - env["PATH_INFO"] == "/" || env["PATH_INFO"] == "" + env[Rack::PATH_INFO] == SLASH || env[Rack::PATH_INFO] == EMPTY end # Syntatic sugar for providing HTTP Verb matching. # # @example @@ -379,9 +390,13 @@ # end # # => '{:role=>"admin", :site=>"main"}' # def vars env["cuba.vars"] ||= {} + end + + def not_found + res.status = 404 end end Cuba.settings[:req] = Rack::Request Cuba.settings[:res] = Cuba::Response