#!/usr/bin/lua5.4
local directory = "/var/nex"
-- Function to escape HTML special characters
local function escape_html(text)
return text:gsub("&", "&")
:gsub("<", "<")
:gsub(">", ">")
end
-- Function to process links, ensuring spaces are preserved
local function process_links(line)
if line:match("^=> ") then
local url, text = line:match("^=>%s*(%S+)(.*)") -- Keep all spacing in text
return string.format('%s%s', escape_html(url), escape_html(url), escape_html(text))
end
return escape_html(line) -- Only escape HTML special characters, no space modifications
end
-- Generate HTML structure
local function generate_html(title, content)
return string.format([[
Morena + %s
%s
]], title, content)
end
-- Simplified error response function
local function send_error(status, message)
io.write(string.format("HTTP/1.0 %s\r\nContent-Type: text/html\r\n\r\n
%s
", status, message))
end
-- Read HTTP request from stdin
local request = io.read("*l")
local method, path = request:match("^(%S+)%s+(%S+)")
path = path:gsub("^/", ""):gsub("%.%.", ""):gsub("/$", "") -- Safe path sanitization
if path == "" then path = "index" end
local file_path = directory .. "/" .. path
-- Handle favicon.ico separately
if path == "favicon.ico" then
local f = io.open(file_path, "rb")
if f then
io.write("HTTP/1.0 200 OK\r\nContent-Type: image/x-icon\r\n\r\n")
io.write(f:read("*all"))
f:close()
else
send_error("404 Not Found", "Favicon Not Found")
end
return
end
-- Serve files
if method == "GET" then
local f = io.open(file_path, "r")
if f then
local content, title = "", ""
local lines = {}
for line in f:lines() do
table.insert(lines, line)
end
f:close()
-- Check if it's a plain text file and serve it
if file_path:match("%.[a-zA-Z0-9]+$") then
io.write("HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n")
io.write(table.concat(lines, "\n"))
else
-- Extract title from the lines
if #lines >= 4 and lines[4]:match("^%-+$") then
title = lines[3] -- Title is on the 3rd line
elseif #lines >= 5 and lines[5]:match("^%-+$") then
title = lines[4] -- Title is on the 4th line
end
-- Process links and escape text
for _, line in ipairs(lines) do
content = content .. process_links(line) .. "\n"
end
io.write("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n")
io.write(generate_html(title, content))
end
else
send_error("404 Not Found", "File Not Found")
end
else
send_error("405 Method Not Allowed", "Method Not Allowed")
end