Class: Jebanni::RequestHandler

Inherits:
Object
  • Object
show all
Includes:
Rack::Utils
Defined in:
lib/jebanni/request_handler.rb,
lib/jebanni/request_handler/processor.rb

Defined Under Namespace

Classes: Processor

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(request, server) ⇒ RequestHandler

Returns a new instance of RequestHandler.



21
22
23
24
# File 'lib/jebanni/request_handler.rb', line 21

def initialize(request, server)
  @request = request
  @server = server
end

Instance Attribute Details

#requestObject (readonly)

Returns the value of attribute request.



9
10
11
# File 'lib/jebanni/request_handler.rb', line 9

def request
  @request
end

#serverObject (readonly)

Returns the value of attribute server.



9
10
11
# File 'lib/jebanni/request_handler.rb', line 9

def server
  @server
end

Class Method Details

.register_route(verb, path, options = {}, &process) ⇒ Object



11
12
13
14
15
16
17
18
19
# File 'lib/jebanni/request_handler.rb', line 11

def self.register_route(verb, path, options = {}, &process)
  verb.downcase!
  @routes ||= {}
  @routes[verb] ||= []
  @routes[verb] << {
    matcher: Mustermann.new(path, options),
    process: process
  }
end

Instance Method Details

#find_routeObject



30
31
32
33
34
35
36
37
# File 'lib/jebanni/request_handler.rb', line 30

def find_route
  known = self.class.instance_variable_get(:@routes)
  found = known[request.method.downcase].find do |route|
    route[:matcher] === request.path
  end
  raise "not found" unless found
  found
end

#indiferrent_keys(hash) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
# File 'lib/jebanni/request_handler.rb', line 75

def indiferrent_keys(hash)
  # Either accessible params[:foo] or params["foo"]
  def hash.[](key)
    super(key.to_s) || begin
      # NOTE: Guard from DoS attack using Symbol:
      #       http://sequel.jeremyevans.net/2011/07/16/dangerous-reflection.html
      super(key.to_sym) if self.keys.map(&:to_s).include?(key.to_s)
    end
  end
  hash
end

#paramsObject



70
71
72
73
# File 'lib/jebanni/request_handler.rb', line 70

def params
  # NOTE: route params is prior than query params for don't accidentally override params with query
  indiferrent_keys request_params.merge(route_params)
end

#processorObject



39
40
41
42
43
44
45
46
47
48
# File 'lib/jebanni/request_handler.rb', line 39

def processor
  @processor ||=
    begin
      # Processor define class method internally, so avoid race condition for Class.new(Processor)
      processor = Class.new(Processor).new(self)
      processor.route = find_route
      processor.params = params
      processor
    end
end

#request_paramsObject



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/jebanni/request_handler.rb', line 50

def request_params
  query = parse_nested_query(request.query_string)
  return query if %w(get head options).include?(request.method.downcase)

  content_type = request.headers.find do |(key, _)|
    key.downcase == "content-type"
  end
  if content_type && content_type.last.downcase == "application/json"
    json_params = JSON.parse(request.body.to_s) rescue {}
    query.merge! json_params
  else
    query.merge! parse_nested_query(request.body.to_s)
  end
  query
end

#route!Object



26
27
28
# File 'lib/jebanni/request_handler.rb', line 26

def route!
  processor.response
end

#route_paramsObject



66
67
68
# File 'lib/jebanni/request_handler.rb', line 66

def route_params
  find_route[:matcher].params(request.path)
end