diff --git a/app/controllers/tests_controller.rb b/app/controllers/tests_controller.rb index 1526a689..42198aba 100644 --- a/app/controllers/tests_controller.rb +++ b/app/controllers/tests_controller.rb @@ -2,10 +2,10 @@ class TestsController < Simpler::Controller def index @time = Time.now + render 'tests/index' end def create - end end diff --git a/config.ru b/config.ru index 3060cc20..95c42b75 100644 --- a/config.ru +++ b/config.ru @@ -1,3 +1,5 @@ require_relative 'config/environment' +require_relative 'lib/middleware/logger' +use LoggerApp, log: File.expand_path('log/app.log', __dir__) run Simpler.application diff --git a/config/routes.rb b/config/routes.rb index 4a751251..6898f509 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,4 @@ Simpler.application.routes do - get '/tests', 'tests#index' + get '/tests/:id', 'tests#index' post '/tests', 'tests#create' end diff --git a/lib/middleware/logger.rb b/lib/middleware/logger.rb new file mode 100644 index 00000000..19479b54 --- /dev/null +++ b/lib/middleware/logger.rb @@ -0,0 +1,34 @@ +require 'logger' + +class LoggerApp + def initialize(app, **options) + @logger = Logger.new(options[:log]) + @app = app + end + + def call(env) + status, headers, response = @app.call(env) + @logger.info(log_struct(env)) + [status, headers, response] + end + + private + + def log_struct(env) + request_method = env['REQUEST_METHOD'] + request_path = env['PATH_INFO'] + header_content_type = env['simpler.controller'].response.headers['Content-Type'] + template = env['simpler.template'] + controller = env['simpler.controller'].class + action = env['simpler.action'] + request_params = env['simpler.controller'].request.params + response_status = env['simpler.controller'].response.status + + <<~LOG_STRUCT + \nRequest: #{request_method} #{request_path} + Handler: #{controller}##{action} + Parameters: #{request_params} + Response: #{response_status} [#{header_content_type}] #{template} + LOG_STRUCT + end +end diff --git a/lib/simpler/application.rb b/lib/simpler/application.rb index 711946a9..8dec8ec8 100644 --- a/lib/simpler/application.rb +++ b/lib/simpler/application.rb @@ -28,7 +28,15 @@ def routes(&block) def call(env) route = @router.route_for(env) + + return [404, {'Content-Type' => 'text/plain'}, ['Path not found']] unless route + + env['simpler.key_path_param'] = route.path_param if route.path_param + + @router.set_value_path_param(env, route.path) if route.path_param + controller = route.controller.new(env) + action = route.action make_response(controller, action) diff --git a/lib/simpler/controller.rb b/lib/simpler/controller.rb index 9383b035..46ead5d7 100644 --- a/lib/simpler/controller.rb +++ b/lib/simpler/controller.rb @@ -1,9 +1,10 @@ require_relative 'view' - +require 'byebug' module Simpler class Controller + PLAIN_TEXT_CONTENT_TYPE = "text/plain".freeze - attr_reader :name, :request, :response + attr_reader :name, :request, :response, :params def initialize(env) @name = extract_name @@ -15,6 +16,7 @@ def make_response(action) @request.env['simpler.controller'] = self @request.env['simpler.action'] = action + set_params set_default_headers send(action) write_response @@ -22,6 +24,10 @@ def make_response(action) @response.finish end + def params + @request.params + end + private def extract_name @@ -33,21 +39,48 @@ def set_default_headers end def write_response - body = render_body + unless content_type_text_plain? + body = render_body - @response.write(body) + @response.write(body) + end end def render_body View.new(@request.env).render(binding) end - def params - @request.params + def set_params + key_param = @request.env['simpler.key_path_param'] + value_param = @request.env['simpler.value_path_param'] + + if key_param && value_param + @request.params[key_param] = value_param + end + end + + def render(template = nil, **options) + if options.has_key?(:plain) + @response['Content-Type'] = 'text/plain' + + plain_text = options[:plain] + + @response.body = [plain_text] + else + @request.env['simpler.template'] = template + end + end + + def status(code) + @response.status = code + end + + def headers + @response.headers end - def render(template) - @request.env['simpler.template'] = template + def content_type_text_plain? + @response['Content-Type'] == PLAIN_TEXT_CONTENT_TYPE end end diff --git a/lib/simpler/router.rb b/lib/simpler/router.rb index 14b3415c..236af4ad 100644 --- a/lib/simpler/router.rb +++ b/lib/simpler/router.rb @@ -22,17 +22,35 @@ def route_for(env) @routes.find { |route| route.match?(method, path) } end + def set_value_path_param(env, path) + value = env['PATH_INFO'].match(path).post_match + + env['simpler.value_path_param'] = value + end + private def add_route(method, path, route_point) route_point = route_point.split('#') + + path_route, path_param = split_param_from_path(path) + controller = controller_from_string(route_point[0]) + action = route_point[1] - route = Route.new(method, path, controller, action) + + route = Route.new(method, path_route, controller, action, path_param) @routes.push(route) end + def split_param_from_path(path) + path_route = path.match(":")&.pre_match || path + path_param = path.match(":")&.post_match || nil + + [path_route, path_param] + end + def controller_from_string(controller_name) Object.const_get("#{controller_name.capitalize}Controller") end diff --git a/lib/simpler/router/route.rb b/lib/simpler/router/route.rb index 4c66b4b7..bb0831a6 100644 --- a/lib/simpler/router/route.rb +++ b/lib/simpler/router/route.rb @@ -2,13 +2,14 @@ module Simpler class Router class Route - attr_reader :controller, :action + attr_reader :controller, :action, :path_param, :path - def initialize(method, path, controller, action) + def initialize(method, path, controller, action, path_param = nil) @method = method @path = path @controller = controller @action = action + @path_param = path_param end def match?(method, path) diff --git a/log/app.log b/log/app.log new file mode 100644 index 00000000..ae3a5968 --- /dev/null +++ b/log/app.log @@ -0,0 +1,13 @@ +# Logfile created on 2025-04-19 23:25:38 +0300 by logger.rb/v1.7.0 +I, [2025-04-19T23:25:42.834972 #21015] INFO -- : +Request: GET /tests/100 +Handler: TestsController#index +Parameters: {"id"=>"100"} +Response: 200 text/html tests/index + +I, [2025-04-19T23:31:39.878967 #21788] INFO -- : +Request: GET /tests/100 +Handler: TestsController#index +Parameters: {"id"=>"100"} +Response: 200 [text/html] tests/index +