feat: implemented basic PHP-like server.

This commit is contained in:
Andrey Parhomenko 2024-05-06 16:24:28 +05:00
parent 898c27134e
commit b22c57a80c
8 changed files with 130 additions and 28 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
/tpp /tpp
/exe

View file

@ -1,3 +1,4 @@
#!/bin/sh #!/bin/sh
# #
go build ./cmd/tpp go build -o ./exe/ ./cmd/tpp ./cmd/tht

View file

@ -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())
}

11
cmd/tht/main.go Normal file
View file

@ -0,0 +1,11 @@
package main
import (
"vultras.su/util/tpp/server"
"os"
)
func main() {
server.Tool.Run(os.Args[1:])
}

View file

@ -1,9 +1,14 @@
package server package server
import ( import (
"vultras.su/util/tpp"
"path/filepath"
"net/http" "net/http"
"path" "path"
"mime"
"log"
"os" "os"
"io"
) )
var _ = http.Handler(&Handler{}) var _ = http.Handler(&Handler{})
@ -15,12 +20,57 @@ type Handler struct {
// where we store site's // where we store site's
// source files and request handlers. // source files and request handlers.
SourcePath string 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( func (h *Handler) ServeHTTP(
w http.ResponseWriter, w http.ResponseWriter,
r *http.Request, r *http.Request,
) { ) {
p := r.URL.Path urlPath := r.URL.Path
p = path.Clean(p) // 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)
} }

42
server/tool.go Normal file
View file

@ -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)
}
})

14
src/main.htm.tpp Normal file
View file

@ -0,0 +1,14 @@
{{
list := [1, 2, 3, 4, 123]
}}<!doctype html>
<html><head>
</head><body>
<div>
Hello, Cock!
</div>
<ul>{{
for v in list {
pp.print("<li>", v, "</li>")
}
}}</ul>
</body></html>

8
src/req.json.tpp Normal file
View file

@ -0,0 +1,8 @@
{
"error": null,
"data": {
"name": "Andrey",
"surname": "Parhomenko",
"age": 22
}
}