Created
September 14, 2012 10:11
-
-
Save daurnimator/3721157 to your computer and use it in GitHub Desktop.
Sinatra like clone for lua
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if not sinatra.incoming ( ngx.req.get_method() , ngx.var.uri ) then | |
return ngx.exit ( 404 ) | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sinatra = require "sinatra" | |
sinatra.get "/" ( function ( p ) | |
ngx.print("A") | |
end ) | |
sinatra.post "/login" ( function ( p ) | |
ngx.print("B") | |
end ) | |
-- Can 'or' routes together with `+` | |
local r = sinatra.get "^/(%d+)/(%w*)" ; | |
( r:agent "Chrome" + "Firefox" ) ( function ( p ) | |
ngx.print("Chrome or firefox user") | |
end ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
worker_processes 1; | |
error_log logs/error.log debug; # Development only | |
events { | |
worker_connections 1024; | |
} | |
http { | |
sendfile on; | |
lua_package_path '/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua;;'; | |
lua_package_cpath '/usr/lib/lua/5.1/?.so;;'; | |
lua_code_cache off; # Development only | |
init_by_lua_file init.lua; | |
server { | |
listen 8000; | |
####################################################### | |
#static files | |
location ^~ /scripts { | |
default_type text/javascript; | |
alias scripts; | |
} | |
location ^~ /styles { | |
default_type text/css; | |
alias styles; | |
} | |
####################################################### | |
location / { | |
default_type text/html; | |
#rewrite_by_lua_file rewrite.lua; | |
#access_by_lua_file access.lua; | |
content_by_lua_file app.lua; | |
} | |
####################################################### | |
# 404s for file requests | |
location ~* \.(ico|gif|jpeg|jpg)$ { | |
internal; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local handlers = { } | |
-- Conditions | |
local conditions = { } | |
local conditions_mt = { | |
__index = conditions ; | |
__call = function ( t , matcher ) | |
return t:default ( matcher ) | |
end ; | |
} | |
local function new_router ( proto , matcher ) | |
local r = setmetatable ( { } , conditions_mt ) | |
if proto then | |
for i , v in ipairs ( proto ) do | |
r [ i ] = v | |
end ; | |
end | |
r [ #r + 1 ] = matcher | |
return r | |
end | |
local function check_match ( v , params ) | |
local matched = true | |
for ii , vv in ipairs ( v ) do | |
if not vv ( params ) then | |
matched = false | |
break | |
end | |
end | |
return matched | |
end | |
conditions_mt.__add = function ( a , b ) | |
return new_router ( nil , function ( params ) | |
return check_match ( a , params ) or check_match ( b , params ) | |
end ) ; | |
end | |
function conditions:default ( matcher ) | |
local t = type ( matcher ) | |
if t == "string" then | |
if matcher:sub(1,1) == "^" then -- Pattern | |
return new_router ( self , function ( params ) | |
local r = { params.uri:match ( matcher ) } | |
if r[1] then | |
params.uri = r | |
return true | |
else | |
return false | |
end | |
end ) | |
else | |
return new_router ( self , function ( params ) | |
return params.uri == matcher | |
end ) | |
end | |
elseif t == "function" then -- Complete the handler | |
self._handler = matcher | |
table.insert ( handlers , self ) | |
else | |
error ( "Unhandled type: " .. t ) | |
end | |
end | |
function conditions:method ( method ) | |
return new_router ( self , function ( params ) | |
return method == params.method | |
end ) | |
end | |
local function incoming ( method , uri ) | |
for i , v in ipairs ( handlers ) do | |
local params = { | |
method = method ; | |
uri = uri ; | |
} | |
if check_match ( v , params ) then | |
v._handler ( params ) | |
return true | |
end | |
end | |
-- No routes matched | |
return false | |
end | |
return { | |
incoming = incoming ; | |
new_router = new_router ; | |
conditions = conditions ; | |
get = conditions.method ( nil , "GET" ) ; | |
post = conditions.method ( nil , "POST" ) ; | |
put = conditions.method ( nil , "PUT" ) ; | |
patch = conditions.method ( nil , "PATCH" ) ; | |
delete = conditions.method ( nil , "DELETE" ) ; | |
options = conditions.method ( nil , "OPTIONS" ) ; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local sinatra = require "sinatra" | |
function sinatra.conditions:agent ( pattern ) | |
return sinatra.new_router ( self , function ( params ) | |
local user_agent = ngx.var.http_user_agent or "" | |
return user_agent:match ( pattern ) | |
end ) | |
end | |
function sinatra.conditions:host_name ( pattern ) | |
return sinatra.new_router ( self , function ( params ) | |
local host = ngx.var.host | |
return host:match ( pattern ) | |
end ) | |
end | |
local header_parsers = require "header_parsers" | |
local misc = require "misc" | |
local accept_comparison = function ( allowed , want ) | |
return ( not want.type or allowed.type == "*" or ( allowed.type == want.type and | |
( not want.subtype or allowed.subtype == "*" or allowed.subtype == want.subtype ) ) | |
) and allowed.q ~= 0 | |
end | |
function sinatra.conditions:provides ( types ) | |
local want_list = { } | |
for type , subtype in string.gmatch ( types , "(%w+)/(%w+)[%s;]*" ) do | |
table.insert ( want_list , { type = type , subtype = subtype } ) | |
end | |
return sinatra.new_router ( self , function ( params ) | |
local accepts = ngx.var.http_accepts or "*/*" | |
local accept_list = header_parsers.accept ( accepts ) | |
local res = misc.choose ( accept_list , want_list , accept_comparison ) | |
if res[1] then | |
params.providing = res[1].type .. "/" .. res[1].subtype | |
return true | |
else | |
return false | |
end | |
end ) | |
end |
I did not :P
I started this after a discussion in #lua (on freenode)
OK. No time to hang on IRC, sadly :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice snippet! Do you know https://github.com/nrk/mercury ?