pax_global_header 0000666 0000000 0000000 00000000064 13104640145 0014510 g ustar 00root root 0000000 0000000 52 comment=44befe565b5bc4036721a5f756e68e39ea52624e
actionpack-xml_parser-2.0.1/ 0000775 0000000 0000000 00000000000 13104640145 0015776 5 ustar 00root root 0000000 0000000 actionpack-xml_parser-2.0.1/.gitignore 0000664 0000000 0000000 00000000224 13104640145 0017764 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-2.0.1/.travis.yml 0000664 0000000 0000000 00000000341 13104640145 0020105 0 ustar 00root root 0000000 0000000 language: ruby
sudo: false
rvm:
- 2.2.5
- 2.3.1
- ruby-head
gemfile:
- gemfiles/Gemfile-edge
- Gemfile
notifications:
email: false
matrix:
fast_finish: true
allow_failures:
- rvm: ruby-head
cache: bundler
actionpack-xml_parser-2.0.1/Gemfile 0000664 0000000 0000000 00000000047 13104640145 0017272 0 ustar 00root root 0000000 0000000 source 'https://rubygems.org'
gemspec
actionpack-xml_parser-2.0.1/LICENSE 0000664 0000000 0000000 00000002062 13104640145 0017003 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-2.0.1/README.md 0000664 0000000 0000000 00000003214 13104640145 0017255 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'
```
Parameters parsing rules
------------------------
The parameters parsing is handled by `ActiveSupport::XMLConverter` so there may
be specific features and subtle differences depending on the chosen XML backend.
### Hashes
Basically, each node represents a key. With the following XML:
```xml
David
```
The resulting parameters will be:
```ruby
{"person" => {"name" => "David"}}
```
### File attachment
You can specify the `type` attribute of a node to attach files:
```xml
```
The resulting parameters will include a `StringIO` object with the given content,
name and content type set accordingly:
```ruby
{"person" => {"avatar" => #}}
```
### Arrays
There are several ways to pass an array. You can either specify multiple nodes
with the same name:
```xml
```
The resulting parameters will be:
```ruby
{"person" => {"address" => [{"city" => "Chicago"}, {"city" => "Ottawa"}]}}
```
You can also specify the `type` attribute of a node and nest child nodes inside:
```xml
```
will result in:
```ruby
{"person" => {"addresses" => [{"city" => "Melbourne"}, {"city" => "Paris"}]}}
```
actionpack-xml_parser-2.0.1/Rakefile 0000664 0000000 0000000 00000000314 13104640145 0017441 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-2.0.1/actionpack-xml_parser.gemspec 0000664 0000000 0000000 00000001465 13104640145 0023637 0 ustar 00root root 0000000 0000000 $:.push File.expand_path("../lib", __FILE__)
require "action_pack/xml_parser/version"
Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.name = 'actionpack-xml_parser'
s.version = ActionPack::XmlParser::VERSION
s.summary = 'XML parameters parser for Action Pack (removed from core in Rails 4.0)'
s.required_ruby_version = '>= 2.2.2'
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', '>= 5.0')
s.add_dependency('railties', '>= 5.0')
s.add_development_dependency('rake')
end
actionpack-xml_parser-2.0.1/gemfiles/ 0000775 0000000 0000000 00000000000 13104640145 0017571 5 ustar 00root root 0000000 0000000 actionpack-xml_parser-2.0.1/gemfiles/Gemfile-edge 0000664 0000000 0000000 00000000245 13104640145 0021767 0 ustar 00root root 0000000 0000000 source 'https://rubygems.org'
gemspec path: '..'
gem 'actionpack', github: 'rails/rails', branch: 'master'
gem 'railties', github: 'rails/rails', branch: 'master'
actionpack-xml_parser-2.0.1/lib/ 0000775 0000000 0000000 00000000000 13104640145 0016544 5 ustar 00root root 0000000 0000000 actionpack-xml_parser-2.0.1/lib/action_pack/ 0000775 0000000 0000000 00000000000 13104640145 0021017 5 ustar 00root root 0000000 0000000 actionpack-xml_parser-2.0.1/lib/action_pack/xml_parser.rb 0000664 0000000 0000000 00000000763 13104640145 0023526 0 ustar 00root root 0000000 0000000 require 'active_support'
require 'active_support/core_ext/hash/conversions'
require 'action_dispatch'
require 'action_dispatch/http/request'
require 'action_pack/xml_parser/version'
module ActionPack
class XmlParser
def self.register
original_parsers = ActionDispatch::Request.parameter_parsers
ActionDispatch::Request.parameter_parsers = original_parsers.merge(Mime[:xml].symbol => self)
end
def self.call(raw_post)
Hash.from_xml(raw_post) || {}
end
end
end
actionpack-xml_parser-2.0.1/lib/action_pack/xml_parser/ 0000775 0000000 0000000 00000000000 13104640145 0023173 5 ustar 00root root 0000000 0000000 actionpack-xml_parser-2.0.1/lib/action_pack/xml_parser/railtie.rb 0000664 0000000 0000000 00000000345 13104640145 0025153 0 ustar 00root root 0000000 0000000 require 'action_pack/xml_parser'
module ActionPack
class XmlParser
class Railtie < ::Rails::Railtie
initializer "actionpack-xml_parser.configure" do
ActionPack::XmlParser.register
end
end
end
end
actionpack-xml_parser-2.0.1/lib/action_pack/xml_parser/version.rb 0000664 0000000 0000000 00000000104 13104640145 0025200 0 ustar 00root root 0000000 0000000 module ActionPack
class XmlParser
VERSION = "2.0.1"
end
end
actionpack-xml_parser-2.0.1/lib/actionpack-xml_parser.rb 0000664 0000000 0000000 00000000105 13104640145 0023353 0 ustar 00root root 0000000 0000000 require 'action_pack/xml_parser/railtie' if defined?(Rails::Railtie)
actionpack-xml_parser-2.0.1/test/ 0000775 0000000 0000000 00000000000 13104640145 0016755 5 ustar 00root root 0000000 0000000 actionpack-xml_parser-2.0.1/test/fixtures/ 0000775 0000000 0000000 00000000000 13104640145 0020626 5 ustar 00root root 0000000 0000000 actionpack-xml_parser-2.0.1/test/fixtures/500.html 0000664 0000000 0000000 00000000022 13104640145 0022012 0 ustar 00root root 0000000 0000000 500 error fixture
actionpack-xml_parser-2.0.1/test/helper.rb 0000664 0000000 0000000 00000004610 13104640145 0020562 0 ustar 00root root 0000000 0000000 require 'bundler/setup'
require 'active_support/testing/autorun'
require 'action_pack/xml_parser'
require 'action_controller'
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
ActionPack::XmlParser.register
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 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-2.0.1/test/webservice_test.rb 0000664 0000000 0000000 00000017055 13104640145 0022507 0 ustar 00root root 0000000 0000000 require 'helper'
class WebServiceTest < ActionDispatch::IntegrationTest
class TestController < ActionController::Base
def assign_parameters
if params[:full]
render plain: dump_params_keys
else
render plain: (params.keys - ['controller', 'action']).sort.join(", ")
end
end
def dump_params_keys(hash = params)
hash.keys.sort.inject("") do |s, k|
value = hash[k]
if value.is_a?(Hash) || value.is_a?(ActionController::Parameters)
value = "(#{dump_params_keys(value)})"
else
value = ""
end
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 "/", params: 'content...',
headers: {'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 "/", params: 'content...',
headers: {'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 "/", params: 'content...',
headers: {'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 "/", params: 'false',
headers: {'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 "/", params: 'arial',
headers: {'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 "/", params: '33',
headers: {'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].symbol => Proc.new { |data| Hash.from_xml(data)['request'].with_indifferent_access } do
post "/", params: 'Arial,123',
headers: {'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 '/', params: 'value', headers: {'CONTENT_TYPE' => 'application/xml'}
assert_response 400
post '/', params: 'value', headers: {'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].symbol => Proc.new { |data| Hash.from_xml(data)['request'].with_indifferent_access } do
post "/", params: 'content...SimpleXml',
headers: {'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 "/", params: "", headers: {'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", params: "\n...\n",
headers: {'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 "/", params: xml, headers: {'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 "/", params: xml, headers: {'CONTENT_TYPE' => 'application/xml'}
assert_equal %(), @controller.params[:data]
end
end
private
def with_params_parsers(parsers = {})
old_session = @integration_session
original_parsers = ActionDispatch::Request.parameter_parsers
ActionDispatch::Request.parameter_parsers = original_parsers.merge parsers
reset!
yield
ensure
ActionDispatch::Request.parameter_parsers = original_parsers
@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-2.0.1/test/xml_params_parsing_test.rb 0000664 0000000 0000000 00000012347 13104640145 0024236 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
def assert_parses(expected, xml)
with_test_routing do
post "/parse", params: xml, headers: default_headers
assert_response :ok
assert_equal(expected, TestController.last_request_parameters)
end
end
test "nils are stripped from collections" do
assert_parses(
{"hash" => { "person" => []} },
"")
assert_parses(
{"hash" => { "person" => ['foo']} },
"foo\n")
end
test "parses hash params" do
xml = "David"
assert_parses({"person" => {"name" => "David"}}, xml)
end
test "parses single file" do
xml = "David#{::Base64.encode64('ABC')}"
person = ActionPack::XmlParser.call(xml)
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
test "logs error if parsing unsuccessful" do
with_test_routing do
output = StringIO.new
xml = "David#{::Base64.encode64('ABC')}"
post "/parse", params: xml, headers: 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", params: xml, headers: 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", params: xml, headers: 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 'parse', to: 'xml_params_parsing_test/test#parse'
end
yield
end
end
def default_headers
{'CONTENT_TYPE' => 'application/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", params: xml, headers: {'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 'parse', to: 'root_less_xml_params__parsing_test/test#parse'
end
yield
end
end
end