Skip to content

Commit

Permalink
allow access to params from within Goliath::Rack::Builder
Browse files Browse the repository at this point in the history
  • Loading branch information
joshbuddy committed Jul 4, 2011
1 parent 178befe commit d454b8c
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 50 deletions.
13 changes: 12 additions & 1 deletion examples/rack_routes.rb
Expand Up @@ -33,6 +33,13 @@ def response(env)
end
end

class BigNumber < Goliath::API
use Goliath::Rack::Params
def response(env)
[200, {}, "big number #{params[:number]}!"]
end
end

class Bonjour < Goliath::API
def response(env)
[200, {}, "bonjour!"]
Expand Down Expand Up @@ -81,7 +88,11 @@ class RackRoutes < Goliath::API
map "/aloha", Aloha

map "/:number", :number => /\d+/ do
run HelloNumber.new
if params[:number].to_i > 100
run BigNumber.new
else
run HelloNumber.new
end
end

map '/' do
Expand Down
12 changes: 9 additions & 3 deletions lib/goliath/rack/builder.rb
Expand Up @@ -2,14 +2,17 @@

module Goliath
module Rack
class Builder
class Builder < ::Rack::Builder
attr_accessor :params
include Params::Parser

# Builds the rack middleware chain for the given API
#
# @param klass [Class] The API class to build the middlewares for
# @param api [Object] The instantiated API
# @return [Object] The Rack middleware chain
def self.build(klass, api)
::Rack::Builder.app do
Builder.app do
klass.middlewares.each do |mw_klass, args, blk|
use(mw_klass, *args, &blk)
end
Expand All @@ -19,9 +22,12 @@ def self.build(klass, api)
run Builder.build(route_klass, route_klass.new)
}
klass.router.add(path, opts.dup).to {|env|
builder = Builder.new
env['params'] ||= {}
env['params'].merge!(env['router.params'])
::Rack::Builder.new(&blk).to_app.call(env)
builder.params = builder.retrieve_params(env)
builder.instance_eval(&blk)
builder.to_app.call(env)
}
end
run klass.router
Expand Down
92 changes: 47 additions & 45 deletions lib/goliath/rack/params.rb
Expand Up @@ -14,66 +14,68 @@ module Rack
# use Goliath::Rack::Params
#
class Params
include Goliath::Rack::Validator

def initialize(app)
@app = app
end

def call(env)
Goliath::Rack::Validator.safely(env) do
env['params'] = retrieve_params(env)
@app.call(env)
end
end

def retrieve_params(env)
params = {}
params.merge!(::Rack::Utils.parse_nested_query(env['QUERY_STRING']))
module Parser
def retrieve_params(env)
params = env['params'] || {}
params.merge!(::Rack::Utils.parse_nested_query(env['QUERY_STRING']))

if env['rack.input']
post_params = ::Rack::Utils::Multipart.parse_multipart(env)
unless post_params
body = env['rack.input'].read
env['rack.input'].rewind
if env['rack.input']
post_params = ::Rack::Utils::Multipart.parse_multipart(env)
unless post_params
body = env['rack.input'].read
env['rack.input'].rewind

unless body.empty?
begin
post_params = case(env['CONTENT_TYPE'])
when URL_ENCODED then
::Rack::Utils.parse_nested_query(body)
when JSON_ENCODED then
MultiJson.decode(body)
else
{}
unless body.empty?
begin
post_params = case(env['CONTENT_TYPE'])
when URL_ENCODED then
::Rack::Utils.parse_nested_query(body)
when JSON_ENCODED then
MultiJson.decode(body)
else
{}
end
rescue StandardError => e
raise Goliath::Validation::BadRequestError, "Invalid parameters: #{e.class.to_s}"
end
rescue StandardError => e
raise Goliath::Validation::BadRequestError, "Invalid parameters: #{e.class.to_s}"
else
post_params = {}
end
else
post_params = {}
end

params.merge!(post_params)
end

params.merge!(post_params)
indifferent_params(params)
end

indifferent_params(params)
end
def indifferent_params(params)
params = indifferent_hash.merge(params)
params.each do |key, value|
next unless value.is_a?(Hash)
params[key] = indifferent_params(value)
end
end

def indifferent_params(params)
params = indifferent_hash.merge(params)
params.each do |key, value|
next unless value.is_a?(Hash)
params[key] = indifferent_params(value)
# Creates a Hash with indifferent access.
def indifferent_hash
Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
end
end

# Creates a Hash with indifferent access.
def indifferent_hash
Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
include Goliath::Rack::Validator
include Parser

def initialize(app)
@app = app
end

def call(env)
Goliath::Rack::Validator.safely(env) do
env['params'] = retrieve_params(env)
@app.call(env)
end
end
end
end
end
11 changes: 10 additions & 1 deletion spec/integration/rack_routes_spec.rb
Expand Up @@ -34,10 +34,19 @@
end

it 'routes to the correct API using regex filters' do
with_api(RackRoutes) do
get_request({:path => '/98'}, err) do |c|
c.response_header.status.should == 200
c.response.should == 'number 98!'
end
end
end

it 'routes to the correct API referencing params in the body of the buidler' do
with_api(RackRoutes) do
get_request({:path => '/123123'}, err) do |c|
c.response_header.status.should == 200
c.response.should == 'number 123123!'
c.response.should == 'big number 123123!'
end
end
end
Expand Down

0 comments on commit d454b8c

Please sign in to comment.