diff --git a/sdk/go/README.md b/sdk/go/README.md index 130c397f2..8962b6317 100644 --- a/sdk/go/README.md +++ b/sdk/go/README.md @@ -198,11 +198,15 @@ sb, err := client.Create(ctx, cubesandbox.CreateOptions{ When `CUBE_PROXY_NODE_IP` is set, data-plane requests connect directly to that IP and port while preserving the virtual sandbox host: ```text -URL: ://49999-./ +URL: ://49983-./ TCP: : -Host: 49999-. +Host: 49983-. ``` +The host prefix is the sandbox's internal service port: `49983` (envd) for +commands/filesystem/files/PTY, and `49999` (Jupyter) for the code interpreter +(`RunCode` / `/execute`). + You can also set it directly: ```go diff --git a/sdk/go/envd.go b/sdk/go/envd.go index 72810ddfc..886bac678 100644 --- a/sdk/go/envd.go +++ b/sdk/go/envd.go @@ -225,7 +225,7 @@ func multipartFileBody(path string, data []byte) (io.Reader, string, error) { func (s *Sandbox) newEnvdRequest(ctx context.Context, method, path string, query url.Values, body io.Reader) (*http.Request, error) { target := url.URL{ Scheme: s.client.config.ProxyScheme, - Host: s.GetHost(JupyterPort), + Host: s.GetHost(EnvdPort), Path: path, RawQuery: query.Encode(), } diff --git a/sdk/go/sandbox.go b/sdk/go/sandbox.go index 07ff27d46..0acc2e32a 100644 --- a/sdk/go/sandbox.go +++ b/sdk/go/sandbox.go @@ -13,7 +13,15 @@ import ( "time" ) -const JupyterPort = 49999 +const ( + // JupyterPort is the code-interpreter (Jupyter) port, used only by the + // /execute endpoint (RunCode). + JupyterPort = 49999 + // EnvdPort is the envd daemon port. All envd data-plane RPCs — commands, + // filesystem, files, and PTY — route here, matching the Python/Node SDKs + // (ENVD_PORT = 49983). Sending these to JupyterPort yields 404s. + EnvdPort = 49983 +) func (s *Sandbox) GetHost(port int) string { domain := s.Domain diff --git a/sdk/go/sdk_test.go b/sdk/go/sdk_test.go index 0599e61f0..fa36529c6 100644 --- a/sdk/go/sdk_test.go +++ b/sdk/go/sdk_test.go @@ -655,7 +655,7 @@ func TestCommandsRunUsesEnvdProcessStart(t *testing.T) { t.Fatalf("Run: %v", err) } - if gotHost != "49999-sb-proc.cube.test" { + if gotHost != "49983-sb-proc.cube.test" { t.Fatalf("Host=%q", gotHost) } if gotHeaders.Get("Content-Type") != connectContentType || gotHeaders.Get("Connect-Protocol-Version") != connectProtocolVersion { @@ -721,7 +721,7 @@ func TestFilesReadUsesEnvdHTTPFileAPI(t *testing.T) { if content != "file content" { t.Fatalf("content=%q", content) } - if gotHost != "49999-sb-files.cube.test" || gotPath != "/tmp/foo bar.txt" || gotToken != "envd-token" { + if gotHost != "49983-sb-files.cube.test" || gotPath != "/tmp/foo bar.txt" || gotToken != "envd-token" { t.Fatalf("host/path/token=%q/%q/%q", gotHost, gotPath, gotToken) } } @@ -944,7 +944,7 @@ func TestFilesListUsesEnvdFilesystemRPC(t *testing.T) { if len(entries) != 1 || entries[0].Name != "a.txt" || entries[0].Size != 10 || entries[0].IsDir() { t.Fatalf("entries=%#v", entries) } - if gotHost != "49999-sb-fs.cube.test" || gotPath != "/filesystem.Filesystem/ListDir" || gotCT != "application/json" { + if gotHost != "49983-sb-fs.cube.test" || gotPath != "/filesystem.Filesystem/ListDir" || gotCT != "application/json" { t.Fatalf("host/path/ct=%q/%q/%q", gotHost, gotPath, gotCT) } }