pax_global_header 0000666 0000000 0000000 00000000064 12514273423 0014515 g ustar 00root root 0000000 0000000 52 comment=405522d3acd6ce850f484d12a7b971c79662d27a
actionpack-xml_parser-1.0.2/ 0000775 0000000 0000000 00000000000 12514273423 0016003 5 ustar 00root root 0000000 0000000 actionpack-xml_parser-1.0.2/.gitignore 0000664 0000000 0000000 00000000224 12514273423 0017771 0 ustar 00root root 0000000 0000000 *.gem
*.rbc
.bundle
.config
.yardoc
*.lock
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp
actionpack-xml_parser-1.0.2/.travis.yml 0000664 0000000 0000000 00000000655 12514273423 0020122 0 ustar 00root root 0000000 0000000 language: ruby
sudo: false
rvm:
- 1.9
- 2.0
- 2.1
- 2.2
- ruby-head
gemfile:
- gemfiles/Gemfile-edge
- Gemfile
notifications:
email: false
before_install:
- gem install bundler
matrix:
fast_finish: true
allow_failures:
- rvm: ruby-head
exclude:
- rvm: 1.9
gemfile: gemfiles/Gemfile-edge
- rvm: 2.0
gemfile: gemfiles/Gemfile-edge
- rvm: 2.1
gemfile: gemfiles/Gemfile-edge
actionpack-xml_parser-1.0.2/Gemfile 0000664 0000000 0000000 00000000047 12514273423 0017277 0 ustar 00root root 0000000 0000000 source 'https://rubygems.org'
gemspec
actionpack-xml_parser-1.0.2/LICENSE 0000664 0000000 0000000 00000002062 12514273423 0017010 0 ustar 00root root 0000000 0000000 Copyright (c) 2013 Prem Sichanugrist
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
actionpack-xml_parser-1.0.2/README.md 0000664 0000000 0000000 00000001172 12514273423 0017263 0 ustar 00root root 0000000 0000000 actionpack-xml\_parser
======================
A XML parameters parser for Action Pack (removed from core in Rails 4.0)
Installation
------------
Include this gem into your Gemfile:
```ruby
gem 'actionpack-xml_parser'
```
Then, add `ActionDispatch::XmlParamsParser` middleware after `ActionDispatch::ParamsParser`
in `config/application.rb`:
```ruby
config.middleware.insert_after ActionDispatch::ParamsParser, ActionDispatch::XmlParamsParser
```
You may need to require the `ActionDispatch::XmlParamsParser` manually. Add the following
in your `config/application.rb`:
```ruby
require 'action_dispatch/xml_params_parser'
```
actionpack-xml_parser-1.0.2/Rakefile 0000664 0000000 0000000 00000000314 12514273423 0017446 0 ustar 00root root 0000000 0000000 #!/usr/bin/env rake
require "bundler/gem_tasks"
require 'rake/testtask'
Rake::TestTask.new do |t|
t.libs = ["test"]
t.pattern = "test/**/*_test.rb"
t.ruby_opts = ['-w']
end
task :default => :test
actionpack-xml_parser-1.0.2/actionpack-xml_parser.gemspec 0000664 0000000 0000000 00000001247 12514273423 0023642 0 ustar 00root root 0000000 0000000 Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.name = 'actionpack-xml_parser'
s.version = '1.0.2'
s.summary = 'XML parameters parser for Action Pack (removed from core in Rails 4.0)'
s.required_ruby_version = '>= 1.9.3'
s.license = 'MIT'
s.author = 'Prem Sichanugrist'
s.email = 's@sikac.hu'
s.homepage = 'http://www.rubyonrails.org'
s.files = Dir['LICENSE', 'README.md', 'lib/**/*']
s.require_path = 'lib'
s.extra_rdoc_files = %w( README.md )
s.rdoc_options.concat ['--main', 'README.md']
s.add_dependency('actionpack', '>= 4.0.0', '< 5')
s.add_development_dependency('rake')
end
actionpack-xml_parser-1.0.2/gemfiles/ 0000775 0000000 0000000 00000000000 12514273423 0017576 5 ustar 00root root 0000000 0000000 actionpack-xml_parser-1.0.2/gemfiles/Gemfile-edge 0000664 0000000 0000000 00000000155 12514273423 0021774 0 ustar 00root root 0000000 0000000 source 'https://rubygems.org'
gemspec path: '..'
gem 'actionpack', github: 'rails/rails', branch: 'master'
actionpack-xml_parser-1.0.2/lib/ 0000775 0000000 0000000 00000000000 12514273423 0016551 5 ustar 00root root 0000000 0000000 actionpack-xml_parser-1.0.2/lib/action_dispatch/ 0000775 0000000 0000000 00000000000 12514273423 0021705 5 ustar 00root root 0000000 0000000 actionpack-xml_parser-1.0.2/lib/action_dispatch/xml_params_parser.rb 0000664 0000000 0000000 00000003154 12514273423 0025754 0 ustar 00root root 0000000 0000000 require 'active_support/core_ext/hash/conversions'
require 'action_dispatch/http/request'
require 'active_support/core_ext/hash/indifferent_access'
module ActionDispatch
class XmlParamsParser
def initialize(app)
@app = app
end
def call(env)
if params = parse_formatted_parameters(env)
env["action_dispatch.request.request_parameters"] = params
end
@app.call(env)
end
private
def parse_formatted_parameters(env)
request = Request.new(env)
return false if request.content_length.zero?
mime_type = content_type_from_legacy_post_data_format_header(env) ||
request.content_mime_type
if mime_type == Mime::XML
# Rails 4.1 moved #deep_munge out of the request and into ActionDispatch::Request::Utils
munger = defined?(Request::Utils) ? Request::Utils : request
data = munger.deep_munge(Hash.from_xml(request.body.read) || {})
request.body.rewind if request.body.respond_to?(:rewind)
data.with_indifferent_access
else
false
end
rescue Exception => e # XML code block errors
logger(env).debug "Error occurred while parsing request parameters.\nContents:\n\n#{request.raw_post}"
raise ActionDispatch::ParamsParser::ParseError.new(e.message, e)
end
def content_type_from_legacy_post_data_format_header(env)
if env['HTTP_X_POST_DATA_FORMAT'].to_s.downcase == 'xml'
Mime::XML
end
end
def logger(env)
env['action_dispatch.logger'] || ActiveSupport::Logger.new($stderr)
end
end
end
actionpack-xml_parser-1.0.2/lib/actionpack/ 0000775 0000000 0000000 00000000000 12514273423 0020665 5 ustar 00root root 0000000 0000000 actionpack-xml_parser-1.0.2/lib/actionpack/xml_parser.rb 0000664 0000000 0000000 00000000054 12514273423 0023365 0 ustar 00root root 0000000 0000000 require 'action_dispatch/xml_params_parser'
actionpack-xml_parser-1.0.2/test/ 0000775 0000000 0000000 00000000000 12514273423 0016762 5 ustar 00root root 0000000 0000000 actionpack-xml_parser-1.0.2/test/fixtures/ 0000775 0000000 0000000 00000000000 12514273423 0020633 5 ustar 00root root 0000000 0000000 actionpack-xml_parser-1.0.2/test/fixtures/500.html 0000664 0000000 0000000 00000000022 12514273423 0022017 0 ustar 00root root 0000000 0000000 500 error fixture
actionpack-xml_parser-1.0.2/test/helper.rb 0000664 0000000 0000000 00000004772 12514273423 0020600 0 ustar 00root root 0000000 0000000 require 'bundler/setup'
require 'active_support/testing/autorun'
require 'action_controller'
require 'action_dispatch'
require 'action_dispatch/xml_params_parser'
FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
SharedTestRoutes = ActionDispatch::Routing::RouteSet.new
module ActionDispatch
module SharedRoutes
def before_setup
@routes = SharedTestRoutes
super
end
end
end
class RoutedRackApp
attr_reader :routes
def initialize(routes, &blk)
@routes = routes
@stack = ActionDispatch::MiddlewareStack.new(&blk).build(@routes)
end
def call(env)
@stack.call(env)
end
end
class ActionDispatch::IntegrationTest < ActiveSupport::TestCase
include ActionDispatch::SharedRoutes
def self.build_app(routes = nil)
RoutedRackApp.new(routes || ActionDispatch::Routing::RouteSet.new) do |middleware|
middleware.use "ActionDispatch::ShowExceptions", ActionDispatch::PublicExceptions.new(FIXTURE_LOAD_PATH)
middleware.use "ActionDispatch::ParamsParser"
middleware.use "ActionDispatch::XmlParamsParser"
middleware.use "Rack::Head"
yield(middleware) if block_given?
end
end
self.app = build_app
# Stub Rails dispatcher so it does not get controller references and
# simply return the controller#action as Rack::Body.
class StubDispatcher < ::ActionDispatch::Routing::RouteSet::Dispatcher
protected
def controller_reference(controller_param)
controller_param
end
def dispatch(controller, action, env)
[200, {'Content-Type' => 'text/html'}, ["#{controller}##{action}"]]
end
end
def self.stub_controllers
old_dispatcher = ActionDispatch::Routing::RouteSet::Dispatcher
ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher }
ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, StubDispatcher }
yield ActionDispatch::Routing::RouteSet.new
ensure
ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher }
ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, old_dispatcher }
end
def with_routing(&block)
temporary_routes = ActionDispatch::Routing::RouteSet.new
old_app, self.class.app = self.class.app, self.class.build_app(temporary_routes)
old_routes = SharedTestRoutes
silence_warnings { Object.const_set(:SharedTestRoutes, temporary_routes) }
yield temporary_routes
ensure
self.class.app = old_app
silence_warnings { Object.const_set(:SharedTestRoutes, old_routes) }
end
end
actionpack-xml_parser-1.0.2/test/webservice_test.rb 0000664 0000000 0000000 00000016065 12514273423 0022514 0 ustar 00root root 0000000 0000000 require 'helper'
class WebServiceTest < ActionDispatch::IntegrationTest
class TestController < ActionController::Base
def assign_parameters
if params[:full]
render :text => dump_params_keys
else
render :text => (params.keys - ['controller', 'action']).sort.join(", ")
end
end
def dump_params_keys(hash = params)
hash.keys.sort.inject("") do |s, k|
value = hash[k]
value = Hash === value ? "(#{dump_params_keys(value)})" : ""
s << ", " unless s.empty?
s << "#{k}#{value}"
end
end
end
def setup
@controller = TestController.new
@integration_session = nil
end
def test_check_parameters
with_test_route_set do
get "/"
assert_equal '', @controller.response.body
end
end
def test_post_xml
with_test_route_set do
post "/", 'content...',
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'entry', @controller.response.body
assert @controller.params.has_key?(:entry)
assert_equal 'content...', @controller.params["entry"]['summary']
assert_equal 'true', @controller.params["entry"]['attributed']
end
end
def test_put_xml
with_test_route_set do
put "/", 'content...',
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'entry', @controller.response.body
assert @controller.params.has_key?(:entry)
assert_equal 'content...', @controller.params["entry"]['summary']
assert_equal 'true', @controller.params["entry"]['attributed']
end
end
def test_put_xml_using_a_type_node
with_test_route_set do
put "/", 'content...',
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'type', @controller.response.body
assert @controller.params.has_key?(:type)
assert_equal 'content...', @controller.params["type"]['summary']
assert_equal 'true', @controller.params["type"]['attributed']
end
end
def test_put_xml_using_a_type_node_and_attribute
with_test_route_set do
put "/", 'false',
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'type', @controller.response.body
assert @controller.params.has_key?(:type)
assert_equal false, @controller.params["type"]['summary']
assert_equal 'true', @controller.params["type"]['attributed']
end
end
def test_post_xml_using_a_type_node
with_test_route_set do
post "/", 'arial',
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'font', @controller.response.body
assert @controller.params.has_key?(:font)
assert_equal 'arial', @controller.params['font']['type']
assert_equal 'true', @controller.params["font"]['attributed']
end
end
def test_post_xml_using_a_root_node_named_type
with_test_route_set do
post "/", '33',
{'CONTENT_TYPE' => 'application/xml'}
assert @controller.params.has_key?(:type)
assert_equal 33, @controller.params['type']
end
end
def test_post_xml_using_an_attributted_node_named_type
with_test_route_set do
with_params_parsers Mime::XML => Proc.new { |data| Hash.from_xml(data)['request'].with_indifferent_access } do
post "/", 'Arial,123',
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'type, z', @controller.response.body
assert @controller.params.has_key?(:type)
assert_equal 'Arial,12', @controller.params['type'], @controller.params.inspect
assert_equal '3', @controller.params['z'], @controller.params.inspect
end
end
end
def test_post_xml_using_a_disallowed_type_attribute
$stderr = StringIO.new
with_test_route_set do
post '/', 'value', 'CONTENT_TYPE' => 'application/xml'
assert_response 400
post '/', 'value', 'CONTENT_TYPE' => 'application/xml'
assert_response 400
end
ensure
$stderr = STDERR
end
def test_register_and_use_xml_simple
with_test_route_set do
with_params_parsers Mime::XML => Proc.new { |data| Hash.from_xml(data)['request'].with_indifferent_access } do
post "/", 'content...SimpleXml',
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'summary, title', @controller.response.body
assert @controller.params.has_key?(:summary)
assert @controller.params.has_key?(:title)
assert_equal 'content...', @controller.params["summary"]
assert_equal 'SimpleXml', @controller.params["title"]
end
end
end
def test_use_xml_ximple_with_empty_request
with_test_route_set do
assert_nothing_raised { post "/", "", {'CONTENT_TYPE' => 'application/xml'} }
assert_equal '', @controller.response.body
end
end
def test_dasherized_keys_as_xml
with_test_route_set do
post "/?full=1", "\n...\n",
{'CONTENT_TYPE' => 'application/xml'}
assert_equal 'action, controller, first_key(sub_key), full', @controller.response.body
assert_equal "...", @controller.params[:first_key][:sub_key]
end
end
def test_typecast_as_xml
with_test_route_set do
xml = <<-XML
15
false
true
2005-03-17
2005-03-17T21:41:07Z
unparsed
1
hello
1974-07-25
XML
post "/", xml, {'CONTENT_TYPE' => 'application/xml'}
params = @controller.params
assert_equal 15, params[:data][:a]
assert_equal false, params[:data][:b]
assert_equal true, params[:data][:c]
assert_equal Date.new(2005,3,17), params[:data][:d]
assert_equal Time.utc(2005,3,17,21,41,7), params[:data][:e]
assert_equal "unparsed", params[:data][:f]
assert_equal [1, "hello", Date.new(1974,7,25)], params[:data][:g]
end
end
def test_entities_unescaped_as_xml_simple
with_test_route_set do
xml = <<-XML
<foo "bar's" & friends>
XML
post "/", xml, {'CONTENT_TYPE' => 'application/xml'}
assert_equal %(), @controller.params[:data]
end
end
private
def with_params_parsers(parsers = {})
old_session = @integration_session
@app = ActionDispatch::ParamsParser.new(app.routes, parsers)
reset!
yield
ensure
@integration_session = old_session
end
def with_test_route_set
with_routing do |set|
set.draw do
match '/', :to => 'web_service_test/test#assign_parameters', :via => :all
end
yield
end
end
end
actionpack-xml_parser-1.0.2/test/xml_params_parsing_test.rb 0000664 0000000 0000000 00000014676 12514273423 0024252 0 ustar 00root root 0000000 0000000 require 'helper'
class XmlParamsParsingTest < ActionDispatch::IntegrationTest
class TestController < ActionController::Base
class << self
attr_accessor :last_request_parameters
attr_accessor :last_request
end
def parse
self.class.last_request_parameters = request.request_parameters
self.class.last_request = request
head :ok
end
end
def teardown
TestController.last_request_parameters = nil
TestController.last_request = nil
end
test "parses a strict rack.input" do
class Linted
undef call if method_defined?(:call)
def call(env)
bar = env['action_dispatch.request.request_parameters']['foo']
result = "#{bar}"
[200, {"Content-Type" => "application/xml", "Content-Length" => result.length.to_s}, [result]]
end
end
req = Rack::MockRequest.new(ActionDispatch::XmlParamsParser.new(Linted.new))
resp = req.post('/', "CONTENT_TYPE" => "application/xml", :input => "bar", :lint => true)
assert_equal "bar", resp.body
end
def assert_parses(expected, xml)
with_test_routing do
post "/parse", xml, default_headers
assert_response :ok
assert_equal(expected, TestController.last_request_parameters)
end
end
test "nils are stripped from collections" do
if ActiveSupport::VERSION::MAJOR >= 5
# Rails 5 changes the behavior of #deep_munge for security reason.
# https://github.com/rails/rails/pull/16924
assert_parses(
{"hash" => { "person" => []} },
"")
else
assert_parses(
{"hash" => { "person" => nil} },
"")
end
assert_parses(
{"hash" => { "person" => ['foo']} },
"foo\n")
end
test "parses hash params" do
with_test_routing do
xml = "David"
post "/parse", xml, default_headers
assert_response :ok
assert_equal({"person" => {"name" => "David"}}, TestController.last_request_parameters)
end
end
test "parses single file" do
with_test_routing do
xml = "David#{::Base64.encode64('ABC')}"
post "/parse", xml, default_headers
assert_response :ok
person = TestController.last_request_parameters
assert_equal "image/jpg", person['person']['avatar'].content_type
assert_equal "me.jpg", person['person']['avatar'].original_filename
assert_equal "ABC", person['person']['avatar'].read
end
end
test "logs error if parsing unsuccessful" do
with_test_routing do
output = StringIO.new
xml = "David#{::Base64.encode64('ABC')}"
post "/parse", xml, default_headers.merge('action_dispatch.show_exceptions' => true, 'action_dispatch.logger' => ActiveSupport::Logger.new(output))
assert_response :bad_request
output.rewind && err = output.read
assert err =~ /Error occurred while parsing request parameters/
end
end
test "occurring a parse error if parsing unsuccessful" do
with_test_routing do
begin
$stderr = StringIO.new # suppress the log
xml = "David"
exception = assert_raise(ActionDispatch::ParamsParser::ParseError) { post "/parse", xml, default_headers.merge('action_dispatch.show_exceptions' => false) }
assert_equal REXML::ParseException, exception.original_exception.class
assert_equal exception.original_exception.message, exception.message
ensure
$stderr = STDERR
end
end
end
test "parses multiple files" do
xml = <<-end_body
David
#{::Base64.encode64('ABC')}
#{::Base64.encode64('DEF')}
end_body
with_test_routing do
post "/parse", xml, default_headers
assert_response :ok
end
person = TestController.last_request_parameters
assert_equal "image/jpg", person['person']['avatars']['avatar'].first.content_type
assert_equal "me.jpg", person['person']['avatars']['avatar'].first.original_filename
assert_equal "ABC", person['person']['avatars']['avatar'].first.read
assert_equal "image/gif", person['person']['avatars']['avatar'].last.content_type
assert_equal "you.gif", person['person']['avatars']['avatar'].last.original_filename
assert_equal "DEF", person['person']['avatars']['avatar'].last.read
end
test "rewinds body if it implements rewind" do
xml = "Marie"
with_test_routing do
post "/parse", xml, default_headers
assert_equal TestController.last_request.body.read, xml
end
end
private
def with_test_routing
with_routing do |set|
set.draw do
post ':action', :to => ::XmlParamsParsingTest::TestController
end
yield
end
end
def default_headers
{'CONTENT_TYPE' => 'application/xml'}
end
end
class LegacyXmlParamsParsingTest < XmlParamsParsingTest
private
def default_headers
{'HTTP_X_POST_DATA_FORMAT' => 'xml'}
end
end
class RootLessXmlParamsParsingTest < ActionDispatch::IntegrationTest
class TestController < ActionController::Base
wrap_parameters :person, :format => :xml
class << self
attr_accessor :last_request_parameters
end
def parse
self.class.last_request_parameters = request.request_parameters
head :ok
end
end
def teardown
TestController.last_request_parameters = nil
end
test "parses hash params" do
with_test_routing do
xml = "David"
post "/parse", xml, {'CONTENT_TYPE' => 'application/xml'}
assert_response :ok
assert_equal({"name" => "David", "person" => {"name" => "David"}}, TestController.last_request_parameters)
end
end
private
def with_test_routing
with_routing do |set|
set.draw do
post ':action', :to => ::RootLessXmlParamsParsingTest::TestController
end
yield
end
end
end