Skip to content

Commit 938e2b4

Browse files
author
yiguo
committed
Document layered invoke env behavior
1 parent 73bb811 commit 938e2b4

4 files changed

Lines changed: 58 additions & 8 deletions

File tree

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,12 @@ The response is a JSON object:
153153
```
154154

155155
`env` is optional and only supports Xray-core environment variables that are
156-
explicitly modeled by libXray:
156+
explicitly modeled by libXray. Passing `env` sets process environment variables
157+
and reloads Xray-core's process-global env-backed settings before the method
158+
continues. It is primarily used for load-stage keys and runtime values that are
159+
not known when the Xray JSON is generated. Reloadable runtime keys can also be
160+
declared in the Xray config root `env` object, which is applied during config
161+
build and overrides same-name external values.
157162

158163
| JSON key | Meaning |
159164
| --- | --- |
@@ -178,7 +183,10 @@ Design notes:
178183
2. Unknown `env` keys are ignored and are not written to the process environment.
179184
3. `env` only sets modeled, non-empty fields. Missing fields are not unset.
180185
4. libXray does not restore previous environment values after a method returns. Callers must pass the required env fields on every request that depends on them. This avoids concurrent calls restoring stale values over newer values.
181-
5. `SetTunFd` has been removed. Pass `xray.tun.fd` in the `env` object of the `runXray` request.
186+
5. `xray.json.strict`, `xray.location.config`, and `xray.location.confdir` are load-stage keys and must stay outside the Xray JSON config.
187+
6. Xray config root `env` does not accept those three load-stage keys. Other reloadable keys declared there override same-name values from `Invoke.env`.
188+
7. `env` reloads Xray-core process-global env-backed settings. It does not provide per-instance environment isolation.
189+
8. `SetTunFd` has been removed. Pass `xray.tun.fd` in the `env` object of the `runXray` request when the fd is only known at runtime.
182190

183191
Supported methods:
184192

invoke.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ func Invoke(requestJSON string) string {
2626
if err := validateAPIVersion(request.APIVersion); err != nil {
2727
return encodeInvokeResponse(nil, err)
2828
}
29-
applyEnv(request.Env)
29+
if err := applyEnv(request.Env); err != nil {
30+
return encodeInvokeResponse(nil, err)
31+
}
3032

3133
switch request.Method {
3234
case LibXrayMethodGetFreePorts:
@@ -63,9 +65,9 @@ func validateAPIVersion(version int) error {
6365
return errors.New("unsupported apiVersion")
6466
}
6567

66-
func applyEnv(env *LibXrayEnvJson) {
68+
func applyEnv(env *LibXrayEnvJson) error {
6769
if env == nil {
68-
return
70+
return nil
6971
}
7072
setEnvIfNotEmpty(platform.ConfigLocation, env.ConfigLocation)
7173
setEnvIfNotEmpty(platform.ConfdirLocation, env.ConfdirLocation)
@@ -81,6 +83,7 @@ func applyEnv(env *LibXrayEnvJson) {
8183
setEnvIfNotEmpty(platform.XUDPLog, env.XUDPLog)
8284
setEnvIfNotEmpty(platform.XUDPBaseKey, env.XUDPBaseKey)
8385
setEnvIfNotEmpty(platform.TunFdKey, env.TunFd)
86+
return platform.ReloadEnvSettings()
8487
}
8588

8689
func setEnvIfNotEmpty(key string, value string) {

invoke_test.go

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package libXray
22

33
import (
4+
"bytes"
45
"encoding/base64"
56
"encoding/json"
67
"os"
78
"path/filepath"
89
"testing"
910

1011
"github.com/xtls/xray-core/common/platform"
12+
"github.com/xtls/xray-core/infra/conf/serial"
1113
)
1214

1315
type testResponse struct {
@@ -282,7 +284,7 @@ func TestInvokeSetsAllSupportedEnvFields(t *testing.T) {
282284
{"buffer size", platform.BufferSize, "buffer-size-value"},
283285
{"browser dialer", platform.BrowserDialerAddress, "browser-dialer-value"},
284286
{"xudp log", platform.XUDPLog, "xudp-log-value"},
285-
{"xudp base key", platform.XUDPBaseKey, "xudp-base-key-value"},
287+
{"xudp base key", platform.XUDPBaseKey, base64.RawURLEncoding.EncodeToString(bytes.Repeat([]byte{7}, 32))},
286288
{"tun fd", platform.TunFdKey, "123"},
287289
}
288290
for _, tt := range tests {
@@ -303,6 +305,37 @@ func TestInvokeSetsAllSupportedEnvFields(t *testing.T) {
303305
}
304306
}
305307

308+
func TestInvokeEnvReloadsXrayCoreSettings(t *testing.T) {
309+
original, existed := os.LookupEnv(platform.UseStrictJSON)
310+
_ = os.Setenv(platform.UseStrictJSON, "false")
311+
platform.ReloadEnvSettings()
312+
t.Cleanup(func() {
313+
if existed {
314+
_ = os.Setenv(platform.UseStrictJSON, original)
315+
} else {
316+
_ = os.Unsetenv(platform.UseStrictJSON)
317+
}
318+
platform.ReloadEnvSettings()
319+
})
320+
321+
if serial.IsStrictJSONEnabled() {
322+
t.Fatal("strict JSON should start disabled")
323+
}
324+
325+
response := invokeForTest(
326+
t,
327+
LibXrayMethodXrayVersion,
328+
&LibXrayEnvJson{UseStrictJSON: "true"},
329+
nil,
330+
)
331+
if !response.Success {
332+
t.Fatalf("XrayVersion failed: %s", response.Err)
333+
}
334+
if !serial.IsStrictJSONEnabled() {
335+
t.Fatal("Invoke.env did not reload strict JSON setting")
336+
}
337+
}
338+
306339
func TestInvokeUnknownMethod(t *testing.T) {
307340
response := invokeForTest(t, LibXrayMethod("unknown"), nil, nil)
308341
if response.Success {

readme/README.zh_CN.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,10 @@ char* CGoInvoke(char* requestJSON);
120120
}
121121
```
122122

123-
`env` 是可选字段,只支持 libXray 显式建模的 Xray-core 环境变量:
123+
`env` 是可选字段,只支持 libXray 显式建模的 Xray-core 环境变量。传入 `env`
124+
会写入进程环境变量,并在 method 继续执行前 reload Xray-core 的进程全局 env-backed settings。
125+
它主要用于加载前 key,以及生成 Xray JSON 时还不知道的运行时值。可 reload 的运行时 key
126+
也可以写在 Xray 配置根 `env` 对象中;配置根 `env` 会在 config build 阶段应用,并覆盖同名外部值。
124127

125128
| JSON key | 含义 |
126129
| --- | --- |
@@ -145,7 +148,10 @@ char* CGoInvoke(char* requestJSON);
145148
2. 未知 `env` key 会被忽略,不会写入进程环境变量。
146149
3. `env` 只设置已建模的非空字段,缺失字段不会 unset。
147150
4. libXray 不会在 method 结束后 restore 旧环境变量。调用方必须在每次依赖环境变量的请求中显式传入对应字段。这样可以避免并发调用时,一个请求恢复旧值覆盖另一个请求的新值。
148-
5. `SetTunFd` 已删除。请在 `runXray` 请求的 `env` 对象中传入 `xray.tun.fd`
151+
5. `xray.json.strict``xray.location.config``xray.location.confdir` 属于加载前 key,必须保留在 Xray JSON 配置外部。
152+
6. Xray 配置根 `env` 不接受上述三个加载前 key;其他可 reload key 写在配置根 `env` 时会覆盖 `Invoke.env` 中的同名值。
153+
7. `env` reload 的是 Xray-core 进程全局 env-backed settings,不提供 per-instance 环境隔离。
154+
8. `SetTunFd` 已删除。如果 fd 只能在运行时获得,请在 `runXray` 请求的 `env` 对象中传入 `xray.tun.fd`
149155

150156
支持的 method:
151157

0 commit comments

Comments
 (0)