mirror of
https://github.com/akyaiy/GoSally-mvp.git
synced 2026-01-03 20:12:25 +00:00
add Net.Http to lua
This commit is contained in:
@@ -22,3 +22,38 @@ Out = {
|
|||||||
|
|
||||||
---@type Log
|
---@type Log
|
||||||
Log = {}
|
Log = {}
|
||||||
|
|
||||||
|
---@class HttpResponse
|
||||||
|
---@field status integer HTTP status code
|
||||||
|
---@field status_text string HTTP status text
|
||||||
|
---@field body string Response body
|
||||||
|
---@field content_length integer Content length
|
||||||
|
---@field headers table<string, string|string[]> Response headers
|
||||||
|
|
||||||
|
---@class Http
|
||||||
|
---@field Get fun(log: boolean, url: string): HttpResponse, string? Makes HTTP GET request
|
||||||
|
---@field Post fun(log: boolean, url: string, content_type: string, payload: string): HttpResponse, string? Makes HTTP POST request
|
||||||
|
|
||||||
|
---@class Net
|
||||||
|
---@field Http Http HTTP client methods
|
||||||
|
|
||||||
|
---@type Net
|
||||||
|
Net = {
|
||||||
|
Http = {
|
||||||
|
---Makes HTTP GET request
|
||||||
|
---@param log boolean Whether to log the request
|
||||||
|
---@param url string URL to request
|
||||||
|
---@return HttpResponse response
|
||||||
|
---@return string? error
|
||||||
|
Get = function(log, url) end,
|
||||||
|
|
||||||
|
---Makes HTTP POST request
|
||||||
|
---@param log boolean Whether to log the request
|
||||||
|
---@param url string URL to request
|
||||||
|
---@param content_type string Content-Type header
|
||||||
|
---@param payload string Request body
|
||||||
|
---@return HttpResponse response
|
||||||
|
---@return string? error
|
||||||
|
Post = function(log, url, content_type, payload) end
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,5 +24,5 @@ func (h *HandlerV1) Handle(r *http.Request, req *rpc.RPCRequest) *rpc.RPCRespons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.handleLUA(method, req)
|
return h.handleLUA(r, req, method)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,32 @@ package sv1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/engine/logs"
|
"github.com/akyaiy/GoSally-mvp/internal/engine/logs"
|
||||||
"github.com/akyaiy/GoSally-mvp/internal/server/rpc"
|
"github.com/akyaiy/GoSally-mvp/internal/server/rpc"
|
||||||
lua "github.com/yuin/gopher-lua"
|
lua "github.com/yuin/gopher-lua"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *HandlerV1) handleLUA(path string, req *rpc.RPCRequest) *rpc.RPCResponse {
|
func addInitiatorHeaders(req *http.Request, headers http.Header) {
|
||||||
|
clientIP := req.RemoteAddr
|
||||||
|
if forwardedFor := req.Header.Get("X-Forwarded-For"); forwardedFor != "" {
|
||||||
|
clientIP = forwardedFor
|
||||||
|
}
|
||||||
|
headers.Set("X-Initiator-IP", clientIP)
|
||||||
|
|
||||||
|
headers.Set("X-Initiator-Host", req.Host)
|
||||||
|
headers.Set("X-Initiator-User-Agent", req.UserAgent())
|
||||||
|
headers.Set("X-Initiator-Referer", req.Referer())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HandlerV1) handleLUA(r *http.Request, req *rpc.RPCRequest, path string) *rpc.RPCResponse {
|
||||||
L := lua.NewState()
|
L := lua.NewState()
|
||||||
defer L.Close()
|
defer L.Close()
|
||||||
|
|
||||||
@@ -68,6 +83,129 @@ func (h *HandlerV1) handleLUA(path string, req *rpc.RPCRequest) *rpc.RPCResponse
|
|||||||
|
|
||||||
L.SetGlobal("Log", logTable)
|
L.SetGlobal("Log", logTable)
|
||||||
|
|
||||||
|
net := L.NewTable()
|
||||||
|
netHttp := L.NewTable()
|
||||||
|
|
||||||
|
L.SetField(netHttp, "Get", L.NewFunction(func(L *lua.LState) int {
|
||||||
|
logRequest := L.ToBool(1)
|
||||||
|
url := L.ToString(2)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
L.Push(lua.LNil)
|
||||||
|
L.Push(lua.LString(err.Error()))
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
addInitiatorHeaders(r, req.Header)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
L.Push(lua.LNil)
|
||||||
|
L.Push(lua.LString(err.Error()))
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
L.Push(lua.LNil)
|
||||||
|
L.Push(lua.LString(err.Error()))
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
if logRequest {
|
||||||
|
h.x.SLog.Info("HTTP GET request",
|
||||||
|
slog.String("script", path),
|
||||||
|
slog.String("url", url),
|
||||||
|
slog.Int("status", resp.StatusCode),
|
||||||
|
slog.String("status_text", resp.Status),
|
||||||
|
slog.String("initiator_ip", req.Header.Get("X-Initiator-IP")),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := L.NewTable()
|
||||||
|
L.SetField(result, "status", lua.LNumber(resp.StatusCode))
|
||||||
|
L.SetField(result, "status_text", lua.LString(resp.Status))
|
||||||
|
L.SetField(result, "body", lua.LString(body))
|
||||||
|
L.SetField(result, "content_length", lua.LNumber(resp.ContentLength))
|
||||||
|
|
||||||
|
headers := L.NewTable()
|
||||||
|
for k, v := range resp.Header {
|
||||||
|
L.SetField(headers, k, ConvertGolangTypesToLua(L, v))
|
||||||
|
}
|
||||||
|
L.SetField(result, "headers", headers)
|
||||||
|
|
||||||
|
L.Push(result)
|
||||||
|
return 1
|
||||||
|
}))
|
||||||
|
|
||||||
|
L.SetField(netHttp, "Post", L.NewFunction(func(L *lua.LState) int {
|
||||||
|
logRequest := L.ToBool(1)
|
||||||
|
url := L.ToString(2)
|
||||||
|
contentType := L.ToString(3)
|
||||||
|
payload := L.ToString(4)
|
||||||
|
|
||||||
|
body := strings.NewReader(payload)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", url, body)
|
||||||
|
if err != nil {
|
||||||
|
L.Push(lua.LNil)
|
||||||
|
L.Push(lua.LString(err.Error()))
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Content-Type", contentType)
|
||||||
|
|
||||||
|
addInitiatorHeaders(r, req.Header)
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
L.Push(lua.LNil)
|
||||||
|
L.Push(lua.LString(err.Error()))
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
respBody, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
L.Push(lua.LNil)
|
||||||
|
L.Push(lua.LString(err.Error()))
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
if logRequest {
|
||||||
|
h.x.SLog.Info("HTTP POST request",
|
||||||
|
slog.String("script", path),
|
||||||
|
slog.String("url", url),
|
||||||
|
slog.String("content_type", contentType),
|
||||||
|
slog.Int("status", resp.StatusCode),
|
||||||
|
slog.String("status_text", resp.Status),
|
||||||
|
slog.String("initiator_ip", req.Header.Get("X-Initiator-IP")),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := L.NewTable()
|
||||||
|
L.SetField(result, "status", lua.LNumber(resp.StatusCode))
|
||||||
|
L.SetField(result, "status_text", lua.LString(resp.Status))
|
||||||
|
L.SetField(result, "body", lua.LString(respBody))
|
||||||
|
L.SetField(result, "content_length", lua.LNumber(resp.ContentLength))
|
||||||
|
|
||||||
|
headers := L.NewTable()
|
||||||
|
for k, v := range resp.Header {
|
||||||
|
L.SetField(headers, k, ConvertGolangTypesToLua(L, v))
|
||||||
|
}
|
||||||
|
L.SetField(result, "headers", headers)
|
||||||
|
|
||||||
|
L.Push(result)
|
||||||
|
return 1
|
||||||
|
}))
|
||||||
|
|
||||||
|
L.SetField(net, "Http", netHttp)
|
||||||
|
L.SetGlobal("Net", net)
|
||||||
|
|
||||||
prep := filepath.Join(*h.x.Config.Conf.ComDir, "_prepare.lua")
|
prep := filepath.Join(*h.x.Config.Conf.ComDir, "_prepare.lua")
|
||||||
if _, err := os.Stat(prep); err == nil {
|
if _, err := os.Stat(prep); err == nil {
|
||||||
if err := L.DoFile(prep); err != nil {
|
if err := L.DoFile(prep); err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user