Fix weblit.
This commit is contained in:
parent
fae23bca06
commit
fbde58f205
8 changed files with 266 additions and 81 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
deps
|
deps/*
|
||||||
|
!deps/weblit-server.lua
|
||||||
|
|
256
deps/weblit-server.lua
vendored
Normal file
256
deps/weblit-server.lua
vendored
Normal file
|
@ -0,0 +1,256 @@
|
||||||
|
--[[lit-meta
|
||||||
|
name = "creationix/weblit-server"
|
||||||
|
version = "3.1.3"
|
||||||
|
dependencies = {
|
||||||
|
'creationix/coro-net@3.3.0',
|
||||||
|
'luvit/http-codec@3.0.0'
|
||||||
|
}
|
||||||
|
description = "Weblit is a webapp framework designed around routes and middleware layers."
|
||||||
|
tags = {"weblit", "server", "framework"}
|
||||||
|
license = "MIT"
|
||||||
|
author = { name = "Tim Caswell" }
|
||||||
|
homepage = "https://github.com/creationix/weblit/blob/master/libs/weblit-app.lua"
|
||||||
|
]]
|
||||||
|
|
||||||
|
local uv = require('uv')
|
||||||
|
local createServer = require('coro-net').createServer
|
||||||
|
local httpCodec = require('http-codec')
|
||||||
|
|
||||||
|
-- Provide a nice case insensitive interface to headers.
|
||||||
|
local headerMeta = {}
|
||||||
|
function headerMeta:__index(name)
|
||||||
|
if type(name) ~= "string" then
|
||||||
|
return rawget(self, name)
|
||||||
|
end
|
||||||
|
name = name:lower()
|
||||||
|
for i = 1, #self do
|
||||||
|
local key, value = unpack(self[i])
|
||||||
|
if key:lower() == name then return value end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function headerMeta:__newindex(name, value)
|
||||||
|
-- non-string keys go through as-is.
|
||||||
|
if type(name) ~= "string" then
|
||||||
|
return rawset(self, name, value)
|
||||||
|
end
|
||||||
|
-- First remove any existing pairs with matching key
|
||||||
|
local lowerName = name:lower()
|
||||||
|
for i = #self, 1, -1 do
|
||||||
|
if self[i][1]:lower() == lowerName then
|
||||||
|
table.remove(self, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- If value is nil, we're done
|
||||||
|
if value == nil then return end
|
||||||
|
-- Otherwise, set the key(s)
|
||||||
|
if (type(value) == "table") then
|
||||||
|
-- We accept a table of strings
|
||||||
|
for i = 1, #value do
|
||||||
|
rawset(self, #self + 1, { name, tostring(value[i]) })
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Or a single value interperted as string
|
||||||
|
rawset(self, #self + 1, { name, tostring(value) })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function newServer(run)
|
||||||
|
local server = {}
|
||||||
|
local bindings = {}
|
||||||
|
|
||||||
|
run = run or function() end
|
||||||
|
|
||||||
|
local pwd = process.env.PWD
|
||||||
|
|
||||||
|
local function handleRequest(head, read, socket)
|
||||||
|
if not head.path then
|
||||||
|
return { code = 500 }, ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local req = {
|
||||||
|
socket = socket,
|
||||||
|
method = head.method or "GET",
|
||||||
|
path = head.path,
|
||||||
|
headers = setmetatable({}, headerMeta),
|
||||||
|
version = head.version,
|
||||||
|
keepAlive = head.keepAlive,
|
||||||
|
body = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
req.path = req.path:gsub("/+$", "")
|
||||||
|
if req.path == "" then req.path = "/" end
|
||||||
|
|
||||||
|
for i = 1, #head do
|
||||||
|
req.headers[i] = head[i]
|
||||||
|
|
||||||
|
local k, a, b, c, d, e = unpack(head[i])
|
||||||
|
req.headers[k] = { a, b, c, d, e }
|
||||||
|
end
|
||||||
|
|
||||||
|
local res = {
|
||||||
|
code = 404,
|
||||||
|
headers = setmetatable({}, headerMeta),
|
||||||
|
body = "Not Found\n",
|
||||||
|
}
|
||||||
|
|
||||||
|
local success, err = pcall(function()
|
||||||
|
if req.method ~= "GET" then
|
||||||
|
local expectedSize
|
||||||
|
local maxSize = 1024 * 1024 -- 10kb
|
||||||
|
|
||||||
|
for i = 1, #req.headers do
|
||||||
|
local key, value = unpack(head[i])
|
||||||
|
if key:lower() == "content-length" then
|
||||||
|
expectedSize = tonumber(value) or expectedSize
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if expectedSize then
|
||||||
|
local bodySize = 0
|
||||||
|
|
||||||
|
if expectedSize > maxSize then
|
||||||
|
req.read = read
|
||||||
|
req.expectedSize = expectedSize
|
||||||
|
else
|
||||||
|
local parts = {}
|
||||||
|
for chunk in read do
|
||||||
|
if #chunk == 0 then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
parts[#parts + 1] = chunk
|
||||||
|
bodySize = bodySize + #chunk
|
||||||
|
|
||||||
|
if bodySize > expectedSize then
|
||||||
|
error("Request body exceeds expected size")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if bodySize ~= expectedSize then
|
||||||
|
error("Request body is not of the expected size")
|
||||||
|
end
|
||||||
|
|
||||||
|
req.body = table.concat(parts)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
run(req, res, function() end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
if not success then
|
||||||
|
local trace = debug.traceback(err, 2)
|
||||||
|
res.code = 500
|
||||||
|
res.headers = setmetatable({}, headerMeta)
|
||||||
|
res.body = trace:gsub(pwd .. "/", "%./")
|
||||||
|
print(trace)
|
||||||
|
end
|
||||||
|
|
||||||
|
local out = {
|
||||||
|
code = res.code,
|
||||||
|
keepAlive = res.keepAlive,
|
||||||
|
}
|
||||||
|
for i = 1, #res.headers do
|
||||||
|
out[i] = res.headers[i]
|
||||||
|
end
|
||||||
|
return out, res.body, res.upgrade
|
||||||
|
end
|
||||||
|
|
||||||
|
local function handleConnection(read, write, socket, updateDecoder, updateEncoder)
|
||||||
|
for head in read do
|
||||||
|
local res, body, upgrade = handleRequest(head, read, socket)
|
||||||
|
write(res)
|
||||||
|
if upgrade then
|
||||||
|
return upgrade(read, write, updateDecoder, updateEncoder, socket)
|
||||||
|
end
|
||||||
|
write(body)
|
||||||
|
if not (res.keepAlive and head.keepAlive) then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
write()
|
||||||
|
end
|
||||||
|
|
||||||
|
function server.setRun(newRun)
|
||||||
|
run = newRun
|
||||||
|
end
|
||||||
|
|
||||||
|
function server.bind(options)
|
||||||
|
if not options.port then
|
||||||
|
local getuid = require('uv').getuid
|
||||||
|
options.port = (getuid and getuid() == 0) and
|
||||||
|
(options.tls and 443 or 80) or
|
||||||
|
(options.tls and 8443 or 8080)
|
||||||
|
end
|
||||||
|
bindings[#bindings + 1] = options
|
||||||
|
return server
|
||||||
|
end
|
||||||
|
|
||||||
|
function server.start()
|
||||||
|
if #bindings == 0 then
|
||||||
|
server.bind({})
|
||||||
|
end
|
||||||
|
|
||||||
|
local function show(options)
|
||||||
|
local protocol = options.tls and 'https' or 'http'
|
||||||
|
local port = ""
|
||||||
|
if options.port ~= (options.tls and 443 or 80) then
|
||||||
|
port = ":" .. options.port
|
||||||
|
end
|
||||||
|
local host = options.host
|
||||||
|
if host:match(":") then host = "[" .. host .. "]" end
|
||||||
|
print(" " .. protocol .. '://' .. host .. port .. '/')
|
||||||
|
end
|
||||||
|
|
||||||
|
print("Server listening at:")
|
||||||
|
|
||||||
|
for i = 1, #bindings do
|
||||||
|
local options = bindings[i]
|
||||||
|
if options.host then
|
||||||
|
show(options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local ips = {}
|
||||||
|
for i = 1, #bindings do
|
||||||
|
local options = bindings[i]
|
||||||
|
if options.host then
|
||||||
|
local list = uv.getaddrinfo(options.host, nil, {})
|
||||||
|
for i = 1, #list do
|
||||||
|
local entry = list[i]
|
||||||
|
ips[entry.addr .. " " .. options.port] = options
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for name, list in pairs(uv.interface_addresses()) do
|
||||||
|
for i = 1, #list do
|
||||||
|
local data = list[i]
|
||||||
|
if data.family == "inet" then
|
||||||
|
ips[data.ip .. ' ' .. options.port] = options
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for addr, options in pairs(ips) do
|
||||||
|
local host, port = addr:match("(.*) (.*)")
|
||||||
|
port = tonumber(port)
|
||||||
|
options.decoder = httpCodec.decoder
|
||||||
|
options.encoder = httpCodec.encoder
|
||||||
|
options.host = host
|
||||||
|
options.port = port
|
||||||
|
createServer(options, handleConnection)
|
||||||
|
show(options)
|
||||||
|
end
|
||||||
|
|
||||||
|
return server
|
||||||
|
end
|
||||||
|
|
||||||
|
return server
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
newServer = newServer,
|
||||||
|
headerMeta = headerMeta
|
||||||
|
}
|
62
kv.lua
62
kv.lua
|
@ -1,62 +0,0 @@
|
||||||
-- Function to check if a line starts with a given prefix
|
|
||||||
local function starts_with(line, prefix)
|
|
||||||
return string.sub(line, 1, #prefix) == prefix
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Function to perform binary search on the file and return the line number
|
|
||||||
local function binary_search_file(filename, target_prefix)
|
|
||||||
local file = io.open(filename, "r")
|
|
||||||
if not file then
|
|
||||||
error("Could not open file: " .. filename)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Find total number of lines in the file
|
|
||||||
local line_count = 0
|
|
||||||
for _ in file:lines() do
|
|
||||||
line_count = line_count + 1
|
|
||||||
end
|
|
||||||
file:seek("set", 0) -- Reset file pointer to the beginning
|
|
||||||
|
|
||||||
local low = 1
|
|
||||||
local high = line_count
|
|
||||||
local line_number = nil
|
|
||||||
|
|
||||||
while low <= high do
|
|
||||||
local mid = math.floor((low + high) / 2)
|
|
||||||
|
|
||||||
-- Seek to the middle line and read it
|
|
||||||
local current_line
|
|
||||||
for i = 1, mid do
|
|
||||||
current_line = file:read()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Check if the line starts with the target prefix
|
|
||||||
if starts_with(current_line, target_prefix) then
|
|
||||||
line_number = mid -- Store the line number
|
|
||||||
file:close()
|
|
||||||
return line_number -- Return the line number where the match was found
|
|
||||||
elseif current_line < target_prefix then
|
|
||||||
low = mid + 1 -- Move to the right half
|
|
||||||
else
|
|
||||||
high = mid - 1 -- Move to the left half
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Reset file pointer after reading the line
|
|
||||||
file:seek("set", 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
file:close()
|
|
||||||
return nil -- No line starts with the target prefix
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Example usage
|
|
||||||
local filename = "yourfile.txt"
|
|
||||||
local target_prefix = "hello"
|
|
||||||
|
|
||||||
local result = binary_search_file(filename, target_prefix)
|
|
||||||
|
|
||||||
if result then
|
|
||||||
print("Found a line that starts with '" .. target_prefix .. "' at line number: " .. result)
|
|
||||||
else
|
|
||||||
print("No line starts with '" .. target_prefix .. "'")
|
|
||||||
end
|
|
2
main.lua
2
main.lua
|
@ -50,7 +50,7 @@ weblit.app
|
||||||
)
|
)
|
||||||
|
|
||||||
.route(
|
.route(
|
||||||
{ path = "/media/:path:" },
|
{ path = "/media/:path:", method = "GET" },
|
||||||
weblit.static("database/media")
|
weblit.static("database/media")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
return {
|
return {
|
||||||
name = "radon",
|
name = "napkin",
|
||||||
version = "0.0.1",
|
version = "0.0.1",
|
||||||
description = "A simple description of my little package.",
|
description = "A simple blogging platform.",
|
||||||
tags = { "lua", "lit", "luvit" },
|
tags = { "lua", "lit", "luvit", "fediverse" },
|
||||||
license = "MIT",
|
license = "MIT",
|
||||||
author = { name = "n", email = "darltrash@icloud.com" },
|
author = { name = "n", email = "darltrash@icloud.com" },
|
||||||
homepage = "https://github.com/radontest",
|
homepage = "https://github.com/radontest",
|
||||||
|
|
|
@ -58,12 +58,10 @@ return function(data)
|
||||||
end
|
end
|
||||||
end),
|
end),
|
||||||
|
|
||||||
div {
|
h1 {
|
||||||
class = "gapped-row",
|
class = "title",
|
||||||
h1 {
|
blog.title,
|
||||||
class = "title",
|
|
||||||
blog.title,
|
|
||||||
},
|
|
||||||
a {
|
a {
|
||||||
class = "handle",
|
class = "handle",
|
||||||
href = "/@" .. handle,
|
href = "/@" .. handle,
|
||||||
|
|
|
@ -112,9 +112,6 @@ utils.is_valid_password = function(password)
|
||||||
end
|
end
|
||||||
|
|
||||||
utils.cookies = function(req, res, go)
|
utils.cookies = function(req, res, go)
|
||||||
req.path = req.path:gsub("/+$", "")
|
|
||||||
if req.path == "" then req.path = "/" end
|
|
||||||
|
|
||||||
req.content_type = nil
|
req.content_type = nil
|
||||||
req.cookies = {}
|
req.cookies = {}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
animals:1000
|
|
||||||
bees:300
|
|
||||||
cachorros:200
|
|
||||||
cerdos:382
|
|
||||||
hello:10110
|
|
Loading…
Add table
Add a link
Reference in a new issue