diff --git a/Brewfile b/Brewfile deleted file mode 100644 index 85826cd..0000000 --- a/Brewfile +++ /dev/null @@ -1,2 +0,0 @@ -# build deps -brew "go@1.25" diff --git a/Makefile b/Makefile index 0bd2067..1284076 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ deps: $(GO) mod download 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" lint: diff --git a/TODO b/TODO new file mode 100644 index 0000000..8896b4e --- /dev/null +++ b/TODO @@ -0,0 +1,4 @@ + * Fix Gemini rendering + * Add Gemini command-line options + * Better gemini errors + * Fix build steps newlines diff --git a/lib/fes.lua b/lib/fes.lua index 968c037..fd5c549 100644 --- a/lib/fes.lua +++ b/lib/fes.lua @@ -105,9 +105,8 @@ local default_gemini_footer = [[ {{COPYRIGHT}} ]] -function M.fes(proto, header, footer) - proto = proto or "http" - std.proto = proto +function M.fes(header, footer) + local proto = std.proto local config = {} local site_config = {} @@ -179,6 +178,14 @@ function M:build() ) 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 return table.concat(self.parts, "\n") diff --git a/lib/std.lua b/lib/std.lua index 8418d60..fa3409c 100644 --- a/lib/std.lua +++ b/lib/std.lua @@ -1,6 +1,7 @@ local M = {} M.proto = "http" +M.__fes_banner_set = false local function isHttp() return M.proto == "http" @@ -10,18 +11,10 @@ local function isGemini() return M.proto == "gemini" end -local function esc(s) - s = s or "" - s = s:gsub("&", "&") - s = s:gsub("<", "<") - s = s:gsub(">", ">") - return s -end - M.p = function(s) s = s or "" if isHttp() then - return "

" .. esc(s) .. "

" + return "

" .. s .. "

" elseif isGemini() then return s end @@ -33,7 +26,7 @@ M.h = function(level, s) if level > 6 then level = 6 end s = s or "" if isHttp() then - return "" .. esc(s) .. "" + return "" .. s .. "" elseif isGemini() then return string.rep("#", level) .. " " .. s end @@ -42,7 +35,7 @@ end M.codeblock = function(s) s = s or "" if isHttp() then - return "
" .. esc(s) .. "
" + return "
" .. s .. "
" elseif isGemini() then return "```\n" .. s .. "\n```" end @@ -51,17 +44,17 @@ end M.inline = function(s) s = s or "" if isHttp() then - return "" .. esc(s) .. "" + return "" .. s .. "" elseif isGemini() then return "`" .. s .. "`" end end -M.link = function(text, url) - text = text or "" +M.link = function(url, text) url = url or "" + text = text or url if isHttp() then - return "" .. esc(text) .. "" + return "" .. text .. "" elseif isGemini() then return "=> " .. url .. " " .. text end @@ -73,7 +66,7 @@ M.list = function(items, ordered) local tag = ordered and "ol" or "ul" local out = "<" .. tag .. ">" for _, v in ipairs(items) do - out = out .. "
  • " .. esc(v) .. "
  • " + out = out .. "
  • " .. v .. "
  • " end out = out .. "" return out @@ -93,7 +86,7 @@ end M.blockquote = function(s) s = s or "" if isHttp() then - return "
    " .. esc(s) .. "
    " + return "
    " .. s .. "
    " elseif isGemini() then return "> " .. s end @@ -111,7 +104,7 @@ M.image = function(alt, src) alt = alt or "" src = src or "" if isHttp() then - return "\""" + return "\""" elseif isGemini() then return "=> " .. src .. " " .. alt end @@ -121,7 +114,7 @@ M.file = function(text, url) text = text or "" url = url or "" if isHttp() then - return "" .. esc(text) .. "" + return "" .. text .. "" elseif isGemini() then return "=> " .. url .. " " .. text end @@ -130,53 +123,25 @@ end M.note = function(text) text = text or "" if isHttp() then - return "
    " .. esc(text) .. "
    " + return "
    " .. text .. "
    " elseif isGemini() then - local width = 31 + return "\n\n" .. text .. "\n\n" + end +end - local function wrap_line(line) - local out = {} - local i = 1 - local len = #line +M.banner = function (text) + text = text or "" - if len == 0 then - out[#out + 1] = "" - return out - end + if M.__fes_banner_set then + error("Page already contains header") + return "" + end - while i <= len do - out[#out + 1] = line:sub(i, i + width - 1) - i = i + width - end - - 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") + M.__fes_banner_set = true + if isHttp() then + return "
    " .. text .. "
    " + elseif isGemini() then + return text .. "\n" end end diff --git a/modules/new/new.go b/modules/new/new.go index 2ae216c..b82dddd 100644 --- a/modules/new/new.go +++ b/modules/new/new.go @@ -105,11 +105,112 @@ All commands are run from the root of the project, from a terminal: | 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? 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 +Blsvz68lSM4QslbS2OOfcATJrE5Apex+kTOas023BPVJgwfFCmey3mUdk4+sIG+I +YpvrfUHBAbhRt1itGjjx/BH3HVtkwKsm3nNNgE8qS0qmziGVa60amLng0OgD4SOH +QKWrotcojYlWHywdHNAmiaWP+ZV9U0u4T59dkHhjqBoPuY64kNddRCLYItszqOmC +tamnflcoFPThdBnDpnXhLX+MnvQKIO2K2QTKjdYrkSMvEC/m96H49Vf4w+Fe3coc +SLsyMqHmYSG3+QtFN3JSmqDdBLQ+bFK0KZOk3IE2UK+lvabmtHuGLkYguur/fOnG +FvxcC+MIHHFrtSfqfvIrXeGFqe2Fb6DIKdMJFPV8iP5Px91A0GAGeabyktyya1n5 +kk5nMJY3A7rTmnDO2PUBAoIBAQDSd+pvNGDf/We74+NODKQBcleCfF0NNzvRIuYH +9vel5jhyD28Y30XQS7+YBo3Y5Yo5pVlJ425Z5CveZOmr4VImuYG8LTbbGYY8ns3c +R/IdP1ByAcIa1eRGQNcKHid7RW4aEoFdvW3jZNj6/ukbJwd9ZHOt4HEUv5MOObn7 +VXiXiwHjVy3X4uD5j0bHS4owd7S3Ygg0OneUzX3XJ+8qUgfU9B+lD3SbtsI4baoU +qUKcQc/0yXKvJvoz9oX2tjQOHqGrGwHdootc2CLnr0PMI7fKBwT3k63B+24xEGcx +OAPc5tUuiqIewiCn1oZbeCxmNnnimkAjDfG2KXMXj1R1G96BAoIBAQDCHnTNQhXH +tcfwnxj86E+Zd7ORS7iH/5eWvnspt2pnNCpufLFQlbdiL3d9ysSN9nw3+y15/o83 +R79s7fLdC0+blc6q/ZQEdB1C+8YQa0nTlqqlZWVbRPjQUV+SfGssaZFEO4W7QWh3 +hJL14HbWUFC3XSdMAeKTNOcgvfVvQ9M8HlJI1ZPo4Pe4rGNFIEsKUz/6HVE7HFgQ +OwcLSxZlSQSQ6/YErP/XJoyQUPjHldAjphV/rn28cvh2quoI35fbBuZu5pyKLXTg +RKbdWbeoIZTthRojpqnfqnIR+rPXIIiaMYhStdPshNUxLL7DX+/3yI05qq8R+yqa +2gLb2mJltuwjAoIBAF0WQI/ywK4Q7CKEBnLs0FT7d4z06EsCFOjI4KjBKIMtseVw +whhkGAKqnhDlRTObQmmAol81wgbsDiMMyvUEcUtDXQgXj12UinShYDd/cqxQ5omm +EW3BEHeqEfIdqCSzbqEFckY9lC6w2e8Zc4xY1M028psC28DrgmUWTxXEldOg3bLp +ShNj+1Eld46J8JLDPyCksTA4c89Sm8ffl75GDcS4PI7KqS59xKUki8cbnaRyz0Fb +H+gr+xmkfVfC+n8MOUDubwLR84Wa6sVCFWBio9UtCZteq8lSJUh6EsoIFl1LkxpE +orOr9LmG/mHSYwDKM1pwEtHuRuvkpUzUTeyF6QECggEAbm/vWZtgUsdbocyR5cix +CImuUlo2+MBz2KIz5c7grShjf4pXQpZ6x1Rj8d/7JRz3HM482Cv4BKZABNP3GMTH +nKeE9YjgvgvlXedpjovLa6JLIV/nYx6BQ9sXuXopaxIAQEZw1dDngx+ckGAMm+8D +jN5lbfugkMlHOTx5Nrzqn0hM3f0McjATHzCMJZayuoQUYNJvFWcRvuImJsmoSyVY +gK6Nv6lAwIHA9JXsg3f6+10Q3BxEkoMCUlj4XuX+OfDaBnwS0RX9aV4FZOcW8oNw +fBT+gwvdl08cKJht2lU7AiZt/UhO8j+8HobrXLHnDxw9JHKzuVIgsgqYF8ZNtrpz +6wKCAQEAqJc9xfNYL2jyJTVBvqX34Uct9xV1fq7z45B3gpPHj4tc0dBOIwPKSsu8 +rGyefPuMDvbecJoaXqRZGQEcv03ecLVtHHDCsJcWavth9sCQJW9mnOxjOnLHdGnl +h2yIV4iVzNEx5XA1+0JRAAwFMXrC9LUZDTT61opjohMJSEySo/HVekoWG9A0bQGn +Ui+JbtLeuuCwwAGSgdAhVkjr27ANyFtjR63KVrDvSLbYFyZXKxrRYnZWs92Ho/g6 +oTLnUSmkbLlhsUDjknAaNfp+enETSoPHcpkd7MeqVw2oYrLw6MCo4h2tBsIgtZEd +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) diff --git a/modules/server/archive.go b/modules/server/archive.go index 4d48fc0..f006e3c 100644 --- a/modules/server/archive.go +++ b/modules/server/archive.go @@ -1,8 +1,9 @@ package server import ( + "errors" "fmt" - "net/http" + "io" "os" "path" "path/filepath" @@ -95,15 +96,22 @@ func generateArchiveIndex(fsPath string, urlPath string) (string, error) { } /* helper to read the archive files */ -func readArchive(w http.ResponseWriter, route string) error { - fsPath := "." + route - if info, err := os.Stat(fsPath); err == nil && info.IsDir() { - if page, err := generateArchiveIndex(fsPath, route); err == nil { - w.Write([]byte(page)) - return nil - } else { - return err +func readArchive(w io.Writer, route string, protcol Protocols) error { + switch protcol { + case HTTP: + fsPath := "." + route + if info, err := os.Stat(fsPath); err == nil && info.IsDir() { + if page, err := generateArchiveIndex(fsPath, route); err == nil { + w.Write([]byte(page)) + return nil + } else { + return err + } } + case GEMINI: + panic(errors.New("TODO")) + default: + panic(errors.New("Invalid Protocol")) } return nil } diff --git a/modules/server/gemini.go b/modules/server/gemini.go index f668781..0e94ec6 100644 --- a/modules/server/gemini.go +++ b/modules/server/gemini.go @@ -25,17 +25,9 @@ func geminiHandler(w gemini.ResponseWriter, r *gemini.Request) { route = r.URL.Path if strings.HasPrefix(route, "/archive") { - w.Write([]byte("# error: not implemented")) - // err = readArchive(w, route) + err = readArchive(w, route, GEMINI) } else { w.WriteHeader(gemini.StatusNotFound, "StatusNotFound") - w.Write([]byte(` -404 Not Found - -

    404 Not Found

    -
    fes
    - -`)) } return } @@ -49,7 +41,7 @@ func geminiHandler(w gemini.ResponseWriter, r *gemini.Request) { var data []byte 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") { data, err = os.ReadFile(route) data = []byte(markdownToHTML(string(data))) diff --git a/modules/server/http.go b/modules/server/http.go index 6577e95..7b370b1 100644 --- a/modules/server/http.go +++ b/modules/server/http.go @@ -26,7 +26,7 @@ func httpHandler(w http.ResponseWriter, r *http.Request) { route = r.URL.Path if strings.HasPrefix(route, "/archive") { - err = readArchive(w, route) + err = readArchive(w, route, HTTP) } else { w.WriteHeader(http.StatusNotFound) w.Write([]byte(` @@ -49,7 +49,7 @@ func httpHandler(w http.ResponseWriter, r *http.Request) { var data []byte 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") { data, err = os.ReadFile(route) data = []byte(markdownToHTML(string(data))) diff --git a/modules/server/render.go b/modules/server/render.go index f41e205..95422cc 100644 --- a/modules/server/render.go +++ b/modules/server/render.go @@ -14,14 +14,7 @@ type reqData struct { params map[string]string } -type DeclarativeSets struct { - protos struct { - http bool - gemini bool - } -} - -func render(luapath string, requestData reqData, setBuffer *DeclarativeSets) ([]byte, error) { +func render(luapath string, requestData reqData, protocol Protocols) ([]byte, error) { L := lua.NewState() defer L.Close() @@ -74,6 +67,36 @@ func render(luapath string, requestData reqData, setBuffer *DeclarativeSets) ([] 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.RawSetString("url", lua.LString(requestData.path)) diff --git a/modules/server/server.go b/modules/server/server.go index b98b1e8..8b7a787 100644 --- a/modules/server/server.go +++ b/modules/server/server.go @@ -11,8 +11,14 @@ import ( "sync" ) +type Protocols int + +const ( + HTTP Protocols = iota + GEMINI +) + var Routes map[string]string -var Sets DeclarativeSets func Start(dir string) { if err := os.Chdir(dir); err != nil { diff --git a/test/default/README.md b/test/README.md similarity index 96% rename from test/default/README.md rename to test/README.md index 7e8b977..748b9e4 100644 --- a/test/default/README.md +++ b/test/README.md @@ -1,7 +1,7 @@ -# default +# test ``` -fes new default +fes new test ``` > **Know what you are doing?** Delete this file. Have fun! diff --git a/test/cert.pem b/test/cert.pem new file mode 100644 index 0000000..8b87bde --- /dev/null +++ b/test/cert.pem @@ -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----- diff --git a/test/default/www/index.lua b/test/default/www/index.lua deleted file mode 100644 index e828f38..0000000 --- a/test/default/www/index.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/test/default_gmi/README.md b/test/default_gmi/README.md deleted file mode 100644 index 7e8b977..0000000 --- a/test/default_gmi/README.md +++ /dev/null @@ -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). \ No newline at end of file diff --git a/test/default_gmi/cert.pem b/test/default_gmi/cert.pem deleted file mode 100644 index 7034838..0000000 --- a/test/default_gmi/cert.pem +++ /dev/null @@ -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----- diff --git a/test/default_gmi/key.pem b/test/default_gmi/key.pem deleted file mode 100644 index f71e8a9..0000000 --- a/test/default_gmi/key.pem +++ /dev/null @@ -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----- diff --git a/test/default_gmi/localhost.cnf b/test/default_gmi/localhost.cnf deleted file mode 100644 index 9f88d19..0000000 --- a/test/default_gmi/localhost.cnf +++ /dev/null @@ -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 diff --git a/test/default_gmi/www/index.lua b/test/default_gmi/www/index.lua deleted file mode 100644 index f1fe9b1..0000000 --- a/test/default_gmi/www/index.lua +++ /dev/null @@ -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 diff --git a/test/error/README.md b/test/error/README.md deleted file mode 100644 index 8acd1c3..0000000 --- a/test/error/README.md +++ /dev/null @@ -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 -``` diff --git a/test/error/www/index.lua b/test/error/www/index.lua deleted file mode 100644 index 68a918e..0000000 --- a/test/error/www/index.lua +++ /dev/null @@ -1,6 +0,0 @@ -local fes = require("fes") -local site = fes.fes() - -site. - -return site diff --git a/test/key.pem b/test/key.pem new file mode 100644 index 0000000..9aafa51 --- /dev/null +++ b/test/key.pem @@ -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 +Blsvz68lSM4QslbS2OOfcATJrE5Apex+kTOas023BPVJgwfFCmey3mUdk4+sIG+I +YpvrfUHBAbhRt1itGjjx/BH3HVtkwKsm3nNNgE8qS0qmziGVa60amLng0OgD4SOH +QKWrotcojYlWHywdHNAmiaWP+ZV9U0u4T59dkHhjqBoPuY64kNddRCLYItszqOmC +tamnflcoFPThdBnDpnXhLX+MnvQKIO2K2QTKjdYrkSMvEC/m96H49Vf4w+Fe3coc +SLsyMqHmYSG3+QtFN3JSmqDdBLQ+bFK0KZOk3IE2UK+lvabmtHuGLkYguur/fOnG +FvxcC+MIHHFrtSfqfvIrXeGFqe2Fb6DIKdMJFPV8iP5Px91A0GAGeabyktyya1n5 +kk5nMJY3A7rTmnDO2PUBAoIBAQDSd+pvNGDf/We74+NODKQBcleCfF0NNzvRIuYH +9vel5jhyD28Y30XQS7+YBo3Y5Yo5pVlJ425Z5CveZOmr4VImuYG8LTbbGYY8ns3c +R/IdP1ByAcIa1eRGQNcKHid7RW4aEoFdvW3jZNj6/ukbJwd9ZHOt4HEUv5MOObn7 +VXiXiwHjVy3X4uD5j0bHS4owd7S3Ygg0OneUzX3XJ+8qUgfU9B+lD3SbtsI4baoU +qUKcQc/0yXKvJvoz9oX2tjQOHqGrGwHdootc2CLnr0PMI7fKBwT3k63B+24xEGcx +OAPc5tUuiqIewiCn1oZbeCxmNnnimkAjDfG2KXMXj1R1G96BAoIBAQDCHnTNQhXH +tcfwnxj86E+Zd7ORS7iH/5eWvnspt2pnNCpufLFQlbdiL3d9ysSN9nw3+y15/o83 +R79s7fLdC0+blc6q/ZQEdB1C+8YQa0nTlqqlZWVbRPjQUV+SfGssaZFEO4W7QWh3 +hJL14HbWUFC3XSdMAeKTNOcgvfVvQ9M8HlJI1ZPo4Pe4rGNFIEsKUz/6HVE7HFgQ +OwcLSxZlSQSQ6/YErP/XJoyQUPjHldAjphV/rn28cvh2quoI35fbBuZu5pyKLXTg +RKbdWbeoIZTthRojpqnfqnIR+rPXIIiaMYhStdPshNUxLL7DX+/3yI05qq8R+yqa +2gLb2mJltuwjAoIBAF0WQI/ywK4Q7CKEBnLs0FT7d4z06EsCFOjI4KjBKIMtseVw +whhkGAKqnhDlRTObQmmAol81wgbsDiMMyvUEcUtDXQgXj12UinShYDd/cqxQ5omm +EW3BEHeqEfIdqCSzbqEFckY9lC6w2e8Zc4xY1M028psC28DrgmUWTxXEldOg3bLp +ShNj+1Eld46J8JLDPyCksTA4c89Sm8ffl75GDcS4PI7KqS59xKUki8cbnaRyz0Fb +H+gr+xmkfVfC+n8MOUDubwLR84Wa6sVCFWBio9UtCZteq8lSJUh6EsoIFl1LkxpE +orOr9LmG/mHSYwDKM1pwEtHuRuvkpUzUTeyF6QECggEAbm/vWZtgUsdbocyR5cix +CImuUlo2+MBz2KIz5c7grShjf4pXQpZ6x1Rj8d/7JRz3HM482Cv4BKZABNP3GMTH +nKeE9YjgvgvlXedpjovLa6JLIV/nYx6BQ9sXuXopaxIAQEZw1dDngx+ckGAMm+8D +jN5lbfugkMlHOTx5Nrzqn0hM3f0McjATHzCMJZayuoQUYNJvFWcRvuImJsmoSyVY +gK6Nv6lAwIHA9JXsg3f6+10Q3BxEkoMCUlj4XuX+OfDaBnwS0RX9aV4FZOcW8oNw +fBT+gwvdl08cKJht2lU7AiZt/UhO8j+8HobrXLHnDxw9JHKzuVIgsgqYF8ZNtrpz +6wKCAQEAqJc9xfNYL2jyJTVBvqX34Uct9xV1fq7z45B3gpPHj4tc0dBOIwPKSsu8 +rGyefPuMDvbecJoaXqRZGQEcv03ecLVtHHDCsJcWavth9sCQJW9mnOxjOnLHdGnl +h2yIV4iVzNEx5XA1+0JRAAwFMXrC9LUZDTT61opjohMJSEySo/HVekoWG9A0bQGn +Ui+JbtLeuuCwwAGSgdAhVkjr27ANyFtjR63KVrDvSLbYFyZXKxrRYnZWs92Ho/g6 +oTLnUSmkbLlhsUDjknAaNfp+enETSoPHcpkd7MeqVw2oYrLw6MCo4h2tBsIgtZEd +h6CgX4Gc3+bhvKx36XYxVwScPJUWsQ== +-----END PRIVATE KEY----- diff --git a/test/static/seal.png b/test/static/seal.png new file mode 100644 index 0000000..bb47029 Binary files /dev/null and b/test/static/seal.png differ diff --git a/test/www/index.lua b/test/www/index.lua new file mode 100644 index 0000000..0e17c10 --- /dev/null +++ b/test/www/index.lua @@ -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 + +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 +
    +"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