diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/zero.rb | 6 | ||||
-rw-r--r-- | lib/zero/rack_request.rb | 44 | ||||
-rw-r--r-- | lib/zero/router.rb | 31 |
3 files changed, 79 insertions, 2 deletions
diff --git a/lib/zero.rb b/lib/zero.rb index 7dca8e1..e9824f9 100644 --- a/lib/zero.rb +++ b/lib/zero.rb @@ -1,5 +1,7 @@ +require 'rack' + module Zero require_relative 'zero/controller' - require_relative 'zero/request' - require_relative 'zero/response' + require_relative 'zero/rack_request' + require_relative 'zero/router' end diff --git a/lib/zero/rack_request.rb b/lib/zero/rack_request.rb new file mode 100644 index 0000000..0a93fc5 --- /dev/null +++ b/lib/zero/rack_request.rb @@ -0,0 +1,44 @@ +# as we need #update_param we patch it it into the request +# this is directly from thr request.rb of the rack repository, so this +# can be deleted, when rack was released +r = Rack::Request.new(Rack::MockRequest.env_for('foo')) +if not r.respond_to?('update_param') then + class Rack::Request + # Destructively update a parameter, whether it's in GET and/or POST. + # Returns nil. + # + # The parameter is updated wherever it was previous defined, so + # GET, POST, or both. If it wasn't previously defined, it's inserted into GET. + # + # env['rack.input'] is not touched. + def update_param(k, v) + found = false + if self.GET.has_key?(k) + found = true + self.GET[k] = v + end + if self.POST.has_key?(k) + found = true + self.POST[k] = v + end + unless found + self.GET[k] = v + end + @params = nil + nil + end + + # Destructively delete a parameter, whether it's in GET or POST. + # Returns the value of the deleted parameter. + # + # If the parameter is in both GET and POST, the POST value takes + # precedence since that's how #params works. + # + # env['rack.input'] is not touched. + def delete_param(k) + v = [ self.POST.delete(k), self.GET.delete(k) ].compact.first + @params = nil + v + end + end +end diff --git a/lib/zero/router.rb b/lib/zero/router.rb new file mode 100644 index 0000000..c890cb7 --- /dev/null +++ b/lib/zero/router.rb @@ -0,0 +1,31 @@ +module Zero + class Router + # match for variables in routes + VARIABLE_MATCH = %r{:(\w+)[^/]?} + # the replacement string to make it an regex + VARIABLE_REGEX = '(?<\1>.+?)' + + def initialize(routes) + @routes = {} + routes.each do |route, target| + @routes[ + Regexp.new( + route.gsub(VARIABLE_MATCH, VARIABLE_REGEX) + '$')] = target + end + end + + def call(env) + request = Rack::Request.new(env) + @routes.each do |route, target| + match = route.match(request.path) + if match + match.names.each_index do |i| + request.update_param(match.names[i], match.captures[i]) + end + return target.call(request.env) + end + end + [404, {'Content-Type' => 'text/html'}, ['Not found!']] + end + end +end |