diff --git a/modules/server/http.go b/modules/server/http.go new file mode 100644 index 0000000..1c93d20 --- /dev/null +++ b/modules/server/http.go @@ -0,0 +1,64 @@ +package server + +import ( + "fes/modules/config" + "fes/modules/ui" + "fmt" + "net/http" + "os" + "strings" +) + +func httpHandler(w http.ResponseWriter, r *http.Request) { + route, ok := Routes[r.URL.Path] + + var err error = nil + + /* defer won't update paramaters unless we do this. */ + defer func() { + ui.Path(route, err) + }() + + if !ok { + err = config.ErrRouteMiss + route = r.URL.Path + + if strings.HasPrefix(route, "/archive") { + err = readArchive(w, route) + } else { + w.WriteHeader(http.StatusNotFound) + w.Write([]byte(` +404 Not Found + +

404 Not Found

+
fes
+ +`)) + } + return + } + + params := make(map[string]string) + for k, v := range r.URL.Query() { + if len(v) > 0 { + params[k] = v[0] + } + } + + var data []byte + if strings.HasSuffix(route, ".lua") { + data, err = render(route, reqData{path: r.URL.Path, params: params}, &Sets) + } else if strings.HasSuffix(route, ".md") { + data, err = os.ReadFile(route) + data = []byte(markdownToHTML(string(data))) + data = []byte("\n" + string(data)) + } else { + data, err = os.ReadFile(route) + } + + if err != nil { + http.Error(w, fmt.Sprintf("Error loading page: %v", err), http.StatusInternalServerError) + } + + w.Write(data) +} diff --git a/modules/server/render.go b/modules/server/render.go index c99162f..3c431ff 100644 --- a/modules/server/render.go +++ b/modules/server/render.go @@ -1,6 +1,7 @@ package server import ( + "errors" "fes/modules/config" "io/fs" "os" @@ -16,8 +17,16 @@ type reqData struct { params map[string]string } -/* returns a string of rendered html */ -func render(luapath string, requestData reqData) ([]byte, error) { +/* declarative sets in the page declaration */ +type DeclarativeSets struct { + protos struct { + http bool + gemini bool + } +} + +/* returns a string of rendered markup */ +func render(luapath string, requestData reqData, setBuffer *DeclarativeSets) ([]byte, error) { L := lua.NewState() defer L.Close() @@ -160,5 +169,35 @@ func render(luapath string, requestData reqData) ([]byte, error) { return []byte(s), nil } + L.GetGlobal("require") + L.Push(lua.LString("std")) + L.Call(1, 1) + + ret := L.Get(-1) + L.Pop(1) + + tbl, ok := ret.(*lua.LTable) + if !ok { + return nil, errors.New("Could not determine protocol") + } + + proto := tbl.RawGetString("proto") + + protoTbl, ok := proto.(*lua.LTable) + if !ok { + return nil, errors.New("Could not determine protocol") + } + + protoTbl.ForEach(func(key lua.LValue, value lua.LValue) { + if str, ok := value.(lua.LString); ok { + switch str.String() { + case "http": + setBuffer.protos.http = true + case "gemini": + setBuffer.protos.gemini = true + } + } + }) + return []byte(""), nil } diff --git a/modules/server/server.go b/modules/server/server.go index dec2afc..d9526b0 100644 --- a/modules/server/server.go +++ b/modules/server/server.go @@ -8,10 +8,10 @@ import ( "net/http" "os" "path/filepath" - "strings" ) -var routes map[string]string +var Routes map[string]string +var Sets DeclarativeSets func Start(dir string) { if err := os.Chdir(dir); err != nil { @@ -30,61 +30,9 @@ func Start(dir string) { ui.Log("running root=%s, port=%d.", root, *config.Port) - routes := loadDirs() + Routes = loadDirs() - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - route, ok := routes[r.URL.Path] - - var err error = nil - - /* defer won't update paramaters unless we do this. */ - defer func() { - ui.Path(route, err) - }() - - if !ok { - err = config.ErrRouteMiss - route = r.URL.Path - - if strings.HasPrefix(route, "/archive") { - err = readArchive(w, route) - } else { - w.WriteHeader(http.StatusNotFound) - w.Write([]byte(` -404 Not Found - -

404 Not Found

-
fes
- -`)) - } - return - } - - params := make(map[string]string) - for k, v := range r.URL.Query() { - if len(v) > 0 { - params[k] = v[0] - } - } - - var data []byte - if strings.HasSuffix(route, ".lua") { - data, err = render(route, reqData{path: r.URL.Path, params: params}) - } else if strings.HasSuffix(route, ".md") { - data, err = os.ReadFile(route) - data = []byte(markdownToHTML(string(data))) - data = []byte("\n" + string(data)) - } else { - data, err = os.ReadFile(route) - } - - if err != nil { - http.Error(w, fmt.Sprintf("Error loading page: %v", err), http.StatusInternalServerError) - } - - w.Write(data) - }) + http.HandleFunc("/", httpHandler) ui.Log("Server initialized") log.Fatal(http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", *config.Port), nil))