rack-app 5.6.0 → 5.7.0.rc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/rack/app/bundled_extensions/payload.rb +3 -0
- data/lib/rack/app/bundled_extensions.rb +1 -0
- data/lib/rack/app/constants.rb +15 -6
- data/lib/rack/app/endpoint/builder.rb +5 -1
- data/lib/rack/app/endpoint/config.rb +8 -0
- data/lib/rack/app/endpoint/executor.rb +1 -1
- data/lib/rack/app/instance_methods/payload.rb +8 -14
- data/lib/rack/app/middlewares/configuration/payload_parser_setter.rb +18 -0
- data/lib/rack/app/middlewares/configuration.rb +1 -0
- data/lib/rack/app/middlewares/payload/parser_setter.rb +18 -0
- data/lib/rack/app/middlewares/payload.rb +3 -0
- data/lib/rack/app/middlewares/payload_parser_setter.rb +18 -0
- data/lib/rack/app/middlewares.rb +2 -0
- data/lib/rack/app/payload/builder.rb +9 -0
- data/lib/rack/app/payload/parser/builder/formats.rb +93 -0
- data/lib/rack/app/payload/parser/builder.rb +39 -0
- data/lib/rack/app/payload/parser.rb +26 -0
- data/lib/rack/app/payload.rb +4 -0
- data/lib/rack/app/serializer.rb +2 -2
- data/lib/rack/app/singleton_methods/extensions.rb +1 -0
- data/lib/rack/app/singleton_methods/formats.rb +4 -6
- data/lib/rack/app/singleton_methods/params_validator.rb +1 -0
- data/lib/rack/app/singleton_methods/payload.rb +12 -0
- data/lib/rack/app/singleton_methods.rb +10 -8
- data/lib/rack/app.rb +1 -0
- data/spike/slice_vs_sub.rb +30 -0
- data/spike/validator_with_minitest.rb +94 -0
- data/spike/xml.rb +24 -0
- metadata +18 -4
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 3a9a62e22dc06930f5166a88e4af70c06faac8a4
         | 
| 4 | 
            +
              data.tar.gz: 7c72121249494bd83440ea3a6819cc24fa8d6608
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: cb093d6592e2ee3cb1efb4a2a40fc02a7cb44972e0abf4acb748d694be5d0dd33b0a1363bdce1d589a28596ab007e805c2b082f28327fd92bc2bd8458be3e654
         | 
| 7 | 
            +
              data.tar.gz: 221eab9e61d07b9a45c3ca302c02795e40c27d4fbcbf2e3af6a8a67e36c38bc040e90af37fafcd94d72c4250a2a525366371b79bb86c109ead12756e2df397bb
         | 
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            5. | 
| 1 | 
            +
            5.7.0.rc
         | 
    
        data/lib/rack/app/constants.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            module Rack::App::Constants
         | 
| 2 2 |  | 
| 3 3 | 
             
              require "rack/app/constants/http_status_codes"
         | 
| 4 | 
            -
             | 
| 4 | 
            +
             | 
| 5 5 | 
             
              def self.rack_constant(constant_name, fallback_value)
         | 
| 6 6 | 
             
                ::Rack.const_get(constant_name)
         | 
| 7 7 | 
             
              rescue NameError
         | 
| @@ -27,7 +27,7 @@ module Rack::App::Constants | |
| 27 27 | 
             
                METHODS = (METHOD.constants - [:ANY]).map(&:to_s).freeze
         | 
| 28 28 |  | 
| 29 29 | 
             
                module Headers
         | 
| 30 | 
            -
                  CONTENT_TYPE =  | 
| 30 | 
            +
                  CONTENT_TYPE = "Content-Type".freeze
         | 
| 31 31 | 
             
                end
         | 
| 32 32 |  | 
| 33 33 | 
             
              end
         | 
| @@ -39,13 +39,22 @@ module Rack::App::Constants | |
| 39 39 | 
             
                REQUEST_METHOD = Rack::App::Constants.rack_constant(:REQUEST_METHOD, "REQUEST_METHOD")
         | 
| 40 40 |  | 
| 41 41 | 
             
                EXTNAME = 'rack-app.extname'.freeze
         | 
| 42 | 
            -
                 | 
| 43 | 
            -
                 | 
| 44 | 
            -
                 | 
| 45 | 
            -
             | 
| 42 | 
            +
                SERIALIZER = 'rack-app.serializer'.freeze
         | 
| 43 | 
            +
                CONTENT_TYPE = 'CONTENT_TYPE'.freeze
         | 
| 44 | 
            +
                REQUEST_HANDLER = 'rack-app.handler'.freeze
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                PARAMS_GETTER = 'rack-app.params.getter'
         | 
| 47 | 
            +
                PARSED_PARAMS = 'rack-app.params.parsed'.freeze
         | 
| 48 | 
            +
                VALIDATED_PARAMS = 'rack-app.params.validated'.freeze
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                PAYLOAD_PARSER = 'rack-app.payload.parser'.freeze
         | 
