Permalink
Browse files

Add Rack::Request

darcs-hash:20070216153205-4fc50-397855182b9d3d9dded0edb36ff5dbfdbfe91f82.gz
  • Loading branch information...
1 parent a7eeb05 commit 5f13e3d01622b4aded1f174c75442483668f45bf @chneukirchen chneukirchen committed Feb 16, 2007
Showing with 132 additions and 0 deletions.
  1. +2 −0 lib/rack.rb
  2. +78 −0 lib/rack/request.rb
  3. +52 −0 test/spec_rack_request.rb
View
@@ -8,6 +8,8 @@ def self.version
autoload :Lint, "rack/lint"
autoload :File, "rack/file"
+ autoload :Request, "rack/request"
+
module Handler
autoload :CGI, "rack/handler/cgi"
autoload :Mongrel, "rack/handler/mongrel"
View
@@ -0,0 +1,78 @@
+module Rack
+ class Request
+ def initialize(env)
+ @env = env
+ end
+
+ def body; @env["rack.input"] end
+ def scheme; @env["rack.url_scheme"] end
+ def method; @env["REQUEST_METHOD"] end
+ def script_name; @env["SCRIPT_NAME"].to_s end
+ def path_info; @env["PATH_INFO"].to_s end
+ def host; @env["HTTP_HOST"] || @env["SERVER_NAME"] end
+ def path_info; @env["PATH_INFO"].to_s end
+ def port; @env["SERVER_PORT"].to_i end
+
+ def GET
+ parse_query(@env["QUERY_STRING"])
+ end
+
+ def POST
+ @env["rack.request.formvars"] ||= body.read
+ parse_query(@env["rack.request.formvars"])
+ end
+
+ def params
+ self.GET.update(self.POST)
+ end
+
+ def cookies
+ parse_query(@env["HTTP_COOKIE"], ';,')
+ end
+
+ def xhr?
+ @env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest"
+ end
+
+
+ # Performs URI escaping so that you can construct proper
+ # query strings faster. Use this rather than the cgi.rb
+ # version since it's faster. (Stolen from Camping).
+ def escape(s)
+ s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
+ '%'+$1.unpack('H2'*$1.size).join('%').upcase
+ }.tr(' ', '+')
+ end
+
+ # Unescapes a URI escaped string. (Stolen from Camping).
+ def unescape(s)
+ s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){
+ [$1.delete('%')].pack('H*')
+ }
+ end
+
+ # Stolen from Mongrel:
+ # Parses a query string by breaking it up at the '&'
+ # and ';' characters. You can also use this to parse
+ # cookies by changing the characters used in the second
+ # parameter (which defaults to '&;'.
+
+ def parse_query(qs, d = '&;')
+ params = {}
+ (qs||'').split(/[#{d}] */n).inject(params) { |h,p|
+ k, v=unescape(p).split('=',2)
+ if cur = params[k]
+ if cur.class == Array
+ params[k] << v
+ else
+ params[k] = [cur, v]
+ end
+ else
+ params[k] = v
+ end
+ }
+
+ return params
+ end
+ end
+end
View
@@ -0,0 +1,52 @@
+require 'test/spec'
+require 'stringio'
+
+require 'rack/testrequest'
+require 'rack/request'
+
+context "Rack::Request" do
+ specify "wraps the rack variables" do
+ req = Rack::Request.new(TestRequest.env({}))
+
+ req.body.should.respond_to? :gets
+ req.scheme.should.equal "http"
+ req.method.should.equal "GET"
+ req.script_name.should.equal ""
+ req.path_info.should.equal "/"
+ req.host.should.equal "example.org"
+ req.port.should.equal 8080
+ end
+
+ specify "can figure out the correct host" do
+ req = Rack::Request.new(TestRequest.env({"HTTP_HOST" => "www2.example.org"}))
+ req.host.should.equal "www2.example.org"
+ end
+
+ specify "can parse the query string" do
+ req = Rack::Request.new(TestRequest.env("QUERY_STRING"=>"foo=bar&quux=bla"))
+ req.GET.should.equal "foo" => "bar", "quux" => "bla"
+ req.POST.should.be.empty
+ req.params.should.equal "foo" => "bar", "quux" => "bla"
+ end
+
+ specify "can parse POST data" do
+ req = Rack::Request.new(TestRequest.env("QUERY_STRING"=>"foo=quux",
+ "rack.input" => StringIO.new("foo=bar&quux=bla")))
+ req.GET.should.equal "foo" => "quux"
+ req.POST.should.equal "foo" => "bar", "quux" => "bla"
+ req.params.should.equal "foo" => "bar", "quux" => "bla"
+ end
+
+ specify "can figure out if called via XHR" do
+ req = Rack::Request.new(TestRequest.env({}))
+ req.should.not.be.xhr
+
+ req = Rack::Request.new(TestRequest.env("HTTP_X_REQUESTED_WITH" => "XMLHttpRequest"))
+ req.should.be.xhr
+ end
+
+ specify "can parse cookies" do
+ req = Rack::Request.new(TestRequest.env({"HTTP_COOKIE" => "foo=bar;quux=h&m"}))
+ req.cookies.should.equal "foo" => "bar", "quux" => "h&m"
+ end
+end

0 comments on commit 5f13e3d

Please sign in to comment.