diff --git a/cmd/tht/main.go b/cmd/tht/main.go index ef76a68..5fffc86 100644 --- a/cmd/tht/main.go +++ b/cmd/tht/main.go @@ -1,11 +1,11 @@ package main import ( - "vultras.su/util/tpp/server" + "vultras.su/util/tpp/httpx" "os" ) func main() { - server.Tool.Run(os.Args[1:]) + httpx.Tool.Run(os.Args[1:]) } diff --git a/server/handler.go b/httpx/handler.go similarity index 92% rename from server/handler.go rename to httpx/handler.go index 905a6a7..3140ba3 100644 --- a/server/handler.go +++ b/httpx/handler.go @@ -1,9 +1,10 @@ -package server +package httpx import ( "vultras.su/util/tpp" "path/filepath" "net/http" + "context" "path" "mime" "log" @@ -58,8 +59,11 @@ func (h *Handler) ServeHTTP( return } + ctx := context.WithValue(r.Context(), KeyRequest, &Request{ + Request: r, + }) processedData, err := h.PP.Process( - r.Context(), + ctx, true, filePathTpp, fileData, diff --git a/httpx/http.go b/httpx/http.go new file mode 100644 index 0000000..0e441e6 --- /dev/null +++ b/httpx/http.go @@ -0,0 +1,2 @@ +package httpx + diff --git a/httpx/request.go b/httpx/request.go new file mode 100644 index 0000000..eab9480 --- /dev/null +++ b/httpx/request.go @@ -0,0 +1,40 @@ +package httpx + +import ( + "github.com/d5/tengo/v2" + "net/http" + //"log" +) + +type Request struct { + tengo.ObjectImpl + *http.Request +} + +func (r *Request) TypeName() string { + return "*http.Request" +} + +func (r *Request) String() string { + return "*http.Request{...}" +} + +func (r *Request) IndexGet( + index tengo.Object, +) (tengo.Object, error) { + key, ok := tengo.ToString(index) + if !ok { + return nil, tengo.ErrInvalidIndexValueType + } + + switch key { + case "url" : + return &URL{ + URL: r.URL, + }, nil + } + + // Nothing found. + return nil, nil +} + diff --git a/server/tool.go b/httpx/tool.go similarity index 65% rename from server/tool.go rename to httpx/tool.go index 4bf3dd5..d745182 100644 --- a/server/tool.go +++ b/httpx/tool.go @@ -1,4 +1,4 @@ -package server +package httpx import ( //"github.com/d5/tengo/v2" @@ -7,8 +7,16 @@ import ( "vultras.su/core/cli/mtool" "net/http" "log" + "context" ) +// Context key type for internal usage. +type CKey string +const ( + KeyRequest CKey = "http-request" +) + +// Simple PHP-like server implementation. var Tool = mtool.T("tht").Func(func(flags *mtool.Flags){ var ( addr string @@ -21,12 +29,23 @@ var Tool = mtool.T("tht").Func(func(flags *mtool.Flags){ flags.Parse() - t := tpp.NewTengo().SetPreCompile(func(s *tpp.Script){ + t := tpp.NewTengo().SetPreCompile(func( + ctx context.Context, + s *tpp.Script, + ){ + s.SetImportDir(handler.SourcePath) s.SetImports(stdlib.GetModuleMap( stdlib.AllModuleNames()..., )) s.EnableFileImport(true) - s.SetImportDir(handler.SourcePath) + + s.Add("__http_request__", ctx.Value(KeyRequest)) + }).SetPreCode(func(ctx context.Context) []byte { + return []byte(` + http := { + request : __http_request__ + } + `) }) handler.PP = tpp.New(t) diff --git a/httpx/url.go b/httpx/url.go new file mode 100644 index 0000000..a8cf06a --- /dev/null +++ b/httpx/url.go @@ -0,0 +1,76 @@ +package httpx + +import ( + "github.com/d5/tengo/v2" + "net/url" + "fmt" +) + +var _ = tengo.Object(&Values{}) +type Values struct { + tengo.ObjectImpl + url.Values +} + +func (vs *Values) TypeName() string { + return "*url.Values" +} + +func (vs *Values) String() string { + return fmt.Sprintf("%v", vs.Values) +} + +func (vs *Values) IndexGet( + index tengo.Object, +) (tengo.Object, error) { + key, ok := tengo.ToString(index) + if !ok { + return nil, tengo.ErrInvalidIndexValueType + } + + val, ok := vs.Values[key] + if !ok { + return nil, nil + } + + arr := make([]tengo.Object, len(val)) + for i, v := range val { + arr[i], _ = tengo.FromInterface(v) + } + + return &tengo.Array{Value: arr}, nil +} + +type URL struct { + tengo.ObjectImpl + *url.URL +} + +func (u *URL) TypeName() string { + return "" +} + +func (u *URL) String() string { + return u.URL.String() +} + +func (u *URL) IndexGet( + index tengo.Object, +) (tengo.Object, error) { + key, ok := tengo.ToString(index) + if !ok { + return nil, tengo.ErrInvalidIndexValueType + } + + switch key { + case "path" : + return tengo.FromInterface(u.Path) + case "query" : + return tengo.FromInterface(&Values{ + Values: u.Query(), + }) + } + + // Nothing found. + return nil, nil +} diff --git a/src/main.htm.tpp b/src/main.htm.tpp index 4c5919a..d19279b 100644 --- a/src/main.htm.tpp +++ b/src/main.htm.tpp @@ -1,11 +1,26 @@ {{ + fmt := import("fmt") + req := http.request + q := req.url.query + // List checking. list := [1, 2, 3, 4, 123] + }} + {{ + if q.name { + pp.print("
", q.name[0], "
") + } + }}
Hello, Cock!
+
+ {{ + pp.print(req.url.path) + }} +