125 lines
3.4 KiB
Go
125 lines
3.4 KiB
Go
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
|
//go:build script
|
|
// +build script
|
|
|
|
package nodes
|
|
|
|
import (
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
|
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
|
|
"github.com/iwind/TeaGo/maps"
|
|
"github.com/iwind/TeaGo/types"
|
|
"rogchap.com/v8go"
|
|
"strings"
|
|
)
|
|
|
|
func (this *HTTPRequest) onInit() {
|
|
this.fireScriptEvent("init")
|
|
}
|
|
|
|
func (this *HTTPRequest) onRequest() {
|
|
if this.isDone || this.writer.isFinished {
|
|
return
|
|
}
|
|
this.fireScriptEvent("request")
|
|
}
|
|
|
|
// 触发事件
|
|
func (this *HTTPRequest) fireScriptEvent(eventType string) {
|
|
if SharedJSPool == nil {
|
|
return
|
|
}
|
|
|
|
if this.web.RequestScripts == nil {
|
|
return
|
|
}
|
|
|
|
var group *serverconfigs.ScriptGroupConfig
|
|
if eventType == "init" && this.web.RequestScripts.InitGroup != nil && this.web.RequestScripts.InitGroup.IsOn {
|
|
group = this.web.RequestScripts.InitGroup
|
|
} else if eventType == "request" && this.web.RequestScripts.RequestGroup != nil && this.web.RequestScripts.RequestGroup.IsOn {
|
|
group = this.web.RequestScripts.RequestGroup
|
|
}
|
|
|
|
if group == nil {
|
|
return
|
|
}
|
|
|
|
for _, script := range group.Scripts {
|
|
if this.isDone {
|
|
return
|
|
}
|
|
|
|
if !script.IsOn {
|
|
continue
|
|
}
|
|
|
|
if len(script.RealCode()) > 0 {
|
|
this.runScript(eventType, script.RealCode())
|
|
}
|
|
}
|
|
}
|
|
|
|
func (this *HTTPRequest) runScript(eventType string, script string) {
|
|
ctx, err := SharedJSPool.GetContext()
|
|
if err != nil {
|
|
remotelogs.Error("SCRIPT", "get context failed: "+err.Error())
|
|
return
|
|
}
|
|
ctx.SetServerId(this.ReqServer.Id)
|
|
defer SharedJSPool.PutContext(ctx)
|
|
|
|
var reqObjectId = ctx.AddGoRequestObject(this)
|
|
var respObjectId = ctx.AddGoResponseObject(this.writer)
|
|
|
|
script = `(function () {
|
|
let req = new gojs.net.http.Request()
|
|
req.setGoObject(` + types.String(reqObjectId) + `)
|
|
|
|
let resp = new gojs.net.http.Response()
|
|
resp.setGoObject(` + types.String(respObjectId) + `)
|
|
` + script + `
|
|
})()`
|
|
_, err = ctx.Run(script, "request."+eventType+".js")
|
|
if err != nil {
|
|
var errString = ""
|
|
jsErr, ok := err.(*v8go.JSError)
|
|
if ok {
|
|
var pieces = strings.Split(jsErr.Location, ":")
|
|
if len(pieces) < 3 {
|
|
errString = err.Error()
|
|
} else {
|
|
if strings.HasPrefix(pieces[0], "gojs") {
|
|
var line = types.Int(pieces[len(pieces)-2])
|
|
var scriptLine = ctx.ReadLineFromLibrary(pieces[0], line)
|
|
if len(scriptLine) > 0 {
|
|
if len(scriptLine) > 256 {
|
|
scriptLine = scriptLine[:256] + "..."
|
|
}
|
|
|
|
errString = jsErr.Error() + ", location: " + strings.Join(pieces[:len(pieces)-2], ":") + ":" + types.String(line) + ":" + pieces[len(pieces)-1] + ", code: " + scriptLine
|
|
}
|
|
}
|
|
if len(errString) == 0 {
|
|
var line = types.Int(pieces[len(pieces)-2])
|
|
var scriptLines = strings.Split(script, "\n")
|
|
var scriptLine = ""
|
|
if len(scriptLines) > line-1 {
|
|
scriptLine = scriptLines[line-1]
|
|
if len(scriptLine) > 256 {
|
|
scriptLine = scriptLine[:256] + "..."
|
|
}
|
|
}
|
|
line -= 6 /* 6是req和resp构造用的行数 */
|
|
errString = jsErr.Error() + ", location: " + strings.Join(pieces[:len(pieces)-2], ":") + ":" + types.String(line) + ":" + pieces[len(pieces)-1] + ", code: " + scriptLine
|
|
}
|
|
}
|
|
} else {
|
|
errString = err.Error()
|
|
}
|
|
remotelogs.ServerError(this.ReqServer.Id, "SCRIPT", "run "+eventType+" script failed: "+errString, nodeconfigs.NodeLogTypeRunScriptFailed, maps.Map{})
|
|
return
|
|
}
|
|
}
|