From b22c57a80c9b3d59e4fd676e69e0d67ab32a1be5 Mon Sep 17 00:00:00 2001 From: surdeus Date: Mon, 6 May 2024 16:24:28 +0500 Subject: [PATCH] feat: implemented basic PHP-like server. --- .gitignore | 1 + build.sh | 3 ++- cmd/tenserve/main.go | 25 -------------------- cmd/tht/main.go | 11 +++++++++ server/handler.go | 54 ++++++++++++++++++++++++++++++++++++++++++-- server/tool.go | 42 ++++++++++++++++++++++++++++++++++ src/main.htm.tpp | 14 ++++++++++++ src/req.json.tpp | 8 +++++++ 8 files changed, 130 insertions(+), 28 deletions(-) delete mode 100644 cmd/tenserve/main.go create mode 100644 cmd/tht/main.go create mode 100644 server/tool.go create mode 100644 src/main.htm.tpp create mode 100644 src/req.json.tpp diff --git a/.gitignore b/.gitignore index 812817f..783eacd 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /tpp +/exe diff --git a/build.sh b/build.sh index e74ef3e..02eb76a 100755 --- a/build.sh +++ b/build.sh @@ -1,3 +1,4 @@ #!/bin/sh # -go build ./cmd/tpp +go build -o ./exe/ ./cmd/tpp ./cmd/tht + diff --git a/cmd/tenserve/main.go b/cmd/tenserve/main.go deleted file mode 100644 index 0ed8189..0000000 --- a/cmd/tenserve/main.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import ( - "flag" - "net/http" - "vultras.su/util/tpp/server" -) - -func main() { - var ( - addr, src string - ) - - flag.StringVar(&addr, "http", ":8080", "HTTP address to serve") - flag.StringVar(&src, "src", "", "path to the source directory") - srv := http.Server{ - Address: addr, - Handler: &server.Handler{ - SourcePath: src, - }, - } - - log.Fatal(srv.ListenAndServe()) -} - diff --git a/cmd/tht/main.go b/cmd/tht/main.go new file mode 100644 index 0000000..ef76a68 --- /dev/null +++ b/cmd/tht/main.go @@ -0,0 +1,11 @@ +package main + +import ( + "vultras.su/util/tpp/server" + "os" +) + +func main() { + server.Tool.Run(os.Args[1:]) +} + diff --git a/server/handler.go b/server/handler.go index a49a853..905a6a7 100644 --- a/server/handler.go +++ b/server/handler.go @@ -1,9 +1,14 @@ package server import ( + "vultras.su/util/tpp" + "path/filepath" "net/http" "path" + "mime" + "log" "os" + "io" ) var _ = http.Handler(&Handler{}) @@ -15,12 +20,57 @@ type Handler struct { // where we store site's // source files and request handlers. SourcePath string + // Preprocessor must be set by user + // to be able to bring custom features in. + PP *tpp.Preprocessor + // Aditional extension. ".tpp" by default. + // For example "file.html.tpp" will be + // first preprocessed TPP and sent back as simple HTML. + Ext string } func (h *Handler) ServeHTTP( w http.ResponseWriter, r *http.Request, ) { - p := r.URL.Path - p = path.Clean(p) + urlPath := r.URL.Path + // Cleaning URL path to prevent injections. + urlPath = path.Clean(urlPath) + urlExt := path.Ext(urlPath) + + filePath := filepath.Join( + filepath.FromSlash(h.SourcePath), + filepath.FromSlash(urlPath), + ) + filePathTpp := filePath + h.Ext + + //log.Println("pth:", urlPath, filePathTpp) + file, err := os.Open(filePathTpp) + if err != nil { + http.NotFound(w, r) + return + } + + //process := true + fileData, err := io.ReadAll(file) + if err != nil { + http.NotFound(w, r) + return + } + + processedData, err := h.PP.Process( + r.Context(), + true, + filePathTpp, + fileData, + ) + if err != nil { + http.NotFound(w, r) + log.Printf("Error: pp.Process(...): %s\n", err) + return + } + + contentType := mime.TypeByExtension(urlExt) + w.Header().Set("Content-Type", contentType) + w.Write(processedData) } diff --git a/server/tool.go b/server/tool.go new file mode 100644 index 0000000..4bf3dd5 --- /dev/null +++ b/server/tool.go @@ -0,0 +1,42 @@ +package server + +import ( + //"github.com/d5/tengo/v2" + "github.com/d5/tengo/v2/stdlib" + "vultras.su/util/tpp" + "vultras.su/core/cli/mtool" + "net/http" + "log" +) + +var Tool = mtool.T("tht").Func(func(flags *mtool.Flags){ + var ( + addr string + handler Handler + ) + + flags.StringVar(&addr, "addr", ":3000", "address to serve at") + flags.StringVar(&handler.SourcePath, "src", "./src", "directory with source files") + flags.StringVar(&handler.Ext, "ext", ".tpp", "extension for TPP files") + + flags.Parse() + + t := tpp.NewTengo().SetPreCompile(func(s *tpp.Script){ + s.SetImports(stdlib.GetModuleMap( + stdlib.AllModuleNames()..., + )) + s.EnableFileImport(true) + s.SetImportDir(handler.SourcePath) + }) + + handler.PP = tpp.New(t) + + srv := &http.Server{ + Addr: addr, + Handler: &handler, + } + err := srv.ListenAndServe() + if err != nil { + log.Printf("Error: srv.ListenAndServe(...): %s\n", err) + } +}) diff --git a/src/main.htm.tpp b/src/main.htm.tpp new file mode 100644 index 0000000..4c5919a --- /dev/null +++ b/src/main.htm.tpp @@ -0,0 +1,14 @@ +{{ + list := [1, 2, 3, 4, 123] +}} + + +
+ Hello, Cock! +
+ + diff --git a/src/req.json.tpp b/src/req.json.tpp new file mode 100644 index 0000000..16bb6de --- /dev/null +++ b/src/req.json.tpp @@ -0,0 +1,8 @@ +{ + "error": null, + "data": { + "name": "Andrey", + "surname": "Parhomenko", + "age": 22 + } +}