save
This commit is contained in:
2
Makefile
2
Makefile
@@ -8,7 +8,7 @@ deps:
|
|||||||
$(GO) mod download
|
$(GO) mod download
|
||||||
|
|
||||||
build: deps
|
build: deps
|
||||||
CGO_ENABLED=0 $(GO) build -a -v -x -trimpath -ldflags "-X fes/modules/version.gitCommit=$(shell git rev-parse --short HEAD) -s -w -buildid=" -o fes
|
CGO_ENABLED=0 $(GO) build -trimpath -ldflags "-X fes/modules/version.gitCommit=$(shell git rev-parse --short HEAD) -s -w -buildid=" -o fes
|
||||||
@echo "Fes is now built to ./fes"
|
@echo "Fes is now built to ./fes"
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
|
|||||||
4
TODO
Normal file
4
TODO
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
* Fix Gemini rendering
|
||||||
|
* Add Gemini command-line options
|
||||||
|
* Better gemini errors
|
||||||
|
* Fix build steps newlines
|
||||||
13
lib/fes.lua
13
lib/fes.lua
@@ -105,9 +105,8 @@ local default_gemini_footer = [[
|
|||||||
{{COPYRIGHT}}
|
{{COPYRIGHT}}
|
||||||
]]
|
]]
|
||||||
|
|
||||||
function M.fes(proto, header, footer)
|
function M.fes(header, footer)
|
||||||
proto = proto or "http"
|
local proto = std.proto
|
||||||
std.proto = proto
|
|
||||||
|
|
||||||
local config = {}
|
local config = {}
|
||||||
local site_config = {}
|
local site_config = {}
|
||||||
@@ -179,6 +178,14 @@ function M:build()
|
|||||||
)
|
)
|
||||||
|
|
||||||
return header .. table.concat(self.parts, "\n") .. footer
|
return header .. table.concat(self.parts, "\n") .. footer
|
||||||
|
elseif self.proto == "gemini" then
|
||||||
|
local footer = self.footer:gsub(
|
||||||
|
"{{COPYRIGHT}}",
|
||||||
|
self.copyright or "(c) The Copyright Holder"
|
||||||
|
)
|
||||||
|
local header = self.header
|
||||||
|
|
||||||
|
return header .. table.concat(self.parts, "\n") .. "\n\n" .. footer
|
||||||
end
|
end
|
||||||
|
|
||||||
return table.concat(self.parts, "\n")
|
return table.concat(self.parts, "\n")
|
||||||
|
|||||||
89
lib/std.lua
89
lib/std.lua
@@ -1,6 +1,7 @@
|
|||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
M.proto = "http"
|
M.proto = "http"
|
||||||
|
M.__fes_banner_set = false
|
||||||
|
|
||||||
local function isHttp()
|
local function isHttp()
|
||||||
return M.proto == "http"
|
return M.proto == "http"
|
||||||
@@ -10,18 +11,10 @@ local function isGemini()
|
|||||||
return M.proto == "gemini"
|
return M.proto == "gemini"
|
||||||
end
|
end
|
||||||
|
|
||||||
local function esc(s)
|
|
||||||
s = s or ""
|
|
||||||
s = s:gsub("&", "&")
|
|
||||||
s = s:gsub("<", "<")
|
|
||||||
s = s:gsub(">", ">")
|
|
||||||
return s
|
|
||||||
end
|
|
||||||
|
|
||||||
M.p = function(s)
|
M.p = function(s)
|
||||||
s = s or ""
|
s = s or ""
|
||||||
if isHttp() then
|
if isHttp() then
|
||||||
return "<p>" .. esc(s) .. "</p>"
|
return "<p>" .. s .. "</p>"
|
||||||
elseif isGemini() then
|
elseif isGemini() then
|
||||||
return s
|
return s
|
||||||
end
|
end
|
||||||
@@ -33,7 +26,7 @@ M.h = function(level, s)
|
|||||||
if level > 6 then level = 6 end
|
if level > 6 then level = 6 end
|
||||||
s = s or ""
|
s = s or ""
|
||||||
if isHttp() then
|
if isHttp() then
|
||||||
return "<h" .. level .. ">" .. esc(s) .. "</h" .. level .. ">"
|
return "<h" .. level .. ">" .. s .. "</h" .. level .. ">"
|
||||||
elseif isGemini() then
|
elseif isGemini() then
|
||||||
return string.rep("#", level) .. " " .. s
|
return string.rep("#", level) .. " " .. s
|
||||||
end
|
end
|
||||||
@@ -42,7 +35,7 @@ end
|
|||||||
M.codeblock = function(s)
|
M.codeblock = function(s)
|
||||||
s = s or ""
|
s = s or ""
|
||||||
if isHttp() then
|
if isHttp() then
|
||||||
return "<pre><code>" .. esc(s) .. "</code></pre>"
|
return "<pre><code>" .. s .. "</code></pre>"
|
||||||
elseif isGemini() then
|
elseif isGemini() then
|
||||||
return "```\n" .. s .. "\n```"
|
return "```\n" .. s .. "\n```"
|
||||||
end
|
end
|
||||||
@@ -51,17 +44,17 @@ end
|
|||||||
M.inline = function(s)
|
M.inline = function(s)
|
||||||
s = s or ""
|
s = s or ""
|
||||||
if isHttp() then
|
if isHttp() then
|
||||||
return "<code>" .. esc(s) .. "</code>"
|
return "<code>" .. s .. "</code>"
|
||||||
elseif isGemini() then
|
elseif isGemini() then
|
||||||
return "`" .. s .. "`"
|
return "`" .. s .. "`"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
M.link = function(text, url)
|
M.link = function(url, text)
|
||||||
text = text or ""
|
|
||||||
url = url or ""
|
url = url or ""
|
||||||
|
text = text or url
|
||||||
if isHttp() then
|
if isHttp() then
|
||||||
return "<a href=\"" .. esc(url) .. "\">" .. esc(text) .. "</a>"
|
return "<a href=\"" .. url .. "\">" .. text .. "</a>"
|
||||||
elseif isGemini() then
|
elseif isGemini() then
|
||||||
return "=> " .. url .. " " .. text
|
return "=> " .. url .. " " .. text
|
||||||
end
|
end
|
||||||
@@ -73,7 +66,7 @@ M.list = function(items, ordered)
|
|||||||
local tag = ordered and "ol" or "ul"
|
local tag = ordered and "ol" or "ul"
|
||||||
local out = "<" .. tag .. ">"
|
local out = "<" .. tag .. ">"
|
||||||
for _, v in ipairs(items) do
|
for _, v in ipairs(items) do
|
||||||
out = out .. "<li>" .. esc(v) .. "</li>"
|
out = out .. "<li>" .. v .. "</li>"
|
||||||
end
|
end
|
||||||
out = out .. "</" .. tag .. ">"
|
out = out .. "</" .. tag .. ">"
|
||||||
return out
|
return out
|
||||||
@@ -93,7 +86,7 @@ end
|
|||||||
M.blockquote = function(s)
|
M.blockquote = function(s)
|
||||||
s = s or ""
|
s = s or ""
|
||||||
if isHttp() then
|
if isHttp() then
|
||||||
return "<blockquote>" .. esc(s) .. "</blockquote>"
|
return "<blockquote>" .. s .. "</blockquote>"
|
||||||
elseif isGemini() then
|
elseif isGemini() then
|
||||||
return "> " .. s
|
return "> " .. s
|
||||||
end
|
end
|
||||||
@@ -111,7 +104,7 @@ M.image = function(alt, src)
|
|||||||
alt = alt or ""
|
alt = alt or ""
|
||||||
src = src or ""
|
src = src or ""
|
||||||
if isHttp() then
|
if isHttp() then
|
||||||
return "<img src=\"" .. esc(src) .. "\" alt=\"" .. esc(alt) .. "\" />"
|
return "<img src=\"" .. src .. "\" alt=\"" .. alt .. "\" />"
|
||||||
elseif isGemini() then
|
elseif isGemini() then
|
||||||
return "=> " .. src .. " " .. alt
|
return "=> " .. src .. " " .. alt
|
||||||
end
|
end
|
||||||
@@ -121,7 +114,7 @@ M.file = function(text, url)
|
|||||||
text = text or ""
|
text = text or ""
|
||||||
url = url or ""
|
url = url or ""
|
||||||
if isHttp() then
|
if isHttp() then
|
||||||
return "<a href=\"" .. esc(url) .. "\" download>" .. esc(text) .. "</a>"
|
return "<a href=\"" .. url .. "\" download>" .. text .. "</a>"
|
||||||
elseif isGemini() then
|
elseif isGemini() then
|
||||||
return "=> " .. url .. " " .. text
|
return "=> " .. url .. " " .. text
|
||||||
end
|
end
|
||||||
@@ -130,53 +123,25 @@ end
|
|||||||
M.note = function(text)
|
M.note = function(text)
|
||||||
text = text or ""
|
text = text or ""
|
||||||
if isHttp() then
|
if isHttp() then
|
||||||
return "<div class=\"note\">" .. esc(text) .. "</div>"
|
return "<div class=\"note\">" .. text .. "</div>"
|
||||||
elseif isGemini() then
|
elseif isGemini() then
|
||||||
local width = 31
|
return "\n\n" .. text .. "\n\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function wrap_line(line)
|
M.banner = function (text)
|
||||||
local out = {}
|
text = text or ""
|
||||||
local i = 1
|
|
||||||
local len = #line
|
|
||||||
|
|
||||||
if len == 0 then
|
if M.__fes_banner_set then
|
||||||
out[#out + 1] = ""
|
error("Page already contains header")
|
||||||
return out
|
return ""
|
||||||
end
|
end
|
||||||
|
|
||||||
while i <= len do
|
M.__fes_banner_set = true
|
||||||
out[#out + 1] = line:sub(i, i + width - 1)
|
if isHttp() then
|
||||||
i = i + width
|
return "<div class=\"banner\">" .. text .. "</div>"
|
||||||
end
|
elseif isGemini() then
|
||||||
|
return text .. "\n"
|
||||||
return out
|
|
||||||
end
|
|
||||||
|
|
||||||
local lines = {}
|
|
||||||
|
|
||||||
for line in (text .. "\n"):gmatch("(.-)\n") do
|
|
||||||
local wrapped = wrap_line(line)
|
|
||||||
for _, w in ipairs(wrapped) do
|
|
||||||
lines[#lines + 1] = w
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local border = "+" .. string.rep("=", width + 2) .. "+"
|
|
||||||
local empty = "|" .. string.rep(" ", width + 2) .. "|"
|
|
||||||
|
|
||||||
local out = {}
|
|
||||||
out[#out + 1] = border
|
|
||||||
out[#out + 1] = empty
|
|
||||||
|
|
||||||
for _, line in ipairs(lines) do
|
|
||||||
local padding = width - #line
|
|
||||||
out[#out + 1] = "| " .. line .. string.rep(" ", padding) .. " |"
|
|
||||||
end
|
|
||||||
|
|
||||||
out[#out + 1] = empty
|
|
||||||
out[#out + 1] = border
|
|
||||||
|
|
||||||
return table.concat(out, "\n")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -105,11 +105,112 @@ All commands are run from the root of the project, from a terminal:
|
|||||||
|
|
||||||
| Command | Action |
|
| Command | Action |
|
||||||
| :------------------------ | :----------------------------------------------- |
|
| :------------------------ | :----------------------------------------------- |
|
||||||
| $$fes run .$$ | Runs the project at $$.$$ |
|
| $$fes run .$$ | Runs the project at $$.$$ |
|
||||||
|
|
||||||
|
## Gemini
|
||||||
|
|
||||||
|
Fes supports many different protocols. One of which is the Gemini protocol; this
|
||||||
|
protocol has specific encryption standards which makes the providing $$key.pem$$
|
||||||
|
and a $$cert.pem$$ files. *Please* regenerate these files by running this command.
|
||||||
|
$$$$$$
|
||||||
|
openssl req -x509 -nodes -days 365 \
|
||||||
|
-newkey rsa:2048 \
|
||||||
|
-keyout key.pem \
|
||||||
|
-out cert.pem \
|
||||||
|
-subj "/C=US/ST=State/L=City/O=Local Development/OU=Localhost/CN=localhost" \
|
||||||
|
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:::1" \
|
||||||
|
-addext "basicConstraints=CA:FALSE" \
|
||||||
|
-addext "keyUsage=digitalSignature,keyEncipherment" \
|
||||||
|
-addext "extendedKeyUsage=serverAuth"
|
||||||
|
$$$$$$
|
||||||
|
|
||||||
## What to learn more?
|
## What to learn more?
|
||||||
|
|
||||||
Check out [Fes's docs](https://docs.vxserver.dev/static/fes.html).`, "$$", "`"), dir, dir)
|
Check out [Fes's docs](https://docs.vxserver.dev/static/fes.html).`, "$$", "`"), dir, dir)
|
||||||
|
write("key.pem", `-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCfl+m81U9+WLBn
|
||||||
|
PiJ1ZADnZC+BecXArguAdnbkgDlmfqe1eU6M0PBmXXFHEvJYOh2oYQZ7DMbuLLvo
|
||||||
|
DdjomXM4yb9Axu2KDHfflTcw3wHD3850ganf9rwVG460gkVfUGaRiokyCvEJKd05
|
||||||
|
BxKmx8Zh6G2tpetaDKm72ONYQFyaBCelYMzaBRpJ2kcPqk/gEhUSvQKVF4oDREm+
|
||||||
|
sTEkCTWsjUesiG0393t3psFa/SlZKsNXNrb+N6y9SElKVlQOT28r9YGiDfy5PiAQ
|
||||||
|
iFtQse2gqC4IhG2MGi0b4mu4Qa3+d2u3jsmn6Gqt92hKrbFOpz+Ci5GQ+zKXnE+j
|
||||||
|
/h40l1J3h/aTM5/qS7malAtXySMVzLQnJzai6IL+nBKbIOMCzP1Bns64Oo7YuuhV
|
||||||
|
Cx/sovrvgFF+8j4nLXOBgrx8llYB5cvgVYkNmccXtPzd7hZI6PHgZRGOd0uBKlZ+
|
||||||
|
OHeKhgdnz/a+pCUBwJe8JAzX7fzoZ+HLy26ADx2Uywh0Rjfj4gVOSZXaGS0ne0p5
|
||||||
|
PciN0xsWQdaAWPcVe6+YYRKS6l6qaWuGaPwVsZSvNgIMMPOgUn7+s2Bxh51DhqZT
|
||||||
|
4MDFUJWXFmTnyhHg3Cq7pWJR7pv2erv5q32b8iah5o+CP4W3FeZX1CcBuiIsrimh
|
||||||
|
vZZIa5W2vzpkLHbWgI2XGbx8yKRXowIDAQABAoICAENZb5lyB5cRRHh9XztdFYiQ
|
||||||
|
3f9s7UhP6qiu1aO+fPrFDm9mHwEMF7eLTYep9j3HYMazE3IQRU8z76SRW21lfJuF
|
||||||
|
gEGM8aeldV0UcnMcWXlY1J6ULaVHUb4yn/mLVE1R98cJyLYmqeutEB/F3VgmzJB6
|
||||||
|
7vYuI/EfkO2mLOMMXkfc4wJGpIyJRLvP8tcoj4bG+r+qphFXGrYgNmLUEiHcBRup
|
||||||
|
j4q/FCBfP2qSI90LI0zu3/rJK1aDFlHW1J8baWOUoBzUAX3rGzDth8iSUr7uJ5L6
|
||||||
|
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
|
||||||
|
h6CgX4Gc3+bhvKx36XYxVwScPJUWsQ==
|
||||||
|
-----END PRIVATE KEY-----`)
|
||||||
|
write("cert.pem", `-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFmzCCA4OgAwIBAgIUZGaMDLeCAQplfhhjXb2HaL6xpFYwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwXTELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5
|
||||||
|
MQwwCgYDVQQKDANPcmcxDTALBgNVBAsMBFVuaXQxEjAQBgNVBAMMCWxvY2FsaG9z
|
||||||
|
dDAeFw0yNjAyMjQwMjUwMzVaFw0yNzAyMjQwMjUwMzVaMF0xCzAJBgNVBAYTAlVT
|
||||||
|
MQ4wDAYDVQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0eTEMMAoGA1UECgwDT3JnMQ0w
|
||||||
|
CwYDVQQLDARVbml0MRIwEAYDVQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEB
|
||||||
|
AQUAA4ICDwAwggIKAoICAQCfl+m81U9+WLBnPiJ1ZADnZC+BecXArguAdnbkgDlm
|
||||||
|
fqe1eU6M0PBmXXFHEvJYOh2oYQZ7DMbuLLvoDdjomXM4yb9Axu2KDHfflTcw3wHD
|
||||||
|
3850ganf9rwVG460gkVfUGaRiokyCvEJKd05BxKmx8Zh6G2tpetaDKm72ONYQFya
|
||||||
|
BCelYMzaBRpJ2kcPqk/gEhUSvQKVF4oDREm+sTEkCTWsjUesiG0393t3psFa/SlZ
|
||||||
|
KsNXNrb+N6y9SElKVlQOT28r9YGiDfy5PiAQiFtQse2gqC4IhG2MGi0b4mu4Qa3+
|
||||||
|
d2u3jsmn6Gqt92hKrbFOpz+Ci5GQ+zKXnE+j/h40l1J3h/aTM5/qS7malAtXySMV
|
||||||
|
zLQnJzai6IL+nBKbIOMCzP1Bns64Oo7YuuhVCx/sovrvgFF+8j4nLXOBgrx8llYB
|
||||||
|
5cvgVYkNmccXtPzd7hZI6PHgZRGOd0uBKlZ+OHeKhgdnz/a+pCUBwJe8JAzX7fzo
|
||||||
|
Z+HLy26ADx2Uywh0Rjfj4gVOSZXaGS0ne0p5PciN0xsWQdaAWPcVe6+YYRKS6l6q
|
||||||
|
aWuGaPwVsZSvNgIMMPOgUn7+s2Bxh51DhqZT4MDFUJWXFmTnyhHg3Cq7pWJR7pv2
|
||||||
|
erv5q32b8iah5o+CP4W3FeZX1CcBuiIsrimhvZZIa5W2vzpkLHbWgI2XGbx8yKRX
|
||||||
|
owIDAQABo1MwUTAdBgNVHQ4EFgQUcyq+ZZWmAUejOPEQpHpl4hOllHswHwYDVR0j
|
||||||
|
BBgwFoAUcyq+ZZWmAUejOPEQpHpl4hOllHswDwYDVR0TAQH/BAUwAwEB/zANBgkq
|
||||||
|
hkiG9w0BAQsFAAOCAgEANwdjxlPHqvOOyNTFJcFhcNff3862/74CyCiglrstk/ea
|
||||||
|
txjyHxXFwXOtyAtm0tqaQPpzHWFM5MDqVD7Qip4aZrPcRvvfJ8zxXuakrgy7oI6i
|
||||||
|
Wl4/BXzvIoxh8MyFVC7VdGmuv11fq091RaNPlnz5lH9Qxhb6QCGbk73PjTXxD/7A
|
||||||
|
yusNiXuJvx3oRhLLGuksotFKEnngOq21Jla3ZPUmJTLAZdk/joXITk5Q64ZBp5uD
|
||||||
|
rpxFZDtdHTBuL3nmNPUHixsxQRFzCSloufRlatdI2ldDc+d2WLLFhkpdM35Oedf3
|
||||||
|
Hib0VXPgJ8j/w6RK+oYKMP27RojMFXALolzRBSQu3Zbd1bD1qVhh/dO5Uyn4E3mb
|
||||||
|
2LW5+a9zuabD9wt8smSU9V5ZYw5hcR0ANN7xYmaMvGFKrNPNkI3m0c2dyj22vgg0
|
||||||
|
zQqeMze4KxZqDf/gFifJ4UIybBAgc/p1uOIceFTSYplVXJQIgFACn9l6c4Zo0GZD
|
||||||
|
H48iKQLwlxDdUSM8aHtItWxRddLCL7lYNKtu2/qu8I9NKkjx4/Kn3I9Is/f37EIn
|
||||||
|
rF3ygUg3ee5zo3fvMjlhCNs6djm+ANx2KzdZkS7UU/jb0o+OSEvoMIgZh5NNgUlC
|
||||||
|
aVR3opS3PTqwu4plN0Evh5kr3nEOx0vcIK726DwnpgNRhcG9cNcSi2UB4NYCWaw=
|
||||||
|
-----END CERTIFICATE-----`)
|
||||||
|
|
||||||
ui.Hint("you can run this with `fes run %s`", dir)
|
ui.Hint("you can run this with `fes run %s`", dir)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -95,15 +96,22 @@ func generateArchiveIndex(fsPath string, urlPath string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* helper to read the archive files */
|
/* helper to read the archive files */
|
||||||
func readArchive(w http.ResponseWriter, route string) error {
|
func readArchive(w io.Writer, route string, protcol Protocols) error {
|
||||||
fsPath := "." + route
|
switch protcol {
|
||||||
if info, err := os.Stat(fsPath); err == nil && info.IsDir() {
|
case HTTP:
|
||||||
if page, err := generateArchiveIndex(fsPath, route); err == nil {
|
fsPath := "." + route
|
||||||
w.Write([]byte(page))
|
if info, err := os.Stat(fsPath); err == nil && info.IsDir() {
|
||||||
return nil
|
if page, err := generateArchiveIndex(fsPath, route); err == nil {
|
||||||
} else {
|
w.Write([]byte(page))
|
||||||
return err
|
return nil
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
case GEMINI:
|
||||||
|
panic(errors.New("TODO"))
|
||||||
|
default:
|
||||||
|
panic(errors.New("Invalid Protocol"))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,17 +25,9 @@ func geminiHandler(w gemini.ResponseWriter, r *gemini.Request) {
|
|||||||
route = r.URL.Path
|
route = r.URL.Path
|
||||||
|
|
||||||
if strings.HasPrefix(route, "/archive") {
|
if strings.HasPrefix(route, "/archive") {
|
||||||
w.Write([]byte("# error: not implemented"))
|
err = readArchive(w, route, GEMINI)
|
||||||
// err = readArchive(w, route)
|
|
||||||
} else {
|
} else {
|
||||||
w.WriteHeader(gemini.StatusNotFound, "StatusNotFound")
|
w.WriteHeader(gemini.StatusNotFound, "StatusNotFound")
|
||||||
w.Write([]byte(`<html>
|
|
||||||
<head><title>404 Not Found</title></head>
|
|
||||||
<body>
|
|
||||||
<center><h1>404 Not Found</h1></center>
|
|
||||||
<hr><center>fes</center>
|
|
||||||
</body>
|
|
||||||
</html>`))
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -49,7 +41,7 @@ func geminiHandler(w gemini.ResponseWriter, r *gemini.Request) {
|
|||||||
|
|
||||||
var data []byte
|
var data []byte
|
||||||
if strings.HasSuffix(route, ".lua") {
|
if strings.HasSuffix(route, ".lua") {
|
||||||
data, err = render(route, reqData{path: r.URL.Path, params: params}, &Sets)
|
data, err = render(route, reqData{path: r.URL.Path, params: params}, GEMINI)
|
||||||
} else if strings.HasSuffix(route, ".md") {
|
} else if strings.HasSuffix(route, ".md") {
|
||||||
data, err = os.ReadFile(route)
|
data, err = os.ReadFile(route)
|
||||||
data = []byte(markdownToHTML(string(data)))
|
data = []byte(markdownToHTML(string(data)))
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ func httpHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
route = r.URL.Path
|
route = r.URL.Path
|
||||||
|
|
||||||
if strings.HasPrefix(route, "/archive") {
|
if strings.HasPrefix(route, "/archive") {
|
||||||
err = readArchive(w, route)
|
err = readArchive(w, route, HTTP)
|
||||||
} else {
|
} else {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
w.WriteHeader(http.StatusNotFound)
|
||||||
w.Write([]byte(`<html>
|
w.Write([]byte(`<html>
|
||||||
@@ -49,7 +49,7 @@ func httpHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
var data []byte
|
var data []byte
|
||||||
if strings.HasSuffix(route, ".lua") {
|
if strings.HasSuffix(route, ".lua") {
|
||||||
data, err = render(route, reqData{path: r.URL.Path, params: params}, &Sets)
|
data, err = render(route, reqData{path: r.URL.Path, params: params}, HTTP)
|
||||||
} else if strings.HasSuffix(route, ".md") {
|
} else if strings.HasSuffix(route, ".md") {
|
||||||
data, err = os.ReadFile(route)
|
data, err = os.ReadFile(route)
|
||||||
data = []byte(markdownToHTML(string(data)))
|
data = []byte(markdownToHTML(string(data)))
|
||||||
|
|||||||
@@ -14,14 +14,7 @@ type reqData struct {
|
|||||||
params map[string]string
|
params map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeclarativeSets struct {
|
func render(luapath string, requestData reqData, protocol Protocols) ([]byte, error) {
|
||||||
protos struct {
|
|
||||||
http bool
|
|
||||||
gemini bool
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func render(luapath string, requestData reqData, setBuffer *DeclarativeSets) ([]byte, error) {
|
|
||||||
L := lua.NewState()
|
L := lua.NewState()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
@@ -74,6 +67,36 @@ func render(luapath string, requestData reqData, setBuffer *DeclarativeSets) ([]
|
|||||||
panic("fes module did not return table")
|
panic("fes module did not return table")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := L.CallByParam(lua.P{
|
||||||
|
Fn: L.GetGlobal("require"),
|
||||||
|
NRet: 1,
|
||||||
|
Protect: true,
|
||||||
|
}, lua.LString("lib.std")); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
stdMod := L.Get(-1)
|
||||||
|
L.Pop(1)
|
||||||
|
|
||||||
|
stdTbl, ok := stdMod.(*lua.LTable)
|
||||||
|
if !ok {
|
||||||
|
panic("lib.std did not return table")
|
||||||
|
}
|
||||||
|
|
||||||
|
proto := func() string {
|
||||||
|
switch protocol {
|
||||||
|
case HTTP:
|
||||||
|
return "http"
|
||||||
|
case GEMINI:
|
||||||
|
return "gemini"
|
||||||
|
default:
|
||||||
|
return "http"
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
stdTbl.RawSetString("proto", lua.LString(proto))
|
||||||
|
tbl.RawSetString("std", stdTbl)
|
||||||
|
|
||||||
bus := L.NewTable()
|
bus := L.NewTable()
|
||||||
bus.RawSetString("url", lua.LString(requestData.path))
|
bus.RawSetString("url", lua.LString(requestData.path))
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,14 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Protocols int
|
||||||
|
|
||||||
|
const (
|
||||||
|
HTTP Protocols = iota
|
||||||
|
GEMINI
|
||||||
|
)
|
||||||
|
|
||||||
var Routes map[string]string
|
var Routes map[string]string
|
||||||
var Sets DeclarativeSets
|
|
||||||
|
|
||||||
func Start(dir string) {
|
func Start(dir string) {
|
||||||
if err := os.Chdir(dir); err != nil {
|
if err := os.Chdir(dir); err != nil {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# default
|
# test
|
||||||
|
|
||||||
```
|
```
|
||||||
fes new default
|
fes new test
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Know what you are doing?** Delete this file. Have fun!
|
> **Know what you are doing?** Delete this file. Have fun!
|
||||||
32
test/cert.pem
Normal file
32
test/cert.pem
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFmzCCA4OgAwIBAgIUZGaMDLeCAQplfhhjXb2HaL6xpFYwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwXTELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5
|
||||||
|
MQwwCgYDVQQKDANPcmcxDTALBgNVBAsMBFVuaXQxEjAQBgNVBAMMCWxvY2FsaG9z
|
||||||
|
dDAeFw0yNjAyMjQwMjUwMzVaFw0yNzAyMjQwMjUwMzVaMF0xCzAJBgNVBAYTAlVT
|
||||||
|
MQ4wDAYDVQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0eTEMMAoGA1UECgwDT3JnMQ0w
|
||||||
|
CwYDVQQLDARVbml0MRIwEAYDVQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEB
|
||||||
|
AQUAA4ICDwAwggIKAoICAQCfl+m81U9+WLBnPiJ1ZADnZC+BecXArguAdnbkgDlm
|
||||||
|
fqe1eU6M0PBmXXFHEvJYOh2oYQZ7DMbuLLvoDdjomXM4yb9Axu2KDHfflTcw3wHD
|
||||||
|
3850ganf9rwVG460gkVfUGaRiokyCvEJKd05BxKmx8Zh6G2tpetaDKm72ONYQFya
|
||||||
|
BCelYMzaBRpJ2kcPqk/gEhUSvQKVF4oDREm+sTEkCTWsjUesiG0393t3psFa/SlZ
|
||||||
|
KsNXNrb+N6y9SElKVlQOT28r9YGiDfy5PiAQiFtQse2gqC4IhG2MGi0b4mu4Qa3+
|
||||||
|
d2u3jsmn6Gqt92hKrbFOpz+Ci5GQ+zKXnE+j/h40l1J3h/aTM5/qS7malAtXySMV
|
||||||
|
zLQnJzai6IL+nBKbIOMCzP1Bns64Oo7YuuhVCx/sovrvgFF+8j4nLXOBgrx8llYB
|
||||||
|
5cvgVYkNmccXtPzd7hZI6PHgZRGOd0uBKlZ+OHeKhgdnz/a+pCUBwJe8JAzX7fzo
|
||||||
|
Z+HLy26ADx2Uywh0Rjfj4gVOSZXaGS0ne0p5PciN0xsWQdaAWPcVe6+YYRKS6l6q
|
||||||
|
aWuGaPwVsZSvNgIMMPOgUn7+s2Bxh51DhqZT4MDFUJWXFmTnyhHg3Cq7pWJR7pv2
|
||||||
|
erv5q32b8iah5o+CP4W3FeZX1CcBuiIsrimhvZZIa5W2vzpkLHbWgI2XGbx8yKRX
|
||||||
|
owIDAQABo1MwUTAdBgNVHQ4EFgQUcyq+ZZWmAUejOPEQpHpl4hOllHswHwYDVR0j
|
||||||
|
BBgwFoAUcyq+ZZWmAUejOPEQpHpl4hOllHswDwYDVR0TAQH/BAUwAwEB/zANBgkq
|
||||||
|
hkiG9w0BAQsFAAOCAgEANwdjxlPHqvOOyNTFJcFhcNff3862/74CyCiglrstk/ea
|
||||||
|
txjyHxXFwXOtyAtm0tqaQPpzHWFM5MDqVD7Qip4aZrPcRvvfJ8zxXuakrgy7oI6i
|
||||||
|
Wl4/BXzvIoxh8MyFVC7VdGmuv11fq091RaNPlnz5lH9Qxhb6QCGbk73PjTXxD/7A
|
||||||
|
yusNiXuJvx3oRhLLGuksotFKEnngOq21Jla3ZPUmJTLAZdk/joXITk5Q64ZBp5uD
|
||||||
|
rpxFZDtdHTBuL3nmNPUHixsxQRFzCSloufRlatdI2ldDc+d2WLLFhkpdM35Oedf3
|
||||||
|
Hib0VXPgJ8j/w6RK+oYKMP27RojMFXALolzRBSQu3Zbd1bD1qVhh/dO5Uyn4E3mb
|
||||||
|
2LW5+a9zuabD9wt8smSU9V5ZYw5hcR0ANN7xYmaMvGFKrNPNkI3m0c2dyj22vgg0
|
||||||
|
zQqeMze4KxZqDf/gFifJ4UIybBAgc/p1uOIceFTSYplVXJQIgFACn9l6c4Zo0GZD
|
||||||
|
H48iKQLwlxDdUSM8aHtItWxRddLCL7lYNKtu2/qu8I9NKkjx4/Kn3I9Is/f37EIn
|
||||||
|
rF3ygUg3ee5zo3fvMjlhCNs6djm+ANx2KzdZkS7UU/jb0o+OSEvoMIgZh5NNgUlC
|
||||||
|
aVR3opS3PTqwu4plN0Evh5kr3nEOx0vcIK726DwnpgNRhcG9cNcSi2UB4NYCWaw=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
local fes = require("fes")
|
|
||||||
local site = fes.fes()
|
|
||||||
|
|
||||||
-- site.copyright = fes.util.copyright("https://example.com", "vx-clutch")
|
|
||||||
|
|
||||||
site:h(1, "Hello, World!")
|
|
||||||
|
|
||||||
return site
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# default
|
|
||||||
|
|
||||||
```
|
|
||||||
fes new default
|
|
||||||
```
|
|
||||||
|
|
||||||
> **Know what you are doing?** Delete this file. Have fun!
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
Inside your Fes project, you'll see the following directories and files:
|
|
||||||
|
|
||||||
```
|
|
||||||
.
|
|
||||||
├── Fes.toml
|
|
||||||
├── README.md
|
|
||||||
└── www
|
|
||||||
└── index.lua
|
|
||||||
```
|
|
||||||
|
|
||||||
Fes looks for `.lua` files in the `www/` directory. Each file is exposed as a route based on its file name.
|
|
||||||
|
|
||||||
## Commands
|
|
||||||
|
|
||||||
All commands are run from the root of the project, from a terminal:
|
|
||||||
|
|
||||||
| Command | Action |
|
|
||||||
| :------------------------ | :----------------------------------------------- |
|
|
||||||
| `fes run .` | Runs the project at `.` |
|
|
||||||
|
|
||||||
## What to learn more?
|
|
||||||
|
|
||||||
Check out [Fes's docs](https://docs.vxserver.dev/static/fes.html).
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIC8zCCAdugAwIBAgIUWobZlV5Gp72Z4LUD/hjRb2aa+GgwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI2MDIxNTAzMDgxOVoXDTI3MDIx
|
|
||||||
NTAzMDgxOVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
|
|
||||||
AAOCAQ8AMIIBCgKCAQEAxvNs7/1cJ/6kdlo7CAwIUc+d8L5cbqw3KKYMl/9JSnqp
|
|
||||||
HutIcl23LrF0ylClnAkTbuuDmzED73Z8788eaoIsjmwNA5yapkmDkjh/y8CRg1+2
|
|
||||||
8iEuneHAeKZosHGdfjBcOzLVPo713Mw2m3yXeeVLfn/FLUql3l/Au0xu+oVT4XB/
|
|
||||||
aZ//j3spgT4xIFggXMYchs9EW1pJpD4pnKDo+ZBATuAJjDy4OstGKzFiEiNSWfiI
|
|
||||||
K8VLM6V74xdEiojcyy2TCHDSYOIozsB5iQRV9PcXyyIEGw7wTx/o9wrkShff+pyn
|
|
||||||
seLJ644FnGRvEkZpTWg18NTC18JNLVGqmuSqbwzGZQIDAQABoz0wOzAaBgNVHREE
|
|
||||||
EzARgglsb2NhbGhvc3SHBH8AAAEwHQYDVR0OBBYEFI/tgi60jQUeMqILEeZf7m80
|
|
||||||
MWB1MA0GCSqGSIb3DQEBCwUAA4IBAQATIwsWSuPBFb/n4q60QgScVIGjTIHTJGUT
|
|
||||||
di6ButyVug4zCltsMIw+VwfigRk77eyqZjbdm9Tmn/1cUTxLnNMBNyUPabojmf32
|
|
||||||
ItWGCLmI9QBW2/d8oK1rxLiDDQ5FwzWloeavwJC2E3xKy5xmcQicv1iTvpJnLRFJ
|
|
||||||
amyrY9dDVo0qAsLnnOmwc0OEnzpcYclegTOD9jUgEMJ00oLrYsWqXC8KvPaWcIu7
|
|
||||||
MiCj9j+U9ncU0fWE0WCOZr8VOgjtJeiHN1CLPOWbsSaZRWLBWlgF4AJGI2VXVM7d
|
|
||||||
BAb5y4cDIqmDnrTl3DUk8BlCnMdHopvl1ZrZWKgQJbfhvOagUv91
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDG82zv/Vwn/qR2
|
|
||||||
WjsIDAhRz53wvlxurDcopgyX/0lKeqke60hyXbcusXTKUKWcCRNu64ObMQPvdnzv
|
|
||||||
zx5qgiyObA0DnJqmSYOSOH/LwJGDX7byIS6d4cB4pmiwcZ1+MFw7MtU+jvXczDab
|
|
||||||
fJd55Ut+f8UtSqXeX8C7TG76hVPhcH9pn/+PeymBPjEgWCBcxhyGz0RbWkmkPimc
|
|
||||||
oOj5kEBO4AmMPLg6y0YrMWISI1JZ+IgrxUszpXvjF0SKiNzLLZMIcNJg4ijOwHmJ
|
|
||||||
BFX09xfLIgQbDvBPH+j3CuRKF9/6nKex4snrjgWcZG8SRmlNaDXw1MLXwk0tUaqa
|
|
||||||
5KpvDMZlAgMBAAECggEAFR1lvOzDWJ1OgB8gb8CzK1ehGBlj/vz5F6/T21flQ+nT
|
|
||||||
xCvNcxHeLK75ybUYdoCCFv4Y6CIiHEqThPIS9NPe/bibAvyebzKTK7QiYBIOf4Zr
|
|
||||||
iLQb2fbJMiTbLIrKX8erKj9BYZPTpTzpOMRW4UGEKydNWnq3MuwvrNE2YBFBb0YM
|
|
||||||
3RcSxs+nEkYs0sbZGtkqy2gYGbr0WcWHi3tNRWTT5FXM5VY84XY8QCPqDTj5fXys
|
|
||||||
DwDFQDBJc0l/IYRcaen+4UNliVaJRto/ZZaqhwnPra1d16PLYhWmfAkYKgWCEIhw
|
|
||||||
+b/+mV+6oUnORGbmq1TiSzZ9U9WqNwSo/8ZoNC8WywKBgQDm7SK2zFyXx4SdnVfL
|
|
||||||
XikJCYLdnsLaaP/Z7iCZgt7oaHUDg6Eb/SAqdEB/YPcCHXox6ChUOqHe7ee7ROCk
|
|
||||||
1wD3xI+kV4E9yZqs2zeRJrv8W8Q0JjJXdVrXy6vFQ0z/132QNXLJpr7KXGctE9zX
|
|
||||||
XheT+yisgJQSd6O7HX1Ow67EKwKBgQDcjX7tThSw+dloyEywbi3dA8VmGVuH3UPk
|
|
||||||
3zgD6dEA/xt/OpD3LgDgHOLIL+lbR4LAfxjS8RTHGOON8iVcCAi6k7gAf+0WU2Uh
|
|
||||||
6GkA4gUM6mx1zSl7k4/vmJa1WpxG11bCdWPvNt3X0cvYMGNPfhTITqz4F81M6+9p
|
|
||||||
ZEmaCGaHrwKBgGGmSzSjbFAeZXzE6TgtJAsXQ4h1tw3msrI0GQLxLVN3wGtxAPK1
|
|
||||||
8iEhsZhrp2f0kRSDiHI9rO95CLHO6XOrG1SqgNdMzXEUTFzmAjRV/c4z+97VfBox
|
|
||||||
nO19ybALyoaxV/5gK58L7MfjlRmhuZQ0zKGd5lAzuumoP8tDKBbjdoarAoGAcNJ9
|
|
||||||
DH21vfaBjcVw3YvvMDE+qITuOqkokwrRB8dzIBRgB4x5HcjNr9d29zrzH7uMGlap
|
|
||||||
5zZmD5ceyL0G+XYuqOrp5G+MY7BTeq3+EPKN7NZ6lyRVRR7uMX2YEruAWAjOG/mb
|
|
||||||
HoKtpzpuEXBnTQHNNc5xUxQx9Fh5ByvDLuV/NYcCgYEAy/An+fPP6Lkl4nwbcnbP
|
|
||||||
npAimzB6z25ftFeNMfggJYOukQomAeuwS5QYdLvqtPdqjtrqRQJrXFW9q0Nmt5HM
|
|
||||||
h0WuMCrKDWfYdZbZ8E6y3zqUXb5J66M2mcu+8ED6zUvktOBHXgIS7YnXYf46illx
|
|
||||||
3+8QDk1ufotloNSokoM/BTw=
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
[req]
|
|
||||||
default_bits = 2048
|
|
||||||
prompt = no
|
|
||||||
default_md = sha256
|
|
||||||
x509_extensions = v3_req
|
|
||||||
distinguished_name = dn
|
|
||||||
|
|
||||||
[dn]
|
|
||||||
CN = localhost
|
|
||||||
|
|
||||||
[v3_req]
|
|
||||||
subjectAltName = @alt_names
|
|
||||||
|
|
||||||
[alt_names]
|
|
||||||
DNS.1 = localhost
|
|
||||||
IP.1 = 127.0.0.1
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
local fes = require("fes")
|
|
||||||
local site = fes.fes("gemini")
|
|
||||||
|
|
||||||
-- site.copyright = fes.util.copyright("https://example.com", "vx-clutch")
|
|
||||||
|
|
||||||
site:h(1, "Hello, World!")
|
|
||||||
|
|
||||||
site:note("Hello, World!. djsaklllllll\nlllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll")
|
|
||||||
|
|
||||||
return site
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
# error
|
|
||||||
|
|
||||||
This is expected to return the following error:
|
|
||||||
|
|
||||||
```
|
|
||||||
Error loading page: www/index.lua line:6(column:6) near 'return': syntax error
|
|
||||||
```
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
local fes = require("fes")
|
|
||||||
local site = fes.fes()
|
|
||||||
|
|
||||||
site.
|
|
||||||
|
|
||||||
return site
|
|
||||||
52
test/key.pem
Normal file
52
test/key.pem
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQCfl+m81U9+WLBn
|
||||||
|
PiJ1ZADnZC+BecXArguAdnbkgDlmfqe1eU6M0PBmXXFHEvJYOh2oYQZ7DMbuLLvo
|
||||||
|
DdjomXM4yb9Axu2KDHfflTcw3wHD3850ganf9rwVG460gkVfUGaRiokyCvEJKd05
|
||||||
|
BxKmx8Zh6G2tpetaDKm72ONYQFyaBCelYMzaBRpJ2kcPqk/gEhUSvQKVF4oDREm+
|
||||||
|
sTEkCTWsjUesiG0393t3psFa/SlZKsNXNrb+N6y9SElKVlQOT28r9YGiDfy5PiAQ
|
||||||
|
iFtQse2gqC4IhG2MGi0b4mu4Qa3+d2u3jsmn6Gqt92hKrbFOpz+Ci5GQ+zKXnE+j
|
||||||
|
/h40l1J3h/aTM5/qS7malAtXySMVzLQnJzai6IL+nBKbIOMCzP1Bns64Oo7YuuhV
|
||||||
|
Cx/sovrvgFF+8j4nLXOBgrx8llYB5cvgVYkNmccXtPzd7hZI6PHgZRGOd0uBKlZ+
|
||||||
|
OHeKhgdnz/a+pCUBwJe8JAzX7fzoZ+HLy26ADx2Uywh0Rjfj4gVOSZXaGS0ne0p5
|
||||||
|
PciN0xsWQdaAWPcVe6+YYRKS6l6qaWuGaPwVsZSvNgIMMPOgUn7+s2Bxh51DhqZT
|
||||||
|
4MDFUJWXFmTnyhHg3Cq7pWJR7pv2erv5q32b8iah5o+CP4W3FeZX1CcBuiIsrimh
|
||||||
|
vZZIa5W2vzpkLHbWgI2XGbx8yKRXowIDAQABAoICAENZb5lyB5cRRHh9XztdFYiQ
|
||||||
|
3f9s7UhP6qiu1aO+fPrFDm9mHwEMF7eLTYep9j3HYMazE3IQRU8z76SRW21lfJuF
|
||||||
|
gEGM8aeldV0UcnMcWXlY1J6ULaVHUb4yn/mLVE1R98cJyLYmqeutEB/F3VgmzJB6
|
||||||
|
7vYuI/EfkO2mLOMMXkfc4wJGpIyJRLvP8tcoj4bG+r+qphFXGrYgNmLUEiHcBRup
|
||||||
|
j4q/FCBfP2qSI90LI0zu3/rJK1aDFlHW1J8baWOUoBzUAX3rGzDth8iSUr7uJ5L6
|
||||||
|
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
|
||||||
|
h6CgX4Gc3+bhvKx36XYxVwScPJUWsQ==
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
BIN
test/static/seal.png
Normal file
BIN
test/static/seal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.3 MiB |
49
test/www/index.lua
Normal file
49
test/www/index.lua
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
local fes = require("fes")
|
||||||
|
local site = fes.fes()
|
||||||
|
|
||||||
|
local std = fes.std
|
||||||
|
local u = fes.util
|
||||||
|
|
||||||
|
site.copyright = std.link("https://fsdproject.org/", "fSD")
|
||||||
|
|
||||||
|
site:banner(table.concat {
|
||||||
|
std.h(1, "Testing Page"),
|
||||||
|
})
|
||||||
|
|
||||||
|
site:note(table.concat {
|
||||||
|
std.h(1, "Example syntax features"),
|
||||||
|
std.h(2, "Paragraphs"),
|
||||||
|
std.p("This is a paragraph."),
|
||||||
|
std.h(2, "Codeblocks"),
|
||||||
|
std.codeblock([[
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
puts("Hello, World!");
|
||||||
|
return 0;
|
||||||
|
}]]),
|
||||||
|
std.h(2, "Inline Codeblocks"),
|
||||||
|
std.inline([[puts("Hello, World!");]]),
|
||||||
|
std.h(2, "Links"),
|
||||||
|
std.link("geminiprotocol.net/"),
|
||||||
|
std.h(2, "Lists"),
|
||||||
|
std.list {
|
||||||
|
"Item 1",
|
||||||
|
"Item 2",
|
||||||
|
"Item 3",
|
||||||
|
},
|
||||||
|
std.h(2, "Blockquotes"),
|
||||||
|
std.blockquote([[
|
||||||
|
"UNIX is very simple" - Dennis Ritchie
|
||||||
|
<br>
|
||||||
|
"GNU's Not UNIX" - Richard Stallman
|
||||||
|
]]),
|
||||||
|
std.h(2, "Rules"),
|
||||||
|
std.rule(),
|
||||||
|
std.h(2, "Images"),
|
||||||
|
std.image("fluffy baby seal", "/static/seal.png"),
|
||||||
|
std.h(2, "Files"),
|
||||||
|
std.file("seal.png", "/static/seal.png"),
|
||||||
|
})
|
||||||
|
|
||||||
|
return site
|
||||||
Reference in New Issue
Block a user