| 51 | 
            +
                PAYLOAD_GETTER = 'rack-app.payload.getter'.freeze
         | 
| 52 | 
            +
                PARSED_PAYLOAD = 'rack-app.payload.parsed'.freeze
         | 
| 53 | 
            +
             | 
| 46 54 | 
             
                ORIGINAL_PATH_INFO = 'rack-app.original_path_info'.freeze
         | 
| 47 55 | 
             
                PATH_PARAMS_MATCHER = 'rack-app.path_params_matcher'.freeze
         | 
| 48 56 | 
             
                METHODOVERRIDE_ORIGINAL_METHOD = 'rack-app.methodoverride.original_method'.freeze
         | 
| 57 | 
            +
             | 
| 49 58 | 
             
              end
         | 
| 50 59 |  | 
| 51 60 | 
             
              MOUNTED_DIRECTORY = '[Mounted Directory]'.freeze
         | 
| @@ -7,14 +7,18 @@ class Rack::App::Endpoint::Builder | |
| 7 7 |  | 
| 8 8 | 
             
              def build
         | 
| 9 9 | 
             
                builder = Rack::Builder.new
         | 
| 10 | 
            +
                apply_core_middlewares(builder)
         | 
| 10 11 | 
             
                apply_middleware_build_blocks(builder)
         | 
| 11 | 
            -
                @config.endpoint_method_name
         | 
| 12 12 | 
             
                builder.run(Rack::App::Endpoint::Executor.new(@config))
         | 
| 13 13 | 
             
                builder.to_app
         | 
| 14 14 | 
             
              end
         | 
| 15 15 |  | 
| 16 16 | 
             
              protected
         | 
| 17 17 |  | 
| 18 | 
            +
              def apply_core_middlewares(builder)
         | 
| 19 | 
            +
                builder.use(Rack::App::Middlewares::Configuration::PayloadParserSetter)
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 18 22 | 
             
              def apply_middleware_build_blocks(builder)
         | 
| 19 23 | 
             
                builder_blocks.each do |builder_block|
         | 
| 20 24 | 
             
                  builder_block.call(builder)
         | 
| @@ -20,6 +20,14 @@ class Rack::App::Endpoint::Config | |
| 20 20 | 
             
                serializer_builder.to_serializer
         | 
| 21 21 | 
             
              end
         | 
| 22 22 |  | 
| 23 | 
            +
              def payload
         | 
| 24 | 
            +
                app_class.__send__(:payload)
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              def payload_parser
         | 
| 28 | 
            +
                payload.parser.to_parser
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 23 31 | 
             
              def serializer_builder
         | 
| 24 32 | 
             
                @raw[:serializer_builder] ||= app_class.__send__(:formats)
         | 
| 25 33 | 
             
              end
         | 
| @@ -2,6 +2,7 @@ class Rack::App::Endpoint::Executor | |
| 2 2 |  | 
| 3 3 | 
             
              def initialize(endpoint_properties)
         | 
| 4 4 | 
             
                @endpoint_properties = endpoint_properties
         | 
| 5 | 
            +
                @endpoint_properties.endpoint_method_name
         | 
| 5 6 | 
             
              end
         | 
| 6 7 |  | 
| 7 8 | 
             
              def call(env)
         | 
| @@ -25,7 +26,6 @@ class Rack::App::Endpoint::Executor | |
| 25 26 | 
             
              end
         | 
| 26 27 |  | 
| 27 28 | 
             
              EXTNAME = ::Rack::App::Constants::ENV::EXTNAME
         | 
| 28 | 
            -
              CONTENT_TYPE = ::Rack::App::Constants::HTTP::Headers::CONTENT_TYPE
         | 
| 29 29 |  | 
| 30 30 | 
             
              def set_response_body(handler, response_body)
         | 
| 31 31 | 
             
                extname = handler.request.env[EXTNAME]
         | 
| @@ -1,29 +1,23 @@ | |
| 1 1 | 
             
            module Rack::App::InstanceMethods::Payload
         | 
| 2 2 |  | 
| 3 | 
            +
              def payload
         | 
| 4 | 
            +
                request.env[Rack::App::Constants::ENV::PAYLOAD_GETTER].call
         | 
| 5 | 
            +
              end
         | 
| 6 | 
            +
             | 
| 3 7 | 
             
              def payload_stream(&block)
         | 
| 4 8 | 
             
                return nil unless @request.body.respond_to?(:gets)
         | 
| 5 | 
            -
                while chunk = request.body.gets
         | 
| 9 | 
            +
                while chunk = @request.body.gets
         | 
| 6 10 | 
             
                  block.call(chunk)
         | 
| 7 11 | 
             
                end
         | 
| 8 | 
            -
                request.body.rewind
         | 
| 12 | 
            +
                @request.body.rewind
         | 
| 9 13 | 
             
                nil
         | 
| 10 14 | 
             
              end
         | 
