From f7484d14d3ab9080d5ccd96a25153d17b3792dcc Mon Sep 17 00:00:00 2001 From: Sdogruyol Date: Sun, 17 Jul 2016 14:43:13 +0300 Subject: [PATCH] Use nested module declaration --- src/kemal/base_log_handler.cr | 18 ++--- src/kemal/common_log_handler.cr | 50 +++++++------- src/kemal/middleware/ssl.cr | 1 + src/kemal/null_log_handler.cr | 6 +- src/kemal/param_parser.cr | 112 ++++++++++++++++--------------- src/kemal/route.cr | 20 +++--- src/kemal/route_handler.cr | 89 ++++++++++++------------ src/kemal/static_file_handler.cr | 20 +++--- src/kemal/websocket_handler.cr | 20 +++--- 9 files changed, 176 insertions(+), 160 deletions(-) diff --git a/src/kemal/base_log_handler.cr b/src/kemal/base_log_handler.cr index 7e6f569..d13f29c 100644 --- a/src/kemal/base_log_handler.cr +++ b/src/kemal/base_log_handler.cr @@ -1,12 +1,14 @@ -# All loggers must inherit from `Kemal::BaseLogHandler`. -class Kemal::BaseLogHandler < HTTP::Handler - def initialize - end +module Kemal + # All loggers must inherit from `Kemal::BaseLogHandler`. + class Kemal::BaseLogHandler < HTTP::Handler + def initialize + end - def call(context) - call_next context - end + def call(context) + call_next context + end - def write(message) + def write(message) + end end end diff --git a/src/kemal/common_log_handler.cr b/src/kemal/common_log_handler.cr index 00e793e..32fd097 100644 --- a/src/kemal/common_log_handler.cr +++ b/src/kemal/common_log_handler.cr @@ -1,33 +1,35 @@ -class Kemal::CommonLogHandler < Kemal::BaseLogHandler - @handler : IO::FileDescriptor - getter handler +module Kemal + class CommonLogHandler < Kemal::BaseLogHandler + @handler : IO::FileDescriptor + getter handler - def initialize - @handler = STDOUT - end + def initialize + @handler = STDOUT + end - def call(context) - time = Time.now - call_next(context) - elapsed_text = elapsed_text(Time.now - time) - @handler << time << " " << context.response.status_code << " " << context.request.method << " " << context.request.resource << " " << elapsed_text << "\n" - context - end + def call(context) + time = Time.now + call_next(context) + elapsed_text = elapsed_text(Time.now - time) + @handler << time << " " << context.response.status_code << " " << context.request.method << " " << context.request.resource << " " << elapsed_text << "\n" + context + end - def write(message) - @handler << message - end + def write(message) + @handler << message + end - private def elapsed_text(elapsed) - minutes = elapsed.total_minutes - return "#{minutes.round(2)}m" if minutes >= 1 + private def elapsed_text(elapsed) + minutes = elapsed.total_minutes + return "#{minutes.round(2)}m" if minutes >= 1 - seconds = elapsed.total_seconds - return "#{seconds.round(2)}s" if seconds >= 1 + seconds = elapsed.total_seconds + return "#{seconds.round(2)}s" if seconds >= 1 - millis = elapsed.total_milliseconds - return "#{millis.round(2)}ms" if millis >= 1 + millis = elapsed.total_milliseconds + return "#{millis.round(2)}ms" if millis >= 1 - "#{(millis * 1000).round(2)}µs" + "#{(millis * 1000).round(2)}µs" + end end end diff --git a/src/kemal/middleware/ssl.cr b/src/kemal/middleware/ssl.cr index 913c03c..d0db32f 100644 --- a/src/kemal/middleware/ssl.cr +++ b/src/kemal/middleware/ssl.cr @@ -1,4 +1,5 @@ module Kemal::Middleware + # This middleware adds SSL / TLS support. class SSL getter context diff --git a/src/kemal/null_log_handler.cr b/src/kemal/null_log_handler.cr index d86a3fe..0e4fb31 100644 --- a/src/kemal/null_log_handler.cr +++ b/src/kemal/null_log_handler.cr @@ -1,3 +1,5 @@ -# This is here to represent the logger corresponding to Null Object Pattern. -class Kemal::NullLogHandler < Kemal::BaseLogHandler +module Kemal + # This is here to represent the logger corresponding to Null Object Pattern. + class NullLogHandler < Kemal::BaseLogHandler + end end diff --git a/src/kemal/param_parser.cr b/src/kemal/param_parser.cr index 1d2aebe..5ea291e 100644 --- a/src/kemal/param_parser.cr +++ b/src/kemal/param_parser.cr @@ -1,73 +1,75 @@ require "json" -# ParamParser parses the request contents including query_params and body -# and converts them into a params hash which you can within the environment -# context. -alias AllParamTypes = Nil | String | Int64 | Float64 | Bool | Hash(String, JSON::Type) | Array(JSON::Type) +module Kemal + # ParamParser parses the request contents including query_params and body + # and converts them into a params hash which you can within the environment + # context. + alias AllParamTypes = Nil | String | Int64 | Float64 | Bool | Hash(String, JSON::Type) | Array(JSON::Type) -class Kemal::ParamParser - URL_ENCODED_FORM = "application/x-www-form-urlencoded" - APPLICATION_JSON = "application/json" + class ParamParser + URL_ENCODED_FORM = "application/x-www-form-urlencoded" + APPLICATION_JSON = "application/json" - def initialize(@request : HTTP::Request) - @url = {} of String => String - @query = HTTP::Params.new({} of String => Array(String)) - @body = HTTP::Params.new({} of String => Array(String)) - @json = {} of String => AllParamTypes - @url_parsed = false - @query_parsed = false - @body_parsed = false - @json_parsed = false - end + def initialize(@request : HTTP::Request) + @url = {} of String => String + @query = HTTP::Params.new({} of String => Array(String)) + @body = HTTP::Params.new({} of String => Array(String)) + @json = {} of String => AllParamTypes + @url_parsed = false + @query_parsed = false + @body_parsed = false + @json_parsed = false + end - {% for method in %w(url query body json) %} - def {{method.id}} - # check memoization - return @{{method.id}} if @{{method.id}}_parsed + {% for method in %w(url query body json) %} + def {{method.id}} + # check memoization + return @{{method.id}} if @{{method.id}}_parsed - parse_{{method.id}} - # memoize - @{{method.id}}_parsed = true - @{{method.id}} - end - {% end %} + parse_{{method.id}} + # memoize + @{{method.id}}_parsed = true + @{{method.id}} + end + {% end %} - def parse_body - return if (@request.headers["Content-Type"]? =~ /#{URL_ENCODED_FORM}/).nil? - @body = parse_part(@request.body) - end + def parse_body + return if (@request.headers["Content-Type"]? =~ /#{URL_ENCODED_FORM}/).nil? + @body = parse_part(@request.body) + end - def parse_query - @query = parse_part(@request.query) - end + def parse_query + @query = parse_part(@request.query) + end - def parse_url - if params = @request.url_params - params.each do |key, value| - @url[key.as(String)] = value.as(String) + def parse_url + if params = @request.url_params + params.each do |key, value| + @url[key.as(String)] = value.as(String) + end end end - end - # Parses JSON request body if Content-Type is `application/json`. - # If request body is a JSON Hash then all the params are parsed and added into `params`. - # If request body is a JSON Array it's added into `params` as `_json` and can be accessed - # like params["_json"] - def parse_json - return unless @request.body && @request.headers["Content-Type"]? == APPLICATION_JSON + # Parses JSON request body if Content-Type is `application/json`. + # If request body is a JSON Hash then all the params are parsed and added into `params`. + # If request body is a JSON Array it's added into `params` as `_json` and can be accessed + # like params["_json"] + def parse_json + return unless @request.body && @request.headers["Content-Type"]? == APPLICATION_JSON - body = @request.body.as(String) - case json = JSON.parse(body).raw - when Hash - json.each do |key, value| - @json[key.as(String)] = value.as(AllParamTypes) + body = @request.body.as(String) + case json = JSON.parse(body).raw + when Hash + json.each do |key, value| + @json[key.as(String)] = value.as(AllParamTypes) + end + when Array + @json["_json"] = json end - when Array - @json["_json"] = json end - end - def parse_part(part) - HTTP::Params.parse(part || "") + def parse_part(part) + HTTP::Params.parse(part || "") + end end end diff --git a/src/kemal/route.cr b/src/kemal/route.cr index 78395d9..20f0f2b 100644 --- a/src/kemal/route.cr +++ b/src/kemal/route.cr @@ -1,12 +1,14 @@ -# Route is the main building block of Kemal. -# It takes 3 parameters: Method, path and a block to specify -# what action to be done if the route is matched. -class Kemal::Route - getter handler - @handler : HTTP::Server::Context -> String - @method : String +module Kemal + # Route is the main building block of Kemal. + # It takes 3 parameters: Method, path and a block to specify + # what action to be done if the route is matched. + class Route + getter handler + @handler : HTTP::Server::Context -> String + @method : String - def initialize(@method, @path : String, &handler : HTTP::Server::Context -> _) - @handler = ->(context : HTTP::Server::Context) { handler.call(context).to_s } + def initialize(@method, @path : String, &handler : HTTP::Server::Context -> _) + @handler = ->(context : HTTP::Server::Context) { handler.call(context).to_s } + end end end diff --git a/src/kemal/route_handler.cr b/src/kemal/route_handler.cr index 6b50333..73665e2 100644 --- a/src/kemal/route_handler.cr +++ b/src/kemal/route_handler.cr @@ -1,53 +1,54 @@ -require "http/server" require "radix" -# Kemal::RouteHandler is the main handler which handles all the HTTP requests. Routing, parsing, rendering e.g -# are done in this handler. -class Kemal::RouteHandler < HTTP::Handler - INSTANCE = new +module Kemal + # Kemal::RouteHandler is the main handler which handles all the HTTP requests. Routing, parsing, rendering e.g + # are done in this handler. + class RouteHandler < HTTP::Handler + INSTANCE = new - property tree + property tree - def initialize - @tree = Radix::Tree(Route).new - end - - def call(context) - context.response.headers.add "X-Powered-By", "Kemal" - context.response.content_type = "text/html" unless context.response.headers.has_key?("Content-Type") - process_request(context) - end - - # Adds a given route to routing tree. As an exception each `GET` route additionaly defines - # a corresponding `HEAD` route. - def add_route(method, path, &handler : HTTP::Server::Context -> _) - add_to_radix_tree method, path, Route.new(method, path, &handler) - add_to_radix_tree("HEAD", path, Route.new("HEAD", path, &handler)) if method == "GET" - end - - # Check if a route is defined and returns the lookup - def lookup_route(verb, path) - @tree.find radix_path(verb, path) - end - - # Processes the route if it's a match. Otherwise renders 404. - def process_request(context) - raise Kemal::Exceptions::RouteNotFound.new(context) unless context.route_defined? - route = context.route_lookup.payload.as(Route) - content = route.handler.call(context) - if Kemal.config.error_handlers.has_key?(context.response.status_code) - raise Kemal::Exceptions::CustomException.new(context) + def initialize + @tree = Radix::Tree(Route).new end - context.response.print(content) - context - end - private def radix_path(method : String, path) - "/#{method.downcase}#{path}" - end + def call(context) + context.response.headers.add "X-Powered-By", "Kemal" + context.response.content_type = "text/html" unless context.response.headers.has_key?("Content-Type") + process_request(context) + end - private def add_to_radix_tree(method, path, route) - node = radix_path method, path - @tree.add node, route + # Adds a given route to routing tree. As an exception each `GET` route additionaly defines + # a corresponding `HEAD` route. + def add_route(method, path, &handler : HTTP::Server::Context -> _) + add_to_radix_tree method, path, Route.new(method, path, &handler) + add_to_radix_tree("HEAD", path, Route.new("HEAD", path, &handler)) if method == "GET" + end + + # Check if a route is defined and returns the lookup + def lookup_route(verb, path) + @tree.find radix_path(verb, path) + end + + # Processes the route if it's a match. Otherwise renders 404. + def process_request(context) + raise Kemal::Exceptions::RouteNotFound.new(context) unless context.route_defined? + route = context.route_lookup.payload.as(Route) + content = route.handler.call(context) + if Kemal.config.error_handlers.has_key?(context.response.status_code) + raise Kemal::Exceptions::CustomException.new(context) + end + context.response.print(content) + context + end + + private def radix_path(method : String, path) + "/#{method.downcase}#{path}" + end + + private def add_to_radix_tree(method, path, route) + node = radix_path method, path + @tree.add node, route + end end end diff --git a/src/kemal/static_file_handler.cr b/src/kemal/static_file_handler.cr index f7fd79d..7a9bb81 100644 --- a/src/kemal/static_file_handler.cr +++ b/src/kemal/static_file_handler.cr @@ -1,11 +1,13 @@ -# Kemal::StaticFileHandler is used to serve static files(.js/.css/.png e.g). -# This handler is on by default and you can disable it like. -# -# serve_static false -# -class Kemal::StaticFileHandler < HTTP::StaticFileHandler - def call(context) - return call_next(context) if context.request.path.not_nil! == "/" - super +module Kemal + # Kemal::StaticFileHandler is used to serve static files(.js/.css/.png e.g). + # This handler is on by default and you can disable it like. + # + # serve_static false + # + class StaticFileHandler < HTTP::StaticFileHandler + def call(context) + return call_next(context) if context.request.path.not_nil! == "/" + super + end end end diff --git a/src/kemal/websocket_handler.cr b/src/kemal/websocket_handler.cr index e570834..19b83bb 100644 --- a/src/kemal/websocket_handler.cr +++ b/src/kemal/websocket_handler.cr @@ -1,12 +1,14 @@ -# Kemal::WebSocketHandler is used for building a WebSocket route. -# For each WebSocket route a new handler is created and registered to global handlers. -class Kemal::WebSocketHandler < HTTP::WebSocketHandler - def initialize(@path : String, &@proc : HTTP::WebSocket, HTTP::Server::Context -> Void) - Kemal.config.add_ws_handler self - end +module Kemal + # Kemal::WebSocketHandler is used for building a WebSocket route. + # For each WebSocket route a new handler is created and registered to global handlers. + class WebSocketHandler < HTTP::WebSocketHandler + def initialize(@path : String, &@proc : HTTP::WebSocket, HTTP::Server::Context -> Void) + Kemal.config.add_ws_handler self + end - def call(context) - return call_next(context) unless context.request.path.not_nil! == @path - super + def call(context) + return call_next(context) unless context.request.path.not_nil! == @path + super + end end end