Class: Culpa::Application

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

Overview

This class is the one instancied by Rack.

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Application

Returns a new instance of Application.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/culpa.rb', line 51

def initialize(options = {})
  # Loading brickchains definitions and the associated routes
  bc_path = options[:brickchains] || './config/brickchains.rb'
  route_builder = RoutesBuilder.new(File.read(bc_path))
  @router = route_builder.result
  # Loads configuration file
  @configuration = YAML.load_file(options[:config] || './config/config.yml')
  PathParser.create_route_cache(@router, route_builder.prefix || '')
  # Setting static file directory
  @public_folder = options[:public] || route_builder.public_folder || './public'
  # Loading renderers
  Action.load_renderers
  # Loading logger
  logger_initialize(options[:log_output] || STDOUT)
  # If in dev or test env, serve the static assets
  if %w(development test).include? ENV['RACK_ENV']
    @rack_file = Rack::File.new(@public_folder)
  end
end

Instance Method Details

#call(env) ⇒ Object

Rack entrypoint



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/culpa.rb', line 73

def call(env)
  # Checking if it is a static file before calling the router
  if @rack_file
    static_asset = try_static_asset(env)
    return static_asset if static_asset
  end
  # Calling the router
  @logger.info "Received request : #{env['PATH_INFO']}"
  # Request preparation
  request = {
    verb: env['REQUEST_METHOD'].downcase.to_sym,
    params: Rack::Utils.parse_nested_query(env['QUERY_STRING'])
  }
  # Parse body if in JSON, otherwise pass the rack.input directly
  if env['CONTENT_TYPE'] == 'application/json'
    body = MultiJson.load(env['rack.input'].read)
    request[:input] = if body.key?('data')
                        body['data']
                      else
                        body
                      end
    request[:params]['sub_call'] = body['sub_call'] if body.key? 'sub_call'
  else
    request[:input] = env['rack.input']
  end
  # Extract vars from path, creates session object, take route decision and go !
  session_id = env.has_key?('HTTP_X_SESSION_ID') ? env['HTTP_X_SESSION_ID'] : nil
  session_obj = if @configuration.has_key? 'session'
    Session.new(@configuration['session']['driver'],
                @configuration['session']['configuration'],
                session_id)
  else
    Session.new('InMemory', {'duration' => 600}, session_id)
  end
  method_name, f_request = PathParser.extract_vars(env['PATH_INFO'], request)
  call_brickchain method_name, f_request, session_obj
rescue UnpredictableSubCallError, MultiJson::ParseError
  # The sub_call wasn't predictacle, or the body wans't correct JSON.
  # In both cases, it is a bad_request.
  rack_error 400
rescue RouteNotFoundError => err
  # The good old 404 not found
  @logger.info "Route not found : #{env['PATH_INFO']}"
  rack_error 404
rescue StandardError => err
  # Something went wrong executing the chain !
  if ENV['RACK_ENV'] != 'test'
    # :nocov:
    @logger.error "#{err}\n#{err.backtrace.join("\n")}"
    # :nocov:
  end
  rack_error 500
end