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.



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

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
  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



70
71
72
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
# File 'lib/culpa.rb', line 70

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, take route decision and go !
  method_name, f_request = PathParser.extract_vars(env['PATH_INFO'], request)
  call_brickchain method_name, f_request
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