| 11 15 |  | 
| 12 | 
            -
              def payload
         | 
| 13 | 
            -
                @__payload__ ||= lambda {
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                  payload = ''
         | 
| 16 | 
            -
                  payload_stream { |chunk| payload << chunk }
         | 
| 17 | 
            -
                  return payload
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                }.call
         | 
| 20 | 
            -
              end
         | 
| 21 | 
            -
             | 
| 22 16 | 
             
              def payload_to_file(file_path, file_mod='w')
         | 
| 17 | 
            +
                return nil unless @request.body.respond_to?(:gets)
         | 
| 23 18 | 
             
                File.open(file_path, file_mod) do |file|
         | 
| 24 | 
            -
                  payload_stream | 
| 19 | 
            +
                  payload_stream{ |chunk| file.print(chunk) }
         | 
| 25 20 | 
             
                end
         | 
| 26 21 | 
             
              end
         | 
| 27 22 |  | 
| 28 23 | 
             
            end
         | 
| 29 | 
            -
             | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            class Rack::App::Middlewares::Configuration::PayloadParserSetter
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              PARSER = ::Rack::App::Constants::ENV::PAYLOAD_PARSER
         | 
| 4 | 
            +
              PARSED = ::Rack::App::Constants::ENV::PARSED_PAYLOAD
         | 
| 5 | 
            +
              GETTER = ::Rack::App::Constants::ENV::PAYLOAD_GETTER
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def initialize(app)
         | 
| 8 | 
            +
                @app = app
         | 
| 9 | 
            +
                @parser = Rack::App::Payload::Parser.new 
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              def call(env)
         | 
| 13 | 
            +
                env[PARSER]= @parser
         | 
| 14 | 
            +
                env[GETTER]= lambda { env[PARSED] ||= env[PARSER].parse_env(env) }
         | 
| 15 | 
            +
                @app.call(env)
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            end
         | 
| @@ -5,6 +5,7 @@ class Rack::App::Middlewares::Configuration | |
| 5 5 |  | 
| 6 6 | 
             
              require "rack/app/middlewares/configuration/handler_setter"
         | 
| 7 7 | 
             
              require "rack/app/middlewares/configuration/serializer_setter"
         | 
| 8 | 
            +
              require "rack/app/middlewares/configuration/payload_parser_setter"
         | 
| 8 9 |  | 
| 9 10 | 
             
              require "rack/app/middlewares/configuration/path_params_matcher"
         | 
| 10 11 |  | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            class Rack::App::Middlewares::Payload::ParserSetter
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              PARSER = ::Rack::App::Constants::ENV::PAYLOAD_PARSER
         | 
| 4 | 
            +
              PARSED = ::Rack::App::Constants::ENV::PARSED_PAYLOAD
         | 
| 5 | 
            +
              GETTER = ::Rack::App::Constants::ENV::PAYLOAD_GETTER
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def initialize(app, payload_builder)
         | 
| 8 | 
            +
                @payload_parser = payload_builder.parser.to_parser
         | 
| 9 | 
            +
                @app = app
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              def call(env)
         | 
| 13 | 
            +
                env[PARSER]= @payload_parser
         | 
| 14 | 
            +
                env[GETTER]= lambda { env[PARSED] ||= env[PARSER].parse_env(env) }
         | 
| 15 | 
            +
                @app.call(env)
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            class Rack::App::Middlewares::PayloadParserSetter
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              PARSER = ::Rack::App::Constants::ENV::PAYLOAD_PARSER
         | 
| 4 | 
            +
              PARSED = ::Rack::App::Constants::ENV::PARSED_PAYLOAD
         | 
| 5 | 
            +
              GETTER = ::Rack::App::Constants::ENV::PAYLOAD_GETTER
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def initialize(app, payload_parser)
         | 
| 8 | 
            +
                @payload_parser = payload_parser
         | 
| 9 | 
            +
                @app = app
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              def call(env)
         | 
| 13 | 
            +
                env[PARSER]= @payload_parser
         | 
| 14 | 
            +
                env[GETTER]= lambda { env[PARSED] ||= env[PARSER].parse_env(env) }
         | 
| 15 | 
            +
                @app.call(env)
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            end
         | 
    
        data/lib/rack/app/middlewares.rb
    CHANGED
    
    | @@ -1,7 +1,9 @@ | |
| 1 1 | 
             
            module Rack::App::Middlewares
         | 
| 2 | 
            +
              require 'rack/app/middlewares/payload_parser_setter'
         | 
| 2 3 | 
             
              require 'rack/app/middlewares/path_info_cutter'
         | 
| 3 4 | 
             
              require 'rack/app/middlewares/configuration'
         | 
| 4 5 | 
             
              require 'rack/app/middlewares/header_setter'
         | 
| 6 | 
            +
              require 'rack/app/middlewares/payload'
         | 
| 5 7 | 
             
              require 'rack/app/middlewares/params'
         | 
| 6 8 | 
             
              require 'rack/app/middlewares/hooks'
         | 
| 7 9 | 
             
            end
         | 
| @@ -0,0 +1,93 @@ | |
| 1 | 
            +
            module Rack::App::Payload::Parser::Builder::Formats
         | 
| 2 | 
            +
              extend(self)
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              JSON_CONTENT_TYPE = [
         | 
| 5 | 
            +
                "application/json",
         | 
| 6 | 
            +
                "application/x-javascript",
         | 
| 7 | 
            +
                "text/javascript",
         | 
| 8 | 
            +
                "text/x-javascript",
         | 
| 9 | 
            +
                "text/x-json",
         | 
| 10 | 
            +
              ]
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              JSON_PARSER = proc do |io|
         | 
| 13 | 
            +
                begin
         | 
| 14 | 
            +
                  ::JSON.load(io)
         | 
| 15 | 
            +
                rescue ::JSON::ParserError => ex
         | 
| 16 | 
            +
                  rr = Rack::Response.new
         | 
| 17 | 
            +
                  rr.status = 400
         | 
| 18 | 
            +
                  rr.write(ex.message)
         | 
| 19 | 
            +
                  throw(:rack_response, rr)
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              def json(builder)
         | 
| 24 | 
            +
                require "json"
         | 
| 25 | 
            +
                JSON_CONTENT_TYPE.each do |content_type|
         | 
| 26 | 
            +
                  builder.on(content_type, &JSON_PARSER)
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              # CSV_CONTENT_TYPE = [
         | 
| 31 | 
            +
              #   "text/comma-separated-values",
         | 
| 32 | 
            +
              #   "application/csv",
         | 
| 33 | 
            +
              #   "text/csv",
         | 
| 34 | 
            +
              # ]
         | 
| 35 | 
            +
              #
         | 
| 36 | 
            +
              # CSV_PARSER = proc do |io|
         | 
| 37 | 
            +
              #   CSV.parse(io.read)
         | 
| 38 | 
            +
              # end
         | 
| 39 | 
            +
              #
         | 
| 40 | 
            +
              # def csv(builder)
         | 
| 41 | 
            +
              #   require "csv"
         | 
| 42 | 
            +
              #   CSV_CONTENT_TYPE.each do |content_type|
         | 
| 43 | 
            +
              #     builder.on(content_type, &CSV_PARSER)
         | 
| 44 | 
            +
              #   end
         | 
| 45 | 
            +
              # rescue LoadError
         | 
| 46 | 
            +
              # end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              FORM_CONTENT_TYPES = [
         | 
| 49 | 
            +
                'application/x-www-form-urlencoded',
         | 
| 50 | 
            +
                # 'multipart/form-data'
         | 
| 51 | 
            +
              ].freeze
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              FORM_SEP_CHAR = '&'.freeze
         | 
| 54 | 
            +
             | 
| 55 | 
            +
              RACK_QUERY_PARSER = if Rack::Utils.respond_to?(:default_query_parser)
         | 
| 56 | 
            +
                lambda do |form|
         | 
| 57 | 
            +
                  ::Rack::Utils.default_query_parser.parse_nested_query(form, FORM_SEP_CHAR)
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
              else
         | 
| 60 | 
            +
                lambda do |form|
         | 
| 61 | 
            +
                  ::Rack::Utils.parse_nested_query(form, FORM_SEP_CHAR)
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
              NULL_END_CHAR = /#{"\u0000"}$/
         | 
| 66 | 
            +
             | 
| 67 | 
            +
              FORM_PARSER = proc do |io|
         | 
| 68 | 
            +
                form_vars = io.read
         | 
| 69 | 
            +
                # Fix for Safari Ajax postings that always append \0
         | 
| 70 | 
            +
                form_vars.slice!(NULL_END_CHAR)
         | 
| 71 | 
            +
                RACK_QUERY_PARSER.call(form_vars)
         | 
| 72 | 
            +
              end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
              def www_form_urlencoded(builder)
         | 
| 75 | 
            +
                FORM_CONTENT_TYPES.each do |content_type|
         | 
| 76 | 
            +
                  builder.on(content_type, &FORM_PARSER)
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
              alias form www_form_urlencoded
         | 
| 81 | 
            +
              alias urlencoded www_form_urlencoded
         | 
| 82 | 
            +
             | 
| 83 | 
            +
              def accept(builder, *form_names)
         | 
| 84 | 
            +
                last_name = nil
         | 
| 85 | 
            +
                form_names.map(&:to_sym).each do |form_name|
         | 
| 86 | 
            +
                  last_name = form_name
         | 
| 87 | 
            +
                  __send__ form_name, builder
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
              rescue NoMethodError
         | 
| 90 | 
            +
                raise(NotImplementedError, "unknown formatter: #{last_name}")
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
            end
         | 
| @@ -0,0 +1,39 @@ | |
| 1 | 
            +
            class Rack::App::Payload::Parser::Builder
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              require "rack/app/payload/parser/builder/formats"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              def initialize
         | 
| 6 | 
            +
                @parsers = {}
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              def to_parser
         | 
| 10 | 
            +
                Rack::App::Payload::Parser.new(@parsers)
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              def on(content_type, &parser)
         | 
| 14 | 
            +
                @parsers[content_type]= parser
         | 
| 15 | 
            +
                self
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              def accept(*formats)
         | 
| 19 | 
            +
                Rack::App::Payload::Parser::Builder::Formats.accept(self, *formats)
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              # def reject_unsupported_media_types
         | 
| 23 | 
            +
              #   reject = proc do
         | 
| 24 | 
            +
              #     rr = Rack::Response.new
         | 
| 25 | 
            +
              #     rr.status = 415
         | 
| 26 | 
            +
              #     rr.write("Unsupported Media Type")
         | 
| 27 | 
            +
              #     throw(:rack_response, rr)
         | 
| 28 | 
            +
              #   end
         | 
| 29 | 
            +
              #   @parsers = Hash.new(reject).merge(@parsers)
         | 
| 30 | 
            +
              #   nil
         | 
| 31 | 
            +
              # end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              def merge!(parser_builder)
         | 
| 34 | 
            +
                raise unless parser_builder.is_a?(self.class)
         | 
| 35 | 
            +
                @parsers.merge!(parser_builder.instance_variable_get(:@parsers))
         | 
| 36 | 
            +
                self
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            require 'stringio'
         | 
| 2 | 
            +
            require 'rack/request'
         | 
| 3 | 
            +
            class Rack::App::Payload::Parser
         | 
| 4 | 
            +
              require 'rack/app/payload/parser/builder'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              DEFAULT_PARSER = proc { |io| io.read }
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              def initialize(content_type__parsers = {})
         | 
| 9 | 
            +
                raise unless content_type__parsers.is_a?(Hash)
         | 
| 10 | 
            +
                @content_type__parsers = Hash.new(DEFAULT_PARSER)
         | 
| 11 | 
            +
                @content_type__parsers.merge!(content_type__parsers)
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              def parse_io(content_type, io)
         | 
| 15 | 
            +
                @content_type__parsers[content_type.to_s].call(io)
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              def parse_env(env)
         | 
| 19 | 
            +
                request = Rack::Request.new(env)
         | 
| 20 | 
            +
                parse_io(request.content_type, request.body)
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              def parse_string(content_type, str)
         | 
| 24 | 
            +
                parse_io(content_type, StringIO.new(str))
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
    
        data/lib/rack/app/serializer.rb
    CHANGED
    
    | @@ -22,8 +22,6 @@ class Rack::App::Serializer | |
| 22 22 | 
             
                String(@formatters[extname].call(object))
         | 
| 23 23 | 
             
              end
         | 
| 24 24 |  | 
| 25 | 
            -
              CONTENT_TYPE = ::Rack::App::Constants::HTTP::Headers::CONTENT_TYPE
         | 
| 26 | 
            -
             | 
| 27 25 | 
             
              def response_headers_for(extname)
         | 
| 28 26 | 
             
                headers = {}
         | 
| 29 27 | 
             
                add_content_type_for(headers, extname)
         | 
| @@ -45,6 +43,8 @@ class Rack::App::Serializer | |
| 45 43 |  | 
| 46 44 | 
             
              protected
         | 
| 47 45 |  | 
| 46 | 
            +
              CONTENT_TYPE = ::Rack::App::Constants::HTTP::Headers::CONTENT_TYPE
         | 
| 47 | 
            +
             | 
| 48 48 | 
             
              def add_content_type_for(headers, extname)
         | 
| 49 49 | 
             
                content_type = @content_types[extname]
         | 
| 50 50 | 
             
                if content_type
         | 
| @@ -1,17 +1,15 @@ | |
| 1 1 | 
             
            module Rack::App::SingletonMethods::Formats
         | 
| 2 | 
            -
             | 
| 3 2 | 
             
              def formats(&descriptor)
         | 
| 4 3 | 
             
                @formats_builder ||= Rack::App::Serializer::FormatsBuilder.new
         | 
| 5 4 | 
             
                unless descriptor.nil?
         | 
| 6 5 | 
             
                  @formats_builder.instance_exec(&descriptor)
         | 
| 7 | 
            -
                  router.reset | 
| 6 | 
            +
                  router.reset
         | 
| 8 7 | 
             
                end
         | 
| 9 8 | 
             
                @formats_builder
         | 
| 10 9 | 
             
              end
         | 
| 11 10 |  | 
| 12 | 
            -
              def serializer(default_content_type=nil, &how_to_serialize)
         | 
| 13 | 
            -
                formats{ default(default_content_type | 
| 14 | 
            -
                 | 
| 11 | 
            +
              def serializer(default_content_type = nil, &how_to_serialize)
         | 
| 12 | 
            +
                formats { default(default_content_type, &how_to_serialize) } unless how_to_serialize.nil?
         | 
| 13 | 
            +
                formats.to_serializer
         | 
| 15 14 | 
             
              end
         | 
| 16 | 
            -
             | 
| 17 15 | 
             
            end
         | 
| @@ -0,0 +1,12 @@ | |
| 1 | 
            +
            module Rack::App::SingletonMethods::Payload
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              def payload(&block)
         | 
| 4 | 
            +
                unless @payload_builder
         | 
| 5 | 
            +
                  @payload_builder = Rack::App::Payload::Builder.new
         | 
| 6 | 
            +
                  use(Rack::App::Middlewares::Payload::ParserSetter, @payload_builder)
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
                @payload_builder.instance_exec(&block) if block
         | 
| 9 | 
            +
                nil 
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            end
         | 
| @@ -1,26 +1,28 @@ | |
| 1 1 | 
             
            module Rack::App::SingletonMethods
         | 
| 2 2 |  | 
| 3 | 
            +
              require 'rack/app/singleton_methods/params_validator'
         | 
| 4 | 
            +
              require 'rack/app/singleton_methods/rack_interface'
         | 
| 5 | 
            +
              require 'rack/app/singleton_methods/route_handling'
         | 
| 3 6 | 
             
              require 'rack/app/singleton_methods/http_methods'
         | 
| 4 7 | 
             
              require 'rack/app/singleton_methods/inheritance'
         | 
| 5 8 | 
             
              require 'rack/app/singleton_methods/middleware'
         | 
| 9 | 
            +
              require 'rack/app/singleton_methods/extensions'
         | 
| 6 10 | 
             
              require 'rack/app/singleton_methods/mounting'
         | 
| 7 | 
            -
              require 'rack/app/singleton_methods/params_validator'
         | 
| 8 | 
            -
              require 'rack/app/singleton_methods/rack_interface'
         | 
| 9 | 
            -
              require 'rack/app/singleton_methods/route_handling'
         | 
| 10 11 | 
             
              require 'rack/app/singleton_methods/settings'
         | 
| 11 | 
            -
              require 'rack/app/singleton_methods/ | 
| 12 | 
            +
              require 'rack/app/singleton_methods/payload'
         | 
| 12 13 | 
             
              require 'rack/app/singleton_methods/formats'
         | 
| 13 14 | 
             
              require 'rack/app/singleton_methods/hooks'
         | 
| 14 15 |  | 
| 16 | 
            +
              include Rack::App::SingletonMethods::ParamsValidator
         | 
| 17 | 
            +
              include Rack::App::SingletonMethods::RackInterface
         | 
| 18 | 
            +
              include Rack::App::SingletonMethods::RouteHandling
         | 
| 15 19 | 
             
              include Rack::App::SingletonMethods::HttpMethods
         | 
| 16 20 | 
             
              include Rack::App::SingletonMethods::Inheritance
         | 
| 21 | 
            +
              include Rack::App::SingletonMethods::Extensions
         | 
| 17 22 | 
             
              include Rack::App::SingletonMethods::Middleware
         | 
| 18 23 | 
             
              include Rack::App::SingletonMethods::Mounting
         | 
| 19 | 
            -
              include Rack::App::SingletonMethods::ParamsValidator
         | 
| 20 | 
            -
              include Rack::App::SingletonMethods::RackInterface
         | 
| 21 | 
            -
              include Rack::App::SingletonMethods::RouteHandling
         | 
| 22 24 | 
             
              include Rack::App::SingletonMethods::Settings
         | 
| 23 | 
            -
              include Rack::App::SingletonMethods:: | 
| 25 | 
            +
              include Rack::App::SingletonMethods::Payload
         | 
| 24 26 | 
             
              include Rack::App::SingletonMethods::Formats
         | 
| 25 27 | 
             
              include Rack::App::SingletonMethods::Hooks
         | 
| 26 28 |  | 
    
        data/lib/rack/app.rb
    CHANGED
    
    
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            require 'benchmark'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            TEST_AMOUNT = 2_000_000
         | 
| 4 | 
            +
            Benchmark.bm(15) do |x|
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              rgx = /\0\z/
         | 
| 7 | 
            +
              x.report('sub! + rgx') do
         | 
| 8 | 
            +
                TEST_AMOUNT.times do
         | 
| 9 | 
            +
                  str = "hello\0"
         | 
| 10 | 
            +
                  str.sub!(rgx, '')
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              x.report('slice! + rgx') do
         | 
| 15 | 
            +
                TEST_AMOUNT.times do
         | 
| 16 | 
            +
                  str = "hello\0"
         | 
| 17 | 
            +
                  str.slice!(rgx)
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              end_char = ?\0
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              x.report('slice! + int + if') do
         | 
| 24 | 
            +
                TEST_AMOUNT.times do
         | 
| 25 | 
            +
                  str = "hello\0"
         | 
| 26 | 
            +
                  str.slice!(-1) if str[-1] == end_char
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            end
         | 
| @@ -0,0 +1,94 @@ | |
| 1 | 
            +
            o = Object.new
         | 
| 2 | 
            +
            ms = o.methods
         | 
| 3 | 
            +
            require "minitest"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            block = proc do |payload|
         | 
| 6 | 
            +
              assert_kind_of(Array, payload, 'Payload should be a collection')
         | 
| 7 | 
            +
              payload.each do |element|
         | 
| 8 | 
            +
                assert_kind_of(Hash, element, 'Payload collection elements should be hashtables')
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                assert_includes(element.keys, 'hello', 'payload elements should has hello key')
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
            end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            good_payload = [
         | 
| 15 | 
            +
              {"hello" => "world1"},
         | 
| 16 | 
            +
              {"hello" => "world2"}
         | 
| 17 | 
            +
            ]
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            bad1_payload = [
         | 
| 20 | 
            +
              {"nope" => "world1"},
         | 
| 21 | 
            +
              {"hello" => "world2"}
         | 
| 22 | 
            +
            ]
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            bad2_payload = {"hello" => "world2"}
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            class Validator
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              include Minitest::Assertions
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              attr_accessor :assertions
         | 
| 31 | 
            +
              def initialize(&block)
         | 
| 32 | 
            +
                @assertions = 0
         | 
| 33 | 
            +
                singleton = class << self
         | 
| 34 | 
            +
                  self
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
                singleton.__send__(:define_method, :__tester__, &block)
         | 
| 37 | 
            +
                singleton.__send__(:protected, :__tester__)
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              def test(payload)
         | 
| 41 | 
            +
                __tester__(payload)
         | 
| 42 | 
            +
              rescue Minitest::Assertion => ex
         | 
| 43 | 
            +
                puts ex.message
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            class Documentation
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              def initialize(&block)
         | 
| 51 | 
            +
                @docs = []
         | 
| 52 | 
            +
                singleton = class << self
         | 
| 53 | 
            +
                  self
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
                singleton.__send__(:define_method, :__tester__, &block)
         | 
| 56 | 
            +
                singleton.__send__(:protected, :__tester__)
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              def to_doc
         | 
| 60 | 
            +
                o = Object.new
         | 
| 61 | 
            +
                def o.method_missing(*_)
         | 
| 62 | 
            +
                  self
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                def o.each(&block)
         | 
| 66 | 
            +
                  block.call(self)
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                def o.inspect
         | 
| 70 | 
            +
                  'element'
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
                __tester__(o)
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                @docs.join("\n")
         | 
| 75 | 
            +
              end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
              protected
         | 
| 78 | 
            +
             | 
| 79 | 
            +
              def method_missing(method_name,*args,&block)
         | 
| 80 | 
            +
                @docs << args.select{|arg| arg.is_a?(String) }.last
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
            end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
             | 
| 86 | 
            +
            puts Object.new.methods - ms # no output , no monkey patch than
         | 
| 87 | 
            +
             | 
| 88 | 
            +
            v = Validator.new(&block)
         | 
| 89 | 
            +
            v.test(good_payload)
         | 
| 90 | 
            +
            v.test(bad1_payload)
         | 
| 91 | 
            +
            v.test(bad2_payload)
         | 
| 92 | 
            +
             | 
| 93 | 
            +
            d = Documentation.new(&block)
         | 
| 94 | 
            +
            puts d.to_doc
         | 
    
        data/spike/xml.rb
    ADDED
    
    | @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            require 'net/http'
         | 
| 2 | 
            +
            require 'rexml/document'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            # Web search for "madonna"
         | 
| 5 | 
            +
            url = 'http://api.search.yahoo.com/WebSearchService/V1/webSearch?appid=YahooDemo&query=madonna&results=2'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            # get the XML data as a string
         | 
| 8 | 
            +
            xml_data = Net::HTTP.get_response(URI.parse(url)).body
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            # extract event information
         | 
| 11 | 
            +
            doc = REXML::Document.new(xml_data)
         | 
| 12 | 
            +
            titles = []
         | 
| 13 | 
            +
            links = []
         | 
| 14 | 
            +
            doc.elements.each('ResultSet/Result/Title') do |ele|
         | 
| 15 | 
            +
               titles << ele.text
         | 
| 16 | 
            +
            end
         | 
| 17 | 
            +
            doc.elements.each('ResultSet/Result/Url') do |ele|
         | 
| 18 | 
            +
               links << ele.text
         | 
| 19 | 
            +
            end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            # print all events
         | 
| 22 | 
            +
            titles.each_with_index do |title, idx|
         | 
| 23 | 
            +
               print "#{title} => #{links[idx]}\n"
         | 
| 24 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: rack-app
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 5. | 
| 4 | 
            +
              version: 5.7.0.rc
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Adam Luzsi
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2016- | 
| 11 | 
            +
            date: 2016-12-11 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| @@ -95,6 +95,7 @@ files: | |
| 95 95 | 
             
            - lib/rack/app.rb
         | 
| 96 96 | 
             
            - lib/rack/app/bundled_extensions.rb
         | 
| 97 97 | 
             
            - lib/rack/app/bundled_extensions/logger.rb
         | 
| 98 | 
            +
            - lib/rack/app/bundled_extensions/payload.rb
         | 
| 98 99 | 
             
            - lib/rack/app/cli.rb
         | 
| 99 100 | 
             
            - lib/rack/app/cli/command.rb
         | 
| 100 101 | 
             
            - lib/rack/app/cli/command/configurator.rb
         | 
| @@ -124,6 +125,7 @@ files: | |
| 124 125 | 
             
            - lib/rack/app/middlewares/configuration.rb
         | 
| 125 126 | 
             
            - lib/rack/app/middlewares/configuration/handler_setter.rb
         | 
| 126 127 | 
             
            - lib/rack/app/middlewares/configuration/path_params_matcher.rb
         | 
| 128 | 
            +
            - lib/rack/app/middlewares/configuration/payload_parser_setter.rb
         | 
| 127 129 | 
             
            - lib/rack/app/middlewares/configuration/serializer_setter.rb
         | 
| 128 130 | 
             
            - lib/rack/app/middlewares/header_setter.rb
         | 
| 129 131 | 
             
            - lib/rack/app/middlewares/hooks.rb
         | 
| @@ -137,7 +139,15 @@ files: | |
| 137 139 | 
             
            - lib/rack/app/middlewares/params/setter.rb
         | 
| 138 140 | 
             
            - lib/rack/app/middlewares/params/validator.rb
         | 
| 139 141 | 
             
            - lib/rack/app/middlewares/path_info_cutter.rb
         | 
| 142 | 
            +
            - lib/rack/app/middlewares/payload.rb
         | 
| 143 | 
            +
            - lib/rack/app/middlewares/payload/parser_setter.rb
         | 
| 144 | 
            +
            - lib/rack/app/middlewares/payload_parser_setter.rb
         | 
| 140 145 | 
             
            - lib/rack/app/params.rb
         | 
| 146 | 
            +
            - lib/rack/app/payload.rb
         | 
| 147 | 
            +
            - lib/rack/app/payload/builder.rb
         | 
| 148 | 
            +
            - lib/rack/app/payload/parser.rb
         | 
| 149 | 
            +
            - lib/rack/app/payload/parser/builder.rb
         | 
| 150 | 
            +
            - lib/rack/app/payload/parser/builder/formats.rb
         | 
| 141 151 | 
             
            - lib/rack/app/request_configurator.rb
         | 
| 142 152 | 
             
            - lib/rack/app/router.rb
         | 
| 143 153 | 
             
            - lib/rack/app/router/base.rb
         | 
| @@ -156,6 +166,7 @@ files: | |
| 156 166 | 
             
            - lib/rack/app/singleton_methods/middleware.rb
         | 
| 157 167 | 
             
            - lib/rack/app/singleton_methods/mounting.rb
         | 
| 158 168 | 
             
            - lib/rack/app/singleton_methods/params_validator.rb
         | 
| 169 | 
            +
            - lib/rack/app/singleton_methods/payload.rb
         | 
| 159 170 | 
             
            - lib/rack/app/singleton_methods/rack_interface.rb
         | 
| 160 171 | 
             
            - lib/rack/app/singleton_methods/route_handling.rb
         | 
| 161 172 | 
             
            - lib/rack/app/singleton_methods/settings.rb
         | 
| @@ -186,6 +197,9 @@ files: | |
| 186 197 | 
             
            - spike/method_vs_hash.rb
         | 
| 187 198 | 
             
            - spike/method_vs_instance_exec.rb
         | 
| 188 199 | 
             
            - spike/return_vs_throw.rb
         | 
| 200 | 
            +
            - spike/slice_vs_sub.rb
         | 
| 201 | 
            +
            - spike/validator_with_minitest.rb
         | 
| 202 | 
            +
            - spike/xml.rb
         | 
| 189 203 | 
             
            - src/Net__HTTP Cheat Sheet.pdf
         | 
| 190 204 | 
             
            homepage: http://www.rack-app.com/
         | 
| 191 205 | 
             
            licenses:
         | 
| @@ -202,9 +216,9 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 202 216 | 
             
                  version: '0'
         | 
| 203 217 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 204 218 | 
             
              requirements:
         | 
| 205 | 
            -
              - - " | 
| 219 | 
            +
              - - ">"
         | 
| 206 220 | 
             
                - !ruby/object:Gem::Version
         | 
| 207 | 
            -
                  version:  | 
| 221 | 
            +
                  version: 1.3.1
         | 
| 208 222 | 
             
            requirements: []
         | 
| 209 223 | 
             
            rubyforge_project: 
         | 
| 210 224 | 
             
            rubygems_version: 2.5.1
         |