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