lib/httpimagestore/configuration/handler.rb in httpimagestore-1.4.1 vs lib/httpimagestore/configuration/handler.rb in httpimagestore-1.5.0

- old
+ new

@@ -64,16 +64,15 @@ super() do |request_state, name| # note that request_state may be different object when useing with_locals that creates duplicate request_state[name] = request_state.generate_meta_variable(name) or raise VariableNotDefinedError.new(name) end - merge! query_string self[:path] = path merge! matches self[:query_string_options] = query_string.sort.map{|kv| kv.join(':')}.join(',') - log.debug "processing request with body length: #{body.bytesize} bytes and variables: #{self} " + log.debug "processing request with body length: #{body.bytesize} bytes and variables: #{map{|k,v| "#{k}: '#{v}'"}.join(', ')}" @body = body @images = Images.new(memory_limit) @memory_limit = memory_limit @output_callback = nil @@ -175,18 +174,10 @@ request_state.body.empty? and raise ZeroBodyLengthError request_state.images['input'] = Image.new(request_state.body) end end - class OutputOK - def realize(request_state) - request_state.output do - write_plain 200, 'OK' - end - end - end - class InclusionMatcher def initialize(value, template) @value = value @template = RubyStringTemplate.new(template) if template end @@ -257,17 +248,32 @@ yield @image_name, image, rendered_path end end class Matcher - def initialize(name, &matcher) - @name = name + def initialize(names, debug_type = '', debug_value = '', &matcher) + @names = names @matcher = matcher + @debug_type = debug_type + @debug_value = case debug_value + when Regexp + "/#{debug_value.source}/" + else + debug_value.inspect + end end - attr_reader :name + attr_reader :names attr_reader :matcher + + def to_s + if @names.empty? + "#{@debug_type}(#{@debug_value})" + else + "#{@debug_type}(#{@names.join(',')} => #{@debug_value})" + end + end end class Handler < Scope def self.match(node) node.name == 'put' or @@ -278,11 +284,11 @@ def self.pre(configuration) configuration.handlers ||= [] end def self.parse(configuration, node) - handler_configuration = + handler_configuration = Struct.new( :global, :http_method, :uri_matchers, :sources, @@ -293,48 +299,67 @@ handler_configuration.global = configuration handler_configuration.http_method = node.name handler_configuration.uri_matchers = node.values.map do |matcher| case matcher - # URI component matchers + # URI matchers when %r{^:([^/]+)/(.*)/$} # :foobar/.*/ - name = $1 - regexp = $2 - Matcher.new(name.to_sym) do - Regexp.new("(#{regexp})") + name = $1.to_sym + _regexp = Regexp.new($2) + regexp = Regexp.new("(#{$2})") + Matcher.new([name], 'Regexp', _regexp) do + regexp end + when %r{^/(.*)/$} # /.*/ + regexp = $1 + _regexp = Regexp.new($1) + names = Regexp.new($1).names.map{|n| n.to_sym} + Matcher.new(names, 'Regexp', _regexp) do + -> { + matchdata = env["PATH_INFO"].match(/\A\/(?<_match_>#{regexp})(?<_tail_>(?:\/|\z))/) + + next false unless matchdata + + path, *vars = matchdata.captures + + env["SCRIPT_NAME"] += "/#{path}" + env["PATH_INFO"] = "#{vars.pop}#{matchdata.post_match}" + + captures.push(*vars) + } + end when /^:(.+)\?(.*)$/ # :foo?bar name = $1.to_sym default = $2 - Matcher.new(name) do + Matcher.new([name], 'SegmentDefault', "<segment>|#{default}") do ->{match(name) || captures.push(default)} end when /^:(.+)$/ # :foobar name = $1.to_sym - Matcher.new(name) do + Matcher.new([name], 'Segment', '<segment>') do name end # Query string matchers when /^\&([^=]+)=(.+)$/# ?foo=bar - name = $1 + name = $1.to_sym value = $2 - Matcher.new(nil) do - ->{req[name] && req[name] == value} + Matcher.new([name], 'QueryKeyValue', "#{name}=#{value}") do + ->{req[name] && req[name] == value && captures.push(req[name])} end when /^\&:(.+)\?(.*)$/# &:foo?bar - name = $1 + name = $1.to_sym default = $2 - Matcher.new(name.to_sym) do + Matcher.new([name], 'QueryKeyDefault', "#{name}=<key>|#{default}") do ->{captures.push(req[name] || default)} end when /^\&:(.+)$/# &:foo - name = $1 - Matcher.new(name.to_sym) do + name = $1.to_sym + Matcher.new([name], 'QueryKey', "#{name}=<key>") do ->{req[name] && captures.push(req[name])} end - # String URI component matcher + # Literal URI segment matcher else # foobar - Matcher.new(nil) do + Matcher.new([], "Literal", matcher) do Regexp.escape(matcher) end end end handler_configuration.sources = []