feat: implemented basic PHP-like server.

This commit is contained in:
Andrey Parhomenko 2024-05-06 16:24:28 +05:00
parent 898c27134e
commit 1c84e46d16
7 changed files with 115 additions and 28 deletions

1
.gitignore vendored
View file

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

View file

@ -1,3 +1,4 @@
#!/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
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, filePath)
file, err := os.Open(filePath)
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.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)
}
})

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

@ -0,0 +1,7 @@
{{
time := import("time")
}}<!doctype html>
<html>
<head></head>
<body>Hello, Cock! <strong>{{ pp.print(1 + 1)}}</strong></body>
</html>