summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/zero.rb6
-rw-r--r--lib/zero/rack_request.rb44
-rw-r--r--lib/zero/router.rb31
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