Initial commit
This commit is contained in:
commit
2eaf44195e
9 changed files with 115 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
.crystal
|
5
samples/hello_world.cr
Normal file
5
samples/hello_world.cr
Normal file
|
@ -0,0 +1,5 @@
|
|||
require "../src/frank"
|
||||
|
||||
get "/" do
|
||||
"Hello World!"
|
||||
end
|
16
spec/route_spec.cr
Normal file
16
spec/route_spec.cr
Normal file
|
@ -0,0 +1,16 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe "Route" do
|
||||
describe "match" do
|
||||
it "doesn't match" do
|
||||
route = Route.new("/foo/bar", nil)
|
||||
route.match(nil, "/foo/baz".split("/")).should be_nil
|
||||
end
|
||||
|
||||
it "matches" do
|
||||
route = Route.new("/foo/:one/path/:two", nil)
|
||||
request = route.match(nil, "/foo/uno/path/dos".split("/"))
|
||||
request.not_nil!.params.should eq({"one" => "uno", "two" => "dos"})
|
||||
end
|
||||
end
|
||||
end
|
4
spec/spec_helper.cr
Normal file
4
spec/spec_helper.cr
Normal file
|
@ -0,0 +1,4 @@
|
|||
require "spec"
|
||||
require "../src/frank/*"
|
||||
|
||||
include Frank
|
21
src/frank.cr
Normal file
21
src/frank.cr
Normal file
|
@ -0,0 +1,21 @@
|
|||
require "option_parser"
|
||||
require "./frank/*"
|
||||
|
||||
$frank_handler = Frank::Handler.new
|
||||
port = 3000
|
||||
|
||||
OptionParser.parse! do |opts|
|
||||
opts.on("-p ", "--port ", "port") do |opt_port|
|
||||
port = opt_port.to_i
|
||||
end
|
||||
end
|
||||
|
||||
at_exit do
|
||||
handlers = [] of HTTP::Handler
|
||||
handlers << HTTP::LogHandler.new
|
||||
handlers << $frank_handler
|
||||
server = HTTP::Server.new(port, HTTP::Server.build_middleware handlers)
|
||||
|
||||
puts "Listening on http://0.0.0.0:#{port}"
|
||||
server.listen
|
||||
end
|
3
src/frank/dsl.cr
Normal file
3
src/frank/dsl.cr
Normal file
|
@ -0,0 +1,3 @@
|
|||
def get(path, &block : Frank::Request -> String)
|
||||
$frank_handler.add_route(path, block)
|
||||
end
|
34
src/frank/handler.cr
Normal file
34
src/frank/handler.cr
Normal file
|
@ -0,0 +1,34 @@
|
|||
require "net/http"
|
||||
|
||||
class Frank::Handler < HTTP::Handler
|
||||
def initialize
|
||||
@routes = [] of Route
|
||||
end
|
||||
|
||||
def call(request)
|
||||
if body = exec_request(request)
|
||||
begin
|
||||
HTTP::Response.new("HTTP/1.1", 200, "OK", {"Content-Type" => "text/plain"}, body)
|
||||
rescue ex
|
||||
HTTP::Response.new("HTTP/1.1", 500, "Internal Server Error", {"Content-Type" => "text/plain"}, ex.to_s)
|
||||
end
|
||||
else
|
||||
HTTP::Response.new("HTTP/1.1", 404, "Not Found", {"Content-Type" => "text/plain"}, "Not Found")
|
||||
end
|
||||
end
|
||||
|
||||
def add_route(path, handler)
|
||||
@routes << Route.new(path, handler)
|
||||
end
|
||||
|
||||
def exec_request(request)
|
||||
components = request.path.split "/"
|
||||
@routes.each do |route|
|
||||
frank_request = route.match(request, components)
|
||||
if frank_request
|
||||
return route.handler.call(frank_request)
|
||||
end
|
||||
end
|
||||
nil
|
||||
end
|
||||
end
|
6
src/frank/request.cr
Normal file
6
src/frank/request.cr
Normal file
|
@ -0,0 +1,6 @@
|
|||
class Frank::Request
|
||||
getter params
|
||||
|
||||
def initialize(@params)
|
||||
end
|
||||
end
|
25
src/frank/route.cr
Normal file
25
src/frank/route.cr
Normal file
|
@ -0,0 +1,25 @@
|
|||
class Frank::Route
|
||||
getter handler
|
||||
|
||||
def initialize(path, @handler)
|
||||
@components = path.split "/"
|
||||
end
|
||||
|
||||
def match(request, components)
|
||||
return nil unless components.length == @components.length
|
||||
|
||||
params = nil
|
||||
|
||||
@components.zip(components) do |route_component, req_component|
|
||||
if route_component.starts_with? ':'
|
||||
params ||= {} of String => String
|
||||
params[route_component[1 .. -1]] = req_component
|
||||
else
|
||||
return nil unless route_component == req_component
|
||||
end
|
||||
end
|
||||
|
||||
params ||= {} of String => String
|
||||
Request.new(params)
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue