diff --git a/app/controllers/tests_controller.rb b/app/controllers/tests_controller.rb index 1526a689..8e7f93f1 100644 --- a/app/controllers/tests_controller.rb +++ b/app/controllers/tests_controller.rb @@ -2,10 +2,19 @@ class TestsController < Simpler::Controller def index @time = Time.now + render 'tests/index' + status 201 + headers['Content-Type'] = 'text/plain' end def create end + def show + @test_id = params[:id] + @time = Time.now + render 'tests/show' + end + end diff --git a/app/views/tests/index.html.erb b/app/views/tests/index.html.erb index 39fce580..0915cef4 100644 --- a/app/views/tests/index.html.erb +++ b/app/views/tests/index.html.erb @@ -9,4 +9,4 @@

<%= @time %>

- \ No newline at end of file + diff --git a/app/views/tests/show.html.erb b/app/views/tests/show.html.erb new file mode 100644 index 00000000..91c52e54 --- /dev/null +++ b/app/views/tests/show.html.erb @@ -0,0 +1,12 @@ + + + + + Show | Simpler application + + +

Simpler framework at work!

+ +

<%= @test_id %>

+ + diff --git a/config.ru b/config.ru index 3060cc20..9a6e0ec2 100644 --- a/config.ru +++ b/config.ru @@ -1,3 +1,5 @@ +require_relative 'middleware/custom_logger' require_relative 'config/environment' +use CustomLogger, logdev: File.expand_path('log/app.log', __dir__) run Simpler.application diff --git a/config/routes.rb b/config/routes.rb index 4a751251..1700ff3a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Simpler.application.routes do get '/tests', 'tests#index' post '/tests', 'tests#create' + get '/tests/:id', 'tests#show' end diff --git a/lib/simpler/application.rb b/lib/simpler/application.rb index 711946a9..2daf4b02 100644 --- a/lib/simpler/application.rb +++ b/lib/simpler/application.rb @@ -28,14 +28,23 @@ def routes(&block) def call(env) route = @router.route_for(env) - controller = route.controller.new(env) - action = route.action - make_response(controller, action) + if route + controller = route.controller.new(env) + action = route.action + + make_response(controller, action) + else + not_found_response + end end private + def not_found_response + [404, {'Content-Type' => 'text/plain'}, ['Not found (404 Error)']] + end + def require_app Dir["#{Simpler.root}/app/**/*.rb"].each { |file| require file } end diff --git a/lib/simpler/controller.rb b/lib/simpler/controller.rb index 9383b035..682c93ee 100644 --- a/lib/simpler/controller.rb +++ b/lib/simpler/controller.rb @@ -3,7 +3,7 @@ module Simpler class Controller - attr_reader :name, :request, :response + attr_reader :name, :request, :response, :status def initialize(env) @name = extract_name @@ -16,6 +16,7 @@ def make_response(action) @request.env['simpler.action'] = action set_default_headers + set_default_status send(action) write_response @@ -28,12 +29,26 @@ def extract_name self.class.name.match('(?.+)Controller')[:name].downcase end + def set_default_status + status 200 + end + + def status(code) + @response.status = code + end + def set_default_headers - @response['Content-Type'] = 'text/html' + headers['Content-Type'] = 'text/html' + end + + def headers + @response.headers end def write_response body = render_body + @request.env['simpler.response.status'] = @response.status + @request.env['simpler.response.header'] = headers['Content-Type'] @response.write(body) end @@ -43,11 +58,11 @@ def render_body end def params - @request.params + @request.env['simpler.params'].merge!(@request.params) end - def render(template) - @request.env['simpler.template'] = template + def render(template) + @request.env['simpler.template'] = template end end diff --git a/lib/simpler/router.rb b/lib/simpler/router.rb index 14b3415c..835726ff 100644 --- a/lib/simpler/router.rb +++ b/lib/simpler/router.rb @@ -19,7 +19,7 @@ def route_for(env) method = env['REQUEST_METHOD'].downcase.to_sym path = env['PATH_INFO'] - @routes.find { |route| route.match?(method, path) } + @routes.find { |route| route.match?(method, path, env) } end private diff --git a/lib/simpler/router/route.rb b/lib/simpler/router/route.rb index 4c66b4b7..bbff331d 100644 --- a/lib/simpler/router/route.rb +++ b/lib/simpler/router/route.rb @@ -11,8 +11,30 @@ def initialize(method, path, controller, action) @action = action end - def match?(method, path) - @method == method && path.match(@path) + def match?(method, path, env) + @method == method && parse_path(path, env) + end + + private + + def parse_path(path, env) + params = {} + router_parts = @path.split('/') + request_parts = path.split('/') + + return false if router_parts.size != request_parts.size + + router_parts.each_index do |index| + unless router_parts[index] == request_parts[index] + match_data = router_parts[index].match(/^:(.+)/) + + return false if match_data.nil? + + params[match_data[1].to_sym] = request_parts[index] + end + end + + env['simpler.params'] = params end end diff --git a/lib/simpler/view.rb b/lib/simpler/view.rb index 19a73b34..24aa0700 100644 --- a/lib/simpler/view.rb +++ b/lib/simpler/view.rb @@ -10,9 +10,13 @@ def initialize(env) end def render(binding) - template = File.read(template_path) + if template.is_a?(Hash) + template[:plain] + else + template = File.read(template_path) - ERB.new(template).result(binding) + ERB.new(template).result(binding) + end end private diff --git a/log/app.log b/log/app.log new file mode 100644 index 00000000..ccd4997c --- /dev/null +++ b/log/app.log @@ -0,0 +1,64 @@ +I, [2023-10-01T20:28:44.252388 #6864] INFO -- : +******************************************************** +Request: GET /tests/1 +Handler: TestsController#show +Parameters: {:id=>"1"} +Response: 200 [text/html] tests/show + +I, [2023-10-01T20:28:50.838787 #6864] INFO -- : +******************************************************** +Request: GET /tests +Handler: TestsController#index +Parameters: {} +Response: 200 [text/html] tests/index + +I, [2023-10-02T19:01:22.890165 #2328] INFO -- : +Request: GET /favicon.ico +Response: + +I, [2023-10-02T19:02:26.432485 #2370] INFO -- : +******************************************************** +Request: GET /tests +Handler: TestsController#index +Parameters: {} +Response: 201 [text/html] tests/index + +I, [2023-10-02T19:02:28.887108 #2370] INFO -- : +******************************************************** +Request: GET /tests/1 +Handler: TestsController#show +Parameters: {:id=>"1"} +Response: 200 [text/html] tests/show + +I, [2023-10-02T19:02:31.419626 #2370] INFO -- : +Request: GET /tests/1/2 +Response: + +I, [2023-10-02T19:02:46.355274 #2370] INFO -- : +******************************************************** +Request: GET /tests/1 +Handler: TestsController#show +Parameters: {:id=>"1"} +Response: 200 [text/html] tests/show + +I, [2023-10-02T19:02:46.821204 #2370] INFO -- : +******************************************************** +Request: GET /tests/ +Handler: TestsController#index +Parameters: {} +Response: 201 [text/html] tests/index + +I, [2023-10-02T19:03:17.334902 #2528] INFO -- : +******************************************************** +Request: GET /tests/ +Handler: TestsController#index +Parameters: {} +Response: 201 [text/plain] tests/index + +I, [2023-10-02T19:03:55.068058 #2559] INFO -- : +******************************************************** +Request: GET /tests/ +Handler: TestsController#index +Parameters: {} +Response: 201 [text/html] {:plain=>"Plain text response"} + diff --git a/middleware/custom_logger.rb b/middleware/custom_logger.rb new file mode 100644 index 00000000..b0f74958 --- /dev/null +++ b/middleware/custom_logger.rb @@ -0,0 +1,36 @@ +require 'logger' + +class CustomLogger + + def initialize(app, **options) + @logger = Logger.new(options[:logdev] || STDOUT) + @app = app + end + + def call(env) + response = @app.call(env) + @logger.info(message(env)) + response + end + + def message(env) + controller = env['simpler.controller'] + + if controller + <<~LOGGER + + ******************************************************** + Request: #{env['REQUEST_METHOD']} #{env['PATH_INFO']} + Handler: #{controller.name.capitalize}Controller##{env['simpler.action']} + Parameters: #{env['simpler.params']} + Response: #{env['simpler.response.status']} [#{env['simpler.response.header']}] #{env['simpler.template']} + LOGGER + else + <<~LOGGER + + Request: #{env['REQUEST_METHOD']} #{env['PATH_INFO']} + Response: #{} + LOGGER + end + end +end