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(
|
||||
{ path = "/media/:path:" },
|
||||
{ path = "/media/:path:", method = "GET" },
|
||||
weblit.static("database/media")
|
||||
)
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
return {
|
||||
name = "radon",
|
||||
name = "napkin",
|
||||
version = "0.0.1",
|
||||
description = "A simple description of my little package.",
|
||||
tags = { "lua", "lit", "luvit" },
|
||||
description = "A simple blogging platform.",
|
||||
tags = { "lua", "lit", "luvit", "fediverse" },
|
||||
license = "MIT",
|
||||
author = { name = "n", email = "darltrash@icloud.com" },
|
||||
homepage = "https://github.com/radontest",
|
||||
|
|
|
@ -58,12 +58,10 @@ return function(data)
|
|||
end
|
||||
end),
|
||||
|
||||
div {
|
||||
class = "gapped-row",
|
||||
h1 {
|
||||
class = "title",
|
||||
blog.title,
|
||||
},
|
||||
h1 {
|
||||
class = "title",
|
||||
blog.title,
|
||||
|
||||
a {
|
||||
class = "handle",
|
||||
href = "/@" .. handle,
|
||||
|
|
|
@ -112,9 +112,6 @@ utils.is_valid_password = function(password)
|
|||
end
|
||||
|
||||
utils.cookies = function(req, res, go)
|
||||
req.path = req.path:gsub("/+$", "")
|
||||
if req.path == "" then req.path = "/" end
|
||||
|
||||
req.content_type = nil
|
||||
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