diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..7ccc842a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+# Ignore all logfiles
+/log/*
diff --git a/app/controllers/tests_controller.rb b/app/controllers/tests_controller.rb
index 900a415d..e8a132a2 100644
--- a/app/controllers/tests_controller.rb
+++ b/app/controllers/tests_controller.rb
@@ -1,19 +1,21 @@
class TestsController < Simpler::Controller
def index
@time = Time.now
+ render "tests/index"
end
def create
+ status 201
+ render plain: "Create method in action!"
end
def plain
- render plain: "plain_option_example"
- status 201
+ render plain: "Plain text responce example"
+ status 200
end
def show
@id = params[:id]
- render plain: "This is an object (show tests method) with id #{@id}"
end
def question
diff --git a/app/views/tests/show.html.erb b/app/views/tests/show.html.erb
new file mode 100644
index 00000000..694ab011
--- /dev/null
+++ b/app/views/tests/show.html.erb
@@ -0,0 +1,10 @@
+
+
+
+
+ Index | Simpler application
+
+
+ This is the test object (show tests method) with id <%= @id %>
+
+
diff --git a/config.ru b/config.ru
index 3060cc20..6beefaa0 100644
--- a/config.ru
+++ b/config.ru
@@ -1,3 +1,5 @@
-require_relative 'config/environment'
+require_relative "config/environment"
+require_relative "lib/simpler/middleware/logger"
+use Simpler::AppLogger, logdev: File.expand_path("log/app.log", Simpler.root)
run Simpler.application
diff --git a/lib/simpler/application.rb b/lib/simpler/application.rb
index fe8f2480..bba58164 100644
--- a/lib/simpler/application.rb
+++ b/lib/simpler/application.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "yaml"
require "singleton"
require "sequel"
@@ -27,7 +29,10 @@ def routes(&block)
def call(env)
route = @router.route_for(env)
+
return not_found unless route
+ return not_found unless route.params.empty? || db_route_params_exists?(route.params)
+
env["simpler.route_params"] = route.params
controller = route.controller.new(env)
action = route.action
@@ -38,7 +43,7 @@ def call(env)
private
def require_app
- Dir["#{Simpler.root}/app/**/*.rb"].each { |file| require file }
+ Dir["#{Simpler.root}/app/**/*.rb"].sort.each { |file| require file }
end
def require_routes
@@ -58,5 +63,12 @@ def make_response(controller, action)
def not_found
[404, { "Content-Type" => "text/plain" }, ["Not found"]]
end
+
+ def db_route_params_exists?(params)
+ corresponding_record = nil
+ params.each { |_param_name, param_value| corresponding_record = @db[:tests].first(id: param_value) }
+
+ !corresponding_record.nil?
+ end
end
end
diff --git a/lib/simpler/middleware/logger.rb b/lib/simpler/middleware/logger.rb
new file mode 100644
index 00000000..dcf995e3
--- /dev/null
+++ b/lib/simpler/middleware/logger.rb
@@ -0,0 +1,55 @@
+require "logger"
+
+module Simpler
+ class AppLogger
+ def initialize(app, **options)
+ @logger = Logger.new(options[:logdev] || STDOUT)
+ @app = app
+ end
+
+ def call(env)
+ @status, @header, @body = @app.call(env)
+ @request = Rack::Request.new(env)
+
+ @logger.info(create_log)
+
+ Rack::Response.new(@body, @status, @header).finish
+ end
+
+ private
+
+ def create_log
+ if @status == 404
+ %Q(
+ Request: #{@request.request_method} #{@request.fullpath}
+ Handler: Nil
+ Parameters: #{@request.params}
+ Response: #{full_status}
+ ).delete!("\n")
+ else
+ %Q(
+ Request: #{@request.request_method} #{@request.fullpath}
+ Handler: #{controller}##{action}
+ Parameters: #{@request.params}
+ Response: #{full_status} \[#{@header["Content-Type"]}\] #{view}
+ ).delete!("\n")
+ end
+ end
+
+ def controller
+ @request.env["simpler.controller"].class.name
+ end
+
+ def action
+ @request.env["simpler.action"]
+ end
+
+ def full_status
+ "#{@status}" + " #{Rack::Utils::HTTP_STATUS_CODES[@status]}"
+ end
+
+ def view
+ "#{@request.env["simpler.template"] || [controller, action].join("/")}.html.erb" unless @request.env["simpler.text_plain"]
+ end
+ end
+end
diff --git a/lib/simpler/router.rb b/lib/simpler/router.rb
index 14b3415c..77b7fdf6 100644
--- a/lib/simpler/router.rb
+++ b/lib/simpler/router.rb
@@ -1,8 +1,7 @@
-require_relative 'router/route'
+require_relative "router/route"
module Simpler
class Router
-
def initialize
@routes = []
end
@@ -16,8 +15,8 @@ def post(path, route_point)
end
def route_for(env)
- method = env['REQUEST_METHOD'].downcase.to_sym
- path = env['PATH_INFO']
+ method = env["REQUEST_METHOD"].downcase.to_sym
+ path = env["PATH_INFO"]
@routes.find { |route| route.match?(method, path) }
end
@@ -25,7 +24,7 @@ def route_for(env)
private
def add_route(method, path, route_point)
- route_point = route_point.split('#')
+ route_point = route_point.split("#")
controller = controller_from_string(route_point[0])
action = route_point[1]
route = Route.new(method, path, controller, action)
@@ -36,6 +35,5 @@ def add_route(method, path, route_point)
def controller_from_string(controller_name)
Object.const_get("#{controller_name.capitalize}Controller")
end
-
end
end
diff --git a/lib/simpler/router/route.rb b/lib/simpler/router/route.rb
index 157667c7..a3763dbd 100644
--- a/lib/simpler/router/route.rb
+++ b/lib/simpler/router/route.rb
@@ -16,8 +16,13 @@ def initialize(method, path, controller, action)
end
def match?(method, path)
- define_params(path)
- edited_path = define_edited_path(path) || path
+ @params = define_params(path)
+
+ edited_path = if @params.values.all? && (!@params.values.empty?)
+ define_edited_path(path)
+ else
+ path
+ end
@method == method && edited_path == @path
end
@@ -31,16 +36,15 @@ def define_params(path)
path.scan(ROUTE_PARAM_VALUE_REGEXP).each { |param| route_params_values << (param.delete "/") }
@path.scan(ROUTE_PARAM_NAME_REGEXP).each { |param| route_params_names << param.delete(":").delete("/").to_sym }
- @params = Hash[route_params_names.zip route_params_values]
+ Hash[route_params_names.zip route_params_values]
end
def define_edited_path(path)
- str = path
- @params.each do |param_name, param_value|
- str = str.gsub param_value, ":#{param_name.to_s}"
- end
+ edited_path = path
+
+ @params.each { |param_name, param_value| edited_path = edited_path.gsub param_value, ":#{param_name.to_s}" }
- str
+ edited_path
end
end
end
diff --git a/log/app.log b/log/app.log
new file mode 100644
index 00000000..aa4618e0
--- /dev/null
+++ b/log/app.log
@@ -0,0 +1,11 @@
+I, [2021-07-20T21:29:48.157677 #288091] INFO -- : Request: GET /tests/2 Handler: TestsController#show Parameters: {:id=>"2"} Response: 200 OK [text/html] TestsController/show.html.erb
+I, [2021-07-20T21:30:01.670387 #288091] INFO -- : Request: GET /tests/6 Handler: Nil Parameters: {} Response: 404 Not Found
+I, [2021-07-20T21:30:14.369278 #288091] INFO -- : Request: GET /tests/3/question/25?one=1 Handler: Nil Parameters: {"one"=>"1"} Response: 404 Not Found
+I, [2021-07-20T21:30:24.195654 #288091] INFO -- : Request: GET /tests Handler: TestsController#index Parameters: {} Response: 200 OK [text/html] tests/index.html.erb
+I, [2021-07-20T21:32:27.196093 #288333] INFO -- : Request: POST /tests Handler: TestsController#create Parameters: {} Response: 201 Created [text/plain]
+I, [2021-07-20T21:35:00.585388 #288333] INFO -- : Request: POST /tests Handler: TestsController#create Parameters: {} Response: 201 Created [text/plain]
+I, [2021-07-20T21:35:02.896432 #288333] INFO -- : Request: GET /tests Handler: TestsController#index Parameters: {} Response: 200 OK [text/html] tests/index.html.erb
+I, [2021-07-20T21:35:07.109826 #288333] INFO -- : Request: GET /tests/3/question/25?one=1 Handler: Nil Parameters: {"one"=>"1"} Response: 404 Not Found
+I, [2021-07-20T21:35:10.289813 #288333] INFO -- : Request: GET /tests/6 Handler: Nil Parameters: {} Response: 404 Not Found
+I, [2021-07-20T21:35:13.920833 #288333] INFO -- : Request: GET /tests/2 Handler: TestsController#show Parameters: {:id=>"2"} Response: 200 OK [text/html] TestsController/show.html.erb
+I, [2021-07-20T21:35:20.181146 #288333] INFO -- : Request: GET /tests/plain Handler: TestsController#plain Parameters: {} Response: 200 OK [text/plain]