Class: AgileProxy::Route

Inherits:
Object
  • Object
show all
Defined in:
lib/agile_proxy/route.rb

Overview

An instance of this class represents a route within the system.

Constant Summary collapse

PATH_INFO =
'PATH_INFO'.freeze
ROUTE_PARAMS =
'rack.route_params'.freeze
QUERY_STRING =
'QUERY_STRING'.freeze
FORM_HASH =
'rack.request.form_hash'.freeze
REQUEST_METHOD =
'REQUEST_METHOD'.freeze
HEAD =
'HEAD'.freeze
GET =
'GET'.freeze
POST =
'POST'.freeze
PUT =
'PUT'.freeze
DELETE =
'DELETE'.freeze
DEFAULT_WILDCARD_NAME =
:paths
WILDCARD_PATTERN =
/\/\*(.*)/.freeze
NAMED_SEGMENTS_PATTERN =
/\/:([^$\/]+)/.freeze
NAMED_SEGMENTS_REPLACEMENT_PATTERN =
/\/:([^$\/]+)/.freeze
DOT =
'.'.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(request_method, pattern, app, options = {}) ⇒ Route

Returns a new instance of Route.



25
26
27
28
29
30
31
32
33
# File 'lib/agile_proxy/route.rb', line 25

def initialize(request_method, pattern, app, options = {})
  fail ArgumentError, 'pattern cannot be blank' if pattern.to_s.strip.empty?
  fail ArgumentError, 'app must be callable' unless app.respond_to?(:call)
  @request_method = request_method
  @pattern = pattern
  @app = app
  @constraints = options && options[:constraints]
  @name = options && options[:as]
end

Instance Attribute Details

#appObject

Returns the value of attribute app.



6
7
8
# File 'lib/agile_proxy/route.rb', line 6

def app
  @app
end

#constraintsObject

Returns the value of attribute constraints.



6
7
8
# File 'lib/agile_proxy/route.rb', line 6

def constraints
  @constraints
end

#nameObject

Returns the value of attribute name.



6
7
8
# File 'lib/agile_proxy/route.rb', line 6

def name
  @name
end

#patternObject

Returns the value of attribute pattern.



6
7
8
# File 'lib/agile_proxy/route.rb', line 6

def pattern
  @pattern
end

#request_methodObject

Returns the value of attribute request_method.



6
7
8
# File 'lib/agile_proxy/route.rb', line 6

def request_method
  @request_method
end

Instance Method Details

#compileObject



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/agile_proxy/route.rb', line 39

def compile
  pattern_match = pattern.match(WILDCARD_PATTERN)
  src = if pattern_match
          @wildcard_name = if pattern_match[1].to_s.strip.empty?
                             DEFAULT_WILDCARD_NAME
                           else
                             pattern_match[1].to_sym
                           end
          pattern.gsub(WILDCARD_PATTERN, '(?:/(.*)|)')
        else
          pattern_match = pattern.match(NAMED_SEGMENTS_PATTERN)
          p = if pattern_match
                pattern.gsub(NAMED_SEGMENTS_REPLACEMENT_PATTERN, '/(?<\1>[^.$/]+)')
              else
                pattern
              end
          p + '(?:\.(?<format>.*))?'
        end
  Regexp.new("\\A#{src}\\Z")
end

#eql?(other) ⇒ Boolean Also known as: ==

Returns:

  • (Boolean)


92
93
94
95
96
97
98
# File 'lib/agile_proxy/route.rb', line 92

def eql?(other)
  other.is_a?(self.class) &&
    other.request_method == request_method &&
    other.pattern == pattern &&
    other.app == app &&
    other.constraints == constraints
end

#hashObject



102
103
104
# File 'lib/agile_proxy/route.rb', line 102

def hash
  request_method.hash ^ pattern.hash ^ app.hash ^ constraints.hash
end

#match(env) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/agile_proxy/route.rb', line 60

def match(env)
  request_method = env[REQUEST_METHOD]
  request_method = GET if request_method == HEAD
  path = env[PATH_INFO]
  qs = env[QUERY_STRING]
  return nil unless request_method == self.request_method
  fail ArgumentError, 'path is required' if path.to_s.strip.empty?
  path_match = path.match(regexp)
  return unless path_match
  params = if @wildcard_name
             { @wildcard_name => path_match[1].to_s.split('/') }
           else
             Hash[path_match.names.map(&:to_sym).zip(path_match.captures)]
           end
  params.merge!(::Rack::Utils.parse_nested_query(qs).symbolize_keys) unless qs.nil? || qs.empty?
  params.merge! env[FORM_HASH] if env.key? FORM_HASH
  params.delete(:format) if params.key?(:format) && params[:format].nil?

  params if meets_constraints(params)
end

#meets_constraints(params) ⇒ Object



81
82
83
84
85
86
87
88
89
90
# File 'lib/agile_proxy/route.rb', line 81

def meets_constraints(params)
  if constraints
    constraints.each do |param, constraint|
      unless params.symbolize_keys[param.to_sym].to_s.match(constraint)
        return false
      end
    end
  end
  true
end

#regexpObject



35
36
37
# File 'lib/agile_proxy/route.rb', line 35

def regexp
  @regexp ||= compile
end