This commit is contained in:
@@ -0,0 +1 @@
|
||||
require "rack/typhoeus/middleware/params_decoder"
|
||||
@@ -0,0 +1,57 @@
|
||||
require 'rack/typhoeus/middleware/params_decoder/helper'
|
||||
|
||||
module Rack
|
||||
module Typhoeus
|
||||
module Middleware
|
||||
|
||||
# This Rack middleware takes care of the proper deserialization of
|
||||
# the nested params encoded by Typhoeus.
|
||||
#
|
||||
# @example Require the railtie when using Rails.
|
||||
# require 'typhoeus/railtie'
|
||||
#
|
||||
# @example Include the middleware for Rack based applications.
|
||||
# use Rack::Typhoeus::Middleware::ParamsDecoder
|
||||
#
|
||||
# @example Use the helper directly. Not recommended as b/c the interface might change.
|
||||
# require 'rack/typhoeus/middleware/params_decoder/helper'
|
||||
# include Rack::Typhoeus::Middleware::ParamsDecoder::Helper
|
||||
# decode!(params)
|
||||
#
|
||||
# @author Dwayne Macgowan
|
||||
# @since 0.5.4
|
||||
class ParamsDecoder
|
||||
include ParamsDecoder::Helper
|
||||
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
req = Rack::Request.new(env)
|
||||
decode(req.params).each_pair { |k, v| update_params req, k, v }
|
||||
@app.call(env)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Persist params change in environment. Extracted from:
|
||||
# https://github.com/rack/rack/blob/master/lib/rack/request.rb#L243
|
||||
def update_params(req, k, v)
|
||||
found = false
|
||||
if req.GET.has_key?(k)
|
||||
found = true
|
||||
req.GET[k] = v
|
||||
end
|
||||
if req.POST.has_key?(k)
|
||||
found = true
|
||||
req.POST[k] = v
|
||||
end
|
||||
unless found
|
||||
req.GET[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,76 @@
|
||||
module Rack
|
||||
module Typhoeus
|
||||
module Middleware
|
||||
class ParamsDecoder
|
||||
module Helper
|
||||
|
||||
# Recursively decodes Typhoeus encoded arrays in given Hash.
|
||||
#
|
||||
# @example Use directly in a Rails controller.
|
||||
# class ApplicationController
|
||||
# before_filter :decode_typhoeus_arrays
|
||||
# end
|
||||
#
|
||||
# @author Dwayne Macgowan
|
||||
#
|
||||
def decode_typhoeus_arrays
|
||||
decode!(params)
|
||||
end
|
||||
|
||||
# Recursively decodes Typhoeus encoded arrays in given Hash.
|
||||
#
|
||||
# @param hash [Hash]. This Hash will be modified!
|
||||
#
|
||||
# @return [Hash] Hash with properly decoded nested arrays.
|
||||
def decode!(hash)
|
||||
return hash unless hash.is_a?(Hash)
|
||||
hash.each_pair do |key,value|
|
||||
if value.is_a?(Hash)
|
||||
decode!(value)
|
||||
hash[key] = convert(value)
|
||||
end
|
||||
end
|
||||
hash
|
||||
end
|
||||
|
||||
def decode(hash)
|
||||
decode!(hash.dup)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Checks if Hash is an Array encoded as a Hash.
|
||||
# Specifically will check for the Hash to have this
|
||||
# form: {'0' => v0, '1' => v1, .., 'n' => vN }
|
||||
#
|
||||
# @param hash [Hash]
|
||||
#
|
||||
# @return [Boolean] True if its a encoded Array, else false.
|
||||
def encoded?(hash)
|
||||
return false if hash.empty?
|
||||
if hash.keys.size > 1
|
||||
keys = hash.keys.map{|i| i.to_i if i.respond_to?(:to_i)}.sort
|
||||
keys == hash.keys.size.times.to_a
|
||||
else
|
||||
hash.keys.first =~ /0/
|
||||
end
|
||||
end
|
||||
|
||||
# If the Hash is an array encoded by typhoeus an array is returned
|
||||
# else the self is returned
|
||||
#
|
||||
# @param hash [Hash] The Hash to convert into an Array.
|
||||
#
|
||||
# @return [Arraya/Hash]
|
||||
def convert(hash)
|
||||
if encoded?(hash)
|
||||
hash.sort{ |a, b| a[0].to_i <=> b[0].to_i }.map{ |key, value| value }
|
||||
else
|
||||
hash
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user