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
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"vultras.su/util/tpp/server"
|
"vultras.su/util/tpp/httpx"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
server.Tool.Run(os.Args[1:])
|
httpx.Tool.Run(os.Args[1:])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package server
|
package httpx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"vultras.su/util/tpp"
|
"vultras.su/util/tpp"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"context"
|
||||||
"path"
|
"path"
|
||||||
"mime"
|
"mime"
|
||||||
"log"
|
"log"
|
||||||
|
@ -58,8 +59,11 @@ func (h *Handler) ServeHTTP(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx := context.WithValue(r.Context(), KeyRequest, &Request{
|
||||||
|
Request: r,
|
||||||
|
})
|
||||||
processedData, err := h.PP.Process(
|
processedData, err := h.PP.Process(
|
||||||
r.Context(),
|
ctx,
|
||||||
true,
|
true,
|
||||||
filePathTpp,
|
filePathTpp,
|
||||||
fileData,
|
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 (
|
import (
|
||||||
//"github.com/d5/tengo/v2"
|
//"github.com/d5/tengo/v2"
|
||||||
|
@ -7,8 +7,16 @@ import (
|
||||||
"vultras.su/core/cli/mtool"
|
"vultras.su/core/cli/mtool"
|
||||||
"net/http"
|
"net/http"
|
||||||
"log"
|
"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 Tool = mtool.T("tht").Func(func(flags *mtool.Flags){
|
||||||
var (
|
var (
|
||||||
addr string
|
addr string
|
||||||
|
@ -21,12 +29,23 @@ var Tool = mtool.T("tht").Func(func(flags *mtool.Flags){
|
||||||
|
|
||||||
flags.Parse()
|
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(
|
s.SetImports(stdlib.GetModuleMap(
|
||||||
stdlib.AllModuleNames()...,
|
stdlib.AllModuleNames()...,
|
||||||
))
|
))
|
||||||
s.EnableFileImport(true)
|
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)
|
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]
|
list := [1, 2, 3, 4, 123]
|
||||||
|
|
||||||
}}<!doctype html>
|
}}<!doctype html>
|
||||||
<html><head>
|
<html><head>
|
||||||
</head><body>
|
</head><body>
|
||||||
|
{{
|
||||||
|
if q.name {
|
||||||
|
pp.print("<div id=\"name\">", q.name[0], "</div>")
|
||||||
|
}
|
||||||
|
}}
|
||||||
<div>
|
<div>
|
||||||
Hello, Cock!
|
Hello, Cock!
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
{{
|
||||||
|
pp.print(req.url.path)
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
<ul>{{
|
<ul>{{
|
||||||
for v in list {
|
for v in list {
|
||||||
pp.print("<li>", v, "</li>")
|
pp.print("<li>", v, "</li>")
|
||||||
|
|
18
tengo.go
18
tengo.go
|
@ -16,9 +16,9 @@ type Tengo struct {
|
||||||
// Functions to modify
|
// Functions to modify
|
||||||
// preprocessor for
|
// preprocessor for
|
||||||
// more specific purposes.
|
// more specific purposes.
|
||||||
preCode func() []byte
|
preCode func(context.Context) []byte
|
||||||
postCode func() []byte
|
postCode func(context.Context) []byte
|
||||||
preCompile func(*Script)
|
preCompile func(context.Context, *Script)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the new Tengo preprocessor
|
// Returns the new Tengo preprocessor
|
||||||
|
@ -28,17 +28,17 @@ func NewTengo() *Tengo {
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tengo *Tengo) SetPreCode(fn func() []byte) *Tengo {
|
func (tengo *Tengo) SetPreCode(fn func(context.Context) []byte) *Tengo {
|
||||||
tengo.preCode = fn
|
tengo.preCode = fn
|
||||||
return tengo
|
return tengo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tengo *Tengo) SetPostCode(fn func() []byte) *Tengo {
|
func (tengo *Tengo) SetPostCode(fn func(context.Context) []byte) *Tengo {
|
||||||
tengo.postCode = fn
|
tengo.postCode = fn
|
||||||
return tengo
|
return tengo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tengo *Tengo) SetPreCompile(fn func(*Script)) *Tengo {
|
func (tengo *Tengo) SetPreCompile(fn func(context.Context, *Script)) *Tengo {
|
||||||
tengo.preCompile = fn
|
tengo.preCompile = fn
|
||||||
return tengo
|
return tengo
|
||||||
}
|
}
|
||||||
|
@ -80,18 +80,18 @@ func (pp *Tengo) Eval(
|
||||||
|
|
||||||
fmt.Fprint(&fullCodeBuf, retHead)
|
fmt.Fprint(&fullCodeBuf, retHead)
|
||||||
if pp.preCode != nil {
|
if pp.preCode != nil {
|
||||||
fullCodeBuf.Write(pp.preCode())
|
fullCodeBuf.Write(pp.preCode(ctx))
|
||||||
}
|
}
|
||||||
for _, code := range codes {
|
for _, code := range codes {
|
||||||
fmt.Fprintln(&fullCodeBuf, "\n" + string(code) + retSeparator)
|
fmt.Fprintln(&fullCodeBuf, "\n" + string(code) + retSeparator)
|
||||||
}
|
}
|
||||||
if pp.postCode != nil {
|
if pp.postCode != nil {
|
||||||
fullCodeBuf.Write(pp.postCode())
|
fullCodeBuf.Write(pp.postCode(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
script := tengo.NewScript(fullCodeBuf.Bytes())
|
script := tengo.NewScript(fullCodeBuf.Bytes())
|
||||||
if pp.preCompile != nil {
|
if pp.preCompile != nil {
|
||||||
pp.preCompile(script)
|
pp.preCompile(ctx, script)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := script.Add("__sprintf__", &tengo.UserFunction{
|
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){
|
var Tool = mtool.T("pp").Func(func(flags *mtool.Flags){
|
||||||
t := NewTengo().
|
t := NewTengo().
|
||||||
SetPreCompile(func(s *Script){
|
SetPreCompile(func(ctx context.Context, s *Script){
|
||||||
s.SetImports(stdlib.GetModuleMap(
|
s.SetImports(stdlib.GetModuleMap(
|
||||||
stdlib.AllModuleNames()...,
|
stdlib.AllModuleNames()...,
|
||||||
))
|
))
|
||||||
|
|
Loading…
Reference in a new issue