-
-
Save dpsk/5088646 to your computer and use it in GitHub Desktop.
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
| <? | |
| -- Launch with: -w /route/=route/,**=./bicycle.lp | |
| _G.bicycle = { | |
| action = { }, | |
| basket = { }, | |
| ride = function (config) | |
| local destination = request_info.uri:gsub("/+$", ""):gsub("^$", "/index") | |
| local route = config and config.route or "route" | |
| local path = route .. destination | |
| local method = request_info.request_method | |
| local headers = request_info.http_headers | |
| local host = headers.Host | |
| local content_type = headers["Content-Type"] | |
| local file | |
| function bounce(uri) | |
| if uri == nil or uri == "" then uri = "/" end | |
| if uri == request_info.uri then | |
| print( | |
| 'HTTP/1.0 404 Not Found\r\nContent-Type: text/html\r\n\r\n' .. | |
| 'Not found.') | |
| else | |
| print( | |
| ("HTTP/1.0 302 Found\r\nLocation: %s://%s%s\r\n\r\n"):format( | |
| request_info.is_ssl == 1 and 'https' or 'http', host, | |
| uri == "." and request_info.uri or uri)) | |
| end | |
| end | |
| function escape (s) | |
| return s:gsub("&", "&"):gsub("<", "<"):gsub(">", ">") | |
| :gsub(" ", "+"):gsub("([^A-Za-z0-9_])", function(c) | |
| return string.format("%%%02x", string.byte(c)) | |
| end) | |
| end | |
| function unescape (s) | |
| return s:gsub("&", "&"):gsub("<", "<"):gsub(">", ">") | |
| :gsub("+", " "):gsub("%%(%x%x)", function(hex) | |
| return string.char(tonumber(hex, 16)) | |
| end) | |
| end | |
| function bundle(query) | |
| local parsed = {} | |
| local pos = 0 | |
| if query == nil then return parsed end | |
| local function insert(s) | |
| local first, last = s:find("=") | |
| if first then | |
| parsed[unescape(s:sub(0, first - 1))] = unescape(s:sub(first + 1)) | |
| end | |
| end | |
| while true do | |
| local first, last = query:find("&", pos) | |
| if first then | |
| insert(query:sub(pos, first - 1)); | |
| pos = last + 1 | |
| else | |
| insert(query:sub(pos)); | |
| break; | |
| end | |
| end | |
| return parsed | |
| end | |
| if method == "POST" then | |
| local realpath = path:gsub("/[^/]*$", "") | |
| local action = path:gsub("^.*/", "") | |
| file = io.open(realpath .. ".lua", "r") | |
| if file == nil then return bounce() end | |
| io.close(file) | |
| if content_type == "application/x-www-form-urlencoded" then | |
| local query = "" | |
| local buffer | |
| local fields | |
| while true do | |
| buffer = read() | |
| if buffer == "" then break end | |
| query = query .. buffer | |
| end | |
| bicycle.basket = bundle(request_info.query_string) | |
| fields = bundle(query) | |
| require(realpath) | |
| bicycle.action[action](fields) | |
| return bounce(request_info.uri:gsub("/[^/]*$", "/")) | |
| else | |
| -- TODO: support "multipart/form-data" | |
| print("Content type " .. content_type .. " not supported.") | |
| return | |
| end | |
| end | |
| if method ~= "GET" and method ~= "POST" then return bounce() end | |
| local file = io.open(path .. ".lp", "r") | |
| if file == nil then return bounce() end | |
| io.close(file) | |
| if destination .. "/" ~= request_info.uri then | |
| return bounce(destination .. '/') | |
| end | |
| bicycle.basket = bundle(request_info.query_string) | |
| print('HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n') | |
| mg.include(path .. ".lp") | |
| end | |
| } | |
| bicycle.ride() | |
| ?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment