Documentation
¶
Overview ¶
Package script runs user-supplied JavaScript hooks that rewrite relayed HTTP requests and responses.
A script may export two optional hook functions:
function onRequest(req) // mutate req in place, or return a response to short-circuit function onResponse(resp, req) // mutate resp in place
The binding model is intentionally simple (mitmproxy/whistle style):
- req.method / req.url / req.host are strings.
- req.headers / resp.headers are plain objects keyed by canonical header name; assigning a string sets the header, `delete h[k]` removes it, and assigning "" keeps the header present with an empty value.
- req.body / resp.body are strings.
onRequest may `return { status, headers, body }` to short-circuit: the relay skips the upstream call but still runs onResponse on the synthesized response.
An Engine is safe for concurrent use and supports hot-reload: Reload swaps in a freshly compiled script atomically, and pooled runtimes tagged with an older generation are rebuilt on next use. A failed Reload keeps the previous version serving traffic.
Index ¶
- Constants
- type Engine
- func (e *Engine) BeginResponseStream(ctx context.Context, resp *Response, req *Request) (*ResponseStream, error)
- func (e *Engine) HasRequestHook() bool
- func (e *Engine) HasResponseEventHook() bool
- func (e *Engine) HasResponseHook() bool
- func (e *Engine) OnRequest(req *Request) (*Response, error)
- func (e *Engine) OnResponse(resp *Response, req *Request) error
- func (e *Engine) Reload() error
- func (e *Engine) Watch(mode ReloadMode, interval time.Duration, onReload func(error)) (stop func(), err error)
- type HTTPInfo
- type HTTPOptions
- type HTTPRequest
- type HTTPResponse
- type HTTPService
- type Options
- type ProfileInfo
- type ProfileOptions
- type Registry
- type ReloadMode
- type Request
- type Response
- type ResponseStream
- type SSEEvent
Constants ¶
const DefaultPollInterval = time.Second
DefaultPollInterval is the stat cadence used by ReloadPoll when no interval is supplied.
const DefaultTimeout = 200 * time.Millisecond
DefaultTimeout bounds a single hook invocation when Options.Timeout is zero.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine is a compiled script ready to run hooks.
func New ¶
New compiles the script at opts.Path. If opts.Path is empty it returns (nil, nil) so callers can treat "no script" as a disabled feature. A missing file, a syntax error, or a non-function hook export is a fatal error.
func (*Engine) BeginResponseStream ¶ added in v0.14.0
func (e *Engine) BeginResponseStream(ctx context.Context, resp *Response, req *Request) (*ResponseStream, error)
BeginResponseStream runs onResponseStart, if present, and returns a stream session that preserves its returned JavaScript value as private state.
func (*Engine) HasRequestHook ¶
HasRequestHook reports whether the current script defines onRequest.
func (*Engine) HasResponseEventHook ¶ added in v0.14.0
HasResponseEventHook reports whether the current script handles SSE events.
func (*Engine) HasResponseHook ¶
HasResponseHook reports whether the current script defines onResponse.
func (*Engine) OnRequest ¶
OnRequest runs onRequest against req, mutating it in place. If the script returns a response object it is returned here (non-nil) to short-circuit the upstream call. A thrown error or timeout is returned as a non-nil error.
func (*Engine) OnResponse ¶
OnResponse runs onResponse against resp, mutating it in place, with req as read-only context. A thrown error or timeout is returned as a non-nil error.
func (*Engine) Reload ¶
Reload recompiles the script from disk and publishes it atomically. On a compile/validation error the previous version is retained and the error is returned, so in-flight traffic is never disrupted by a bad edit.
func (*Engine) Watch ¶
func (e *Engine) Watch(mode ReloadMode, interval time.Duration, onReload func(error)) (stop func(), err error)
Watch starts watching the engine's script file and calls Reload on change. onReload, if non-nil, is invoked after each reload attempt with its error (nil on success) so callers can log the outcome. It returns a stop function; calling it ends watching and releases resources. For ReloadOff it is a no-op.
type HTTPInfo ¶ added in v0.13.0
type HTTPInfo struct {
Enabled bool
AllowedOrigins int
DefaultTimeout time.Duration
MaxTimeout time.Duration
MaxRequestBodyBytes int64
MaxResponseBodyBytes int64
MaxCallsPerHook int
FollowRedirects bool
AllowPrivateNetworks bool
}
HTTPInfo is safe startup metadata for the script HTTP capability.
type HTTPOptions ¶ added in v0.13.0
type HTTPOptions struct {
Enabled bool
AllowedOrigins []string
DefaultTimeout time.Duration
MaxTimeout time.Duration
MaxRequestBodyBytes int64
MaxResponseBodyBytes int64
MaxCallsPerHook int
FollowRedirects bool
AllowPrivateNetworks bool
}
HTTPOptions configures the synchronous relay.http.request capability.
type HTTPRequest ¶ added in v0.13.0
type HTTPRequest struct {
URL string
Method string
Headers map[string]string
Body string
Timeout time.Duration
HasBody bool
HasTimeout bool
}
HTTPRequest is the validated Go-side representation of one JS request.
type HTTPResponse ¶ added in v0.13.0
HTTPResponse is returned to JavaScript as a plain object.
type HTTPService ¶ added in v0.13.0
type HTTPService struct {
// contains filtered or unexported fields
}
HTTPService owns the shared HTTP policy and transport used by all engines.
func NewHTTPService ¶ added in v0.13.0
func NewHTTPService(opts HTTPOptions) (*HTTPService, error)
NewHTTPService validates opts and creates a dedicated client that does not use environment proxies or a cookie jar.
func (*HTTPService) Enabled ¶ added in v0.13.0
func (s *HTTPService) Enabled() bool
func (*HTTPService) Info ¶ added in v0.13.0
func (s *HTTPService) Info() HTTPInfo
func (*HTTPService) Request ¶ added in v0.13.0
func (s *HTTPService) Request(ctx context.Context, request HTTPRequest) (*HTTPResponse, error)
Request executes one policy-checked request under the current Hook context.
type Options ¶
type Options struct {
// Path is the script file to compile, or a diagnostic label when Source is
// set. Path and Source both empty disables scripting.
Path string
// Source is an optional in-memory script. When set, Path is used only as a
// diagnostic label and the script cannot be watched for file changes.
Source string
// Timeout bounds a single hook invocation. Zero uses DefaultTimeout.
Timeout time.Duration
// Console receives output from console.log/info/warn/error/debug calls in
// the script. Nil discards it.
Console io.Writer
// HTTP provides the optional synchronous relay.http.request capability.
HTTP *HTTPService
}
Options configures a script Engine.
type ProfileInfo ¶ added in v0.11.0
type ProfileInfo struct {
Name string
Path string
Timeout time.Duration
Reload ReloadMode
HasRequest bool
HasResponse bool
}
ProfileInfo is safe metadata used by startup logs and diagnostics.
type ProfileOptions ¶ added in v0.11.0
type ProfileOptions struct {
Name string
Path string
Source string
Timeout time.Duration
Reload ReloadMode
Console io.Writer
HTTP *HTTPService
}
ProfileOptions configures one named rewrite profile.
type Registry ¶ added in v0.11.0
type Registry struct {
// contains filtered or unexported fields
}
Registry owns the legacy default engine and all configured named engines. Its profile map is immutable after construction; individual engines publish hot-reloaded versions atomically.
func NewRegistry ¶ added in v0.11.0
func NewRegistry(defaultEngine *Engine, profiles []ProfileOptions) (*Registry, error)
func (*Registry) Profiles ¶ added in v0.11.0
func (r *Registry) Profiles() []ProfileInfo
func (*Registry) WatchAll ¶ added in v0.11.0
func (r *Registry) WatchAll(defaultReload ReloadMode, onReload func(profile string, err error)) (func(), error)
WatchAll starts the default and named watchers as one lifecycle. If any watcher cannot start, already-started watchers are stopped before returning.
type ReloadMode ¶
type ReloadMode int
ReloadMode selects how an Engine watches its script file for changes.
const ( // ReloadOff disables hot-reload; the script is loaded once at startup. ReloadOff ReloadMode = iota // ReloadWatch uses filesystem notifications (fsnotify). ReloadWatch // ReloadPoll periodically stats the file's modification time. ReloadPoll )
func ParseReloadMode ¶
func ParseReloadMode(raw string) (ReloadMode, error)
ParseReloadMode parses a CLI value into a ReloadMode. An empty string defaults to ReloadWatch.
func (ReloadMode) String ¶
func (m ReloadMode) String() string
type Request ¶
type Request struct {
Method string
URL string
Host string
Header http.Header
Body []byte
Namespace string
RewriteProfile string
OriginalPath string
// StreamResponse selects event-level SSE response hooks for this request.
// Scripts may set req.streamResponse in onRequest.
StreamResponse bool
}
Request is the mutable view of an inbound request handed to onRequest.
type Response ¶
Response is the mutable view of a response handed to onResponse, and the shape onRequest returns to short-circuit the upstream call.
type ResponseStream ¶ added in v0.14.0
type ResponseStream struct {
// contains filtered or unexported fields
}
ResponseStream owns one pooled JavaScript runtime for the lifetime of a single response stream. It must be closed exactly once by the caller.
func (*ResponseStream) Close ¶ added in v0.14.0
func (s *ResponseStream) Close()
Close returns the private runtime to the pool. It is safe to call repeatedly.