feat: added access to the request in preprocessing in THT.
This commit is contained in:
parent
b22c57a80c
commit
8ac7b3bb31
9 changed files with 173 additions and 17 deletions
|
@ -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:])
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
2
httpx/http.go
Normal file
2
httpx/http.go
Normal file
|
@ -0,0 +1,2 @@
|
|||
package httpx
|
||||
|
40
httpx/request.go
Normal file
40
httpx/request.go
Normal file
|
@ -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
|
||||
}
|
||||
|
|
@ -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)
|
76
httpx/url.go
Normal file
76
httpx/url.go
Normal file
|
@ -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 "<URL>"
|
||||
}
|
||||
|
||||
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
|
||||
}
|
|
@ -1,11 +1,26 @@
|
|||
{{
|
||||
fmt := import("fmt")
|
||||
req := http.request
|
||||
q := req.url.query
|
||||
// List checking.
|
||||
list := [1, 2, 3, 4, 123]
|
||||
|
||||
}}<!doctype html>
|
||||
<html><head>
|
||||
</head><body>
|
||||
{{
|
||||
if q.name {
|
||||
pp.print("<div id=\"name\">", q.name[0], "</div>")
|
||||
}
|
||||
}}
|
||||
<div>
|
||||
Hello, Cock!
|
||||
</div>
|
||||
<div>
|
||||
{{
|
||||
pp.print(req.url.path)
|
||||
}}
|
||||
</div>
|
||||
<ul>{{
|
||||
for v in list {
|
||||
pp.print("<li>", v, "</li>")
|
||||
|
|
18
tengo.go
18
tengo.go
|
@ -16,9 +16,9 @@ type Tengo struct {
|
|||
// Functions to modify
|
||||
// preprocessor for
|
||||
// more specific purposes.
|
||||
preCode func() []byte
|
||||
postCode func() []byte
|
||||
preCompile func(*Script)
|
||||
preCode func(context.Context) []byte
|
||||
postCode func(context.Context) []byte
|
||||
preCompile func(context.Context, *Script)
|
||||
}
|
||||
|
||||
// Returns the new Tengo preprocessor
|
||||
|
@ -28,17 +28,17 @@ func NewTengo() *Tengo {
|
|||
return ret
|
||||
}
|
||||
|
||||
func (tengo *Tengo) SetPreCode(fn func() []byte) *Tengo {
|
||||
func (tengo *Tengo) SetPreCode(fn func(context.Context) []byte) *Tengo {
|
||||
tengo.preCode = fn
|
||||
return tengo
|
||||
}
|
||||
|
||||
func (tengo *Tengo) SetPostCode(fn func() []byte) *Tengo {
|
||||
func (tengo *Tengo) SetPostCode(fn func(context.Context) []byte) *Tengo {
|
||||
tengo.postCode = fn
|
||||
return tengo
|
||||
}
|
||||
|
||||
func (tengo *Tengo) SetPreCompile(fn func(*Script)) *Tengo {
|
||||
func (tengo *Tengo) SetPreCompile(fn func(context.Context, *Script)) *Tengo {
|
||||
tengo.preCompile = fn
|
||||
return tengo
|
||||
}
|
||||
|
@ -80,18 +80,18 @@ func (pp *Tengo) Eval(
|
|||
|
||||
fmt.Fprint(&fullCodeBuf, retHead)
|
||||
if pp.preCode != nil {
|
||||
fullCodeBuf.Write(pp.preCode())
|
||||
fullCodeBuf.Write(pp.preCode(ctx))
|
||||
}
|
||||
for _, code := range codes {
|
||||
fmt.Fprintln(&fullCodeBuf, "\n" + string(code) + retSeparator)
|
||||
}
|
||||
if pp.postCode != nil {
|
||||
fullCodeBuf.Write(pp.postCode())
|
||||
fullCodeBuf.Write(pp.postCode(ctx))
|
||||
}
|
||||
|
||||
script := tengo.NewScript(fullCodeBuf.Bytes())
|
||||
if pp.preCompile != nil {
|
||||
pp.preCompile(script)
|
||||
pp.preCompile(ctx, script)
|
||||
}
|
||||
|
||||
err := script.Add("__sprintf__", &tengo.UserFunction{
|
||||
|
|
2
tool.go
2
tool.go
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
var Tool = mtool.T("pp").Func(func(flags *mtool.Flags){
|
||||
t := NewTengo().
|
||||
SetPreCompile(func(s *Script){
|
||||
SetPreCompile(func(ctx context.Context, s *Script){
|
||||
s.SetImports(stdlib.GetModuleMap(
|
||||
stdlib.AllModuleNames()...,
|
||||
))
|
||||
|
|
Loading…
Reference in a new issue