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