Help us shape the future of Go! Take the 2026 Go Developer Survey

hostmodule

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 23, 2026 License: MIT Imports: 19 Imported by: 0

README

Host Module Framework(语言无关宿主模块框架)

ModuleDef = 模块名 + map[函数名]Go函数,是向脚本 VM 注入宿主能力的语言无关形态:

  • JS(goja):把 ModuleDef.Funcs 直接注册进 VM,Go 函数即可被脚本调用;(T, error) 返回形态自动转为 JS 异常。
  • Lua(gopher-lua):继续走 lua/host 的 Loader* 形态;本包的 HTTP 护栏原语两侧行为完全一致。

Go 函数签名约定:参数用基础类型(string/int/float64/map[string]any/[]any),返回单值或 (result, error)。

内置模块

构造器 模块名 函数面
ModuleLogger(logger) log info / warn / error / debug 及 *f 格式化变体(float64 整数自动转 int,兼容 %d)
ModuleCrypto() crypto encrypt / decrypt / is_encrypted / encrypt_json / decrypt_json / hash_sha256(底层 go-utils/crypto 全局加密器,enc: 前缀按需加密)
ModuleUtil(maxSleep...) util sleep(默认上限 5s,防脚本无限阻塞执行线程)、time / timestamp / date(默认 RFC3339)
ModuleHTTP(opts) http request(url, options?) / get(url) / post(url, body, contentType?) → {status, body, headers(全小写键)}

HTTP 出站护栏

ModuleHTTP 与底层原语(NormalizeHTTPOptions / CheckAllowedURL / HTTPRequest / BuildHTTPClient)实现同一套护栏,Lua / JS 两侧共享:

  • fail-closed 白名单:AllowedDomains 为空 = 全部出站拒绝。部署侧经环境变量 SCRIPT_HTTP_ALLOWED_DOMAINS(逗号分隔,如 hooks.slack.com,oapi.dingtalk.com)放行,HTTPAllowlistFromEnv() 一行构造。
  • 协议与域名:仅 http/https;host 需精确命中白名单,*.example.com 只通配一级子域(a.b.example.com 不命中)。
  • SSRF 基线:localhost / 127.0.0.1 / 0.0.0.0 / ::1 / 169.254.169.254(云元数据地址)硬禁——即使白名单显式列出也拒绝;DenyLoopback=false 仅为 httptest 等测试环境留的逃生门。
  • 重定向逐跳复检:CheckRedirect 内对每个跳转目标重新执行白名单校验,上限 3 跳——白名单域名 302 到内网同样被拦。
  • 体积/超时上限:单请求超时默认 10s(配置 >30s 收敛回 10s);请求体 / 响应体上限各 1MB,超限即错不截断。
  • 防护头不可伪装:脚本传入的 host / user-agent / content-length 头被丢弃;UA 固定为 go-scripts-host/1.0。

用法

opts := hostmodule.HTTPAllowlistFromEnv() // 或手工构造 HTTPOptions
mod := hostmodule.ModuleHTTP(opts)        // mod.Name="http", mod.Funcs 注册进你的 VM

logger := hostmodule.NewKitLogger()
logMod := hostmodule.ModuleLogger(logger) // ModuleLogger 接受 hostmodule.Logger
// 脚本侧(goja)
const http = require('http'); // 或 VM 全局,取决于宿主注册方式
const resp = http.get('https://hooks.slack.com/services/xxx');
if (resp.status === 200) { /* resp.body / resp.headers */ }

依赖

Documentation

Index

Constants

View Source
const EnvHTTPAllowedDomains = "SCRIPT_HTTP_ALLOWED_DOMAINS"

Variables

This section is empty.

Functions

func BuildHTTPClient

func BuildHTTPClient(opts HTTPOptions) *http.Client

func CheckAllowedURL

func CheckAllowedURL(rawURL string, allowed []string, denyLoopback bool) error

func DecryptIfNeeded

func DecryptIfNeeded(ciphertext string) (string, error)

DecryptIfNeeded 解密带 enc: 前缀的字符串,普通明文直接透传。

func DecryptPayload

func DecryptPayload(payload map[string]any) (map[string]any, error)

DecryptPayload 解密带加密标记的载荷;未加密载荷原样返回。

func EncryptIfNeeded

func EncryptIfNeeded(plaintext string) (string, error)

EncryptIfNeeded 在加密器启用时加密 plaintext,否则原样返回。

func EncryptPayload

func EncryptPayload(payload map[string]any, reservedKeys ...string) (map[string]any, error)

EncryptPayload 加密载荷,并保留 reservedKeys 指定的路由字段。

func HTTPRequest

func HTTPRequest(ctx context.Context, client *http.Client, rawURL, method string, headers map[string]string, body string, maxBody int64) (map[string]any, error)

func HasEncryptedPayload

func HasEncryptedPayload(payload map[string]any) bool

HasEncryptedPayload 判断载荷是否标记为已加密。

func InitGlobalEncryptor

func InitGlobalEncryptor(key string, enabled bool) error

InitGlobalEncryptor 初始化全局 AES-GCM 加密器。enabled 为 false 时保留明文透传行为。

func IsEncrypted

func IsEncrypted(data string) bool

IsEncrypted 判断 data 是否带有 enc: 加密前缀。

func Logf

func Logf(logger Logger, ctx context.Context, level string, format string, args ...any)

Logf 按 level 格式化消息并转发给 Logger。

Types

type HTTPOptions

type HTTPOptions struct {
	AllowedDomains  []string
	Timeout         time.Duration
	MaxResponseBody int64
	DenyLoopback    bool
}

func HTTPAllowlistFromEnv

func HTTPAllowlistFromEnv() HTTPOptions

func NormalizeHTTPOptions

func NormalizeHTTPOptions(o HTTPOptions) HTTPOptions

type Logger

type Logger interface {
	Debug(ctx context.Context, msg string, args ...any)
	Info(ctx context.Context, msg string, args ...any)
	Warn(ctx context.Context, msg string, args ...any)
	Error(ctx context.Context, msg string, args ...any)
}

Logger 定义宿主模块所需的最小日志接口。

func NewKitLogger

func NewKitLogger() Logger

NewKitLogger 创建基于 kratos-kit/logger 的标准日志适配器。

type ModuleDef

type ModuleDef struct {
	Name  string
	Funcs map[string]any
}

ModuleDef 是语言无关的宿主模块定义。Name 是模块名,Funcs 保存脚本可调用的 Go 函数。

func ModuleCrypto

func ModuleCrypto() ModuleDef

ModuleCrypto 构建提供字符串、JSON 和 SHA-256 操作的 crypto 模块。

func ModuleHTTP

func ModuleHTTP(opts HTTPOptions) ModuleDef

func ModuleLogger

func ModuleLogger(logger Logger) ModuleDef

ModuleLogger 构建提供 info、warn、error、debug 及其格式化版本的 log 模块。

func ModuleUtil

func ModuleUtil(maxSleep ...time.Duration) ModuleDef

ModuleUtil 构建提供 sleep、time、timestamp 和 date 操作的 util 模块。 maxSleep 限制脚本 sleep 的最长时间,默认值为 5 秒。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL