tfrere HF Staff Cursor commited on
Commit
35110ea
·
1 Parent(s): 2b065e9

fix: propagate private-space __sign JWT to all same-origin requests

Browse files
Files changed (3) hide show
  1. duck.js +7 -2
  2. index.html +8 -1
  3. rl.js +22 -7
duck.js CHANGED
@@ -19,6 +19,11 @@ export const MESH_VERSION = "8";
19
  // targets them.
20
  export const MODEL_DIR = "./robot/mjlab";
21
 
 
 
 
 
 
22
  // Meshes fully occluded inside the shells at every demo camera angle,
23
  // verified empirically by per-mesh pixel-diff (front 3/4, back, low
24
  // front close-up): hiding each changes exactly 0 pixels. Skipped at
@@ -29,7 +34,7 @@ const HIDDEN_MESHES = new Set([]);
29
  export async function loadKinematics(url) {
30
  // Same cache-buster as the STLs: force-cache would otherwise keep
31
  // serving a stale kinematics.json after the mesh list changes.
32
- const r = await fetch(`${url}?v=${MESH_VERSION}`, { cache: "force-cache" });
33
  if (!r.ok) throw new Error(`kinematics fetch ${r.status}`);
34
  const k = await r.json();
35
  // Full-resolution meshes by default (the reduction will be redone
@@ -75,7 +80,7 @@ export async function buildRig(k, opts = {}) {
75
  if (!meshCache.has(name)) {
76
  meshCache.set(
77
  name,
78
- loader.loadAsync(`${k.mesh_dir}/${name}?v=${MESH_VERSION}`).then((raw) => {
79
  raw.deleteAttribute("normal");
80
  const welded = mergeVertices(raw, 1e-4);
81
  welded.scale(1000, 1000, 1000);
 
19
  // targets them.
20
  export const MODEL_DIR = "./robot/mjlab";
21
 
22
+ // On a private HF Space, rl.js installs a URL signer that appends the
23
+ // ?__sign JWT to same-origin requests (auth cookies may be blocked in the
24
+ // hub iframe). Identity everywhere else.
25
+ const signed = (url) => (window.__hfSigned ? window.__hfSigned(url) : url);
26
+
27
  // Meshes fully occluded inside the shells at every demo camera angle,
28
  // verified empirically by per-mesh pixel-diff (front 3/4, back, low
29
  // front close-up): hiding each changes exactly 0 pixels. Skipped at
 
34
  export async function loadKinematics(url) {
35
  // Same cache-buster as the STLs: force-cache would otherwise keep
36
  // serving a stale kinematics.json after the mesh list changes.
37
+ const r = await fetch(signed(`${url}?v=${MESH_VERSION}`), { cache: "force-cache" });
38
  if (!r.ok) throw new Error(`kinematics fetch ${r.status}`);
39
  const k = await r.json();
40
  // Full-resolution meshes by default (the reduction will be redone
 
80
  if (!meshCache.has(name)) {
81
  meshCache.set(
82
  name,
83
+ loader.loadAsync(signed(`${k.mesh_dir}/${name}?v=${MESH_VERSION}`)).then((raw) => {
84
  raw.deleteAttribute("normal");
85
  const welded = mergeVertices(raw, 1e-4);
86
  welded.scale(1000, 1000, 1000);
index.html CHANGED
@@ -178,6 +178,13 @@
178
  }
179
  }
180
  </script>
181
- <script type="module" src="./rl.js"></script>
 
 
 
 
 
 
 
182
  </body>
183
  </html>
 
178
  }
179
  }
180
  </script>
181
+ <!-- rl.js is imported dynamically with the private-space ?__sign JWT
182
+ appended: a plain src attribute can 401 when the browser blocks the
183
+ *.static.hf.space auth cookie inside the hub iframe. -->
184
+ <script type="module">
185
+ const sign = new URLSearchParams(location.search).get("__sign");
186
+ const suffix = sign ? `?__sign=${encodeURIComponent(sign)}` : "";
187
+ import(`./rl.js${suffix}`);
188
+ </script>
189
  </body>
190
  </html>
rl.js CHANGED
@@ -17,11 +17,26 @@
17
  import * as THREE from "three";
18
  import { OrbitControls } from "three/addons/controls/OrbitControls.js";
19
  import { RoomEnvironment } from "three/addons/environments/RoomEnvironment.js";
20
- import { buildRig, loadKinematics, setJoint, setJawOpen, MODEL_DIR, MESH_VERSION } from "./duck.js";
21
- import { VARIANTS, VARIANT_NAMES, materialHookFor, randomVariantName, applyVariant, specToHex } from "./variants.js";
22
  import loadMujoco from "https://cdn.jsdelivr.net/npm/@mujoco/mujoco@3.11.0/mujoco.js";
23
  import * as ort from "https://cdn.jsdelivr.net/npm/onnxruntime-web@1.27.0/dist/ort.min.mjs";
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  ort.env.wasm.wasmPaths = "https://cdn.jsdelivr.net/npm/onnxruntime-web@1.27.0/dist/";
26
  ort.env.wasm.numThreads = 1; // static hosting sends no COOP/COEP headers
27
 
@@ -94,7 +109,7 @@ const traced = (label, p) => {
94
  // Stripping them means the MuJoCo VFS only needs the ~10 meshes referenced
95
  // by collision geoms.
96
  async function buildPhysicsXml() {
97
- const src = await (await fetch(`${MODEL_DIR}/robot_allcollisions.xml`)).text();
98
  const doc = new DOMParser().parseFromString(src, "text/xml");
99
  for (const g of [...doc.querySelectorAll('geom[class="visual"]')]) g.remove();
100
  const usedMeshes = new Set(
@@ -138,7 +153,7 @@ await Promise.all(
138
  meshFiles.map(async (f) => {
139
  // Same cache-busted URL as duck.js so the browser reuses the render
140
  // meshes instead of downloading the collision subset a second time.
141
- const buf = await (await fetch(`${MODEL_DIR}/meshes/${f}?v=${MESH_VERSION}`, { cache: "force-cache" })).arrayBuffer();
142
  // meshdir="assets" in the MJCF, so the compiler looks up "assets/<f>".
143
  vfs.addBuffer(`assets/${f}`, new Uint8Array(buf));
144
  }),
@@ -151,9 +166,9 @@ const rigPromise = (async () => {
151
  })();
152
  const sessionOpts = { executionProviders: ["wasm"] };
153
  [sessions.walk, sessions.sitstand, sessions.roulade] = await Promise.all([
154
- ort.InferenceSession.create(POLICIES.walk, sessionOpts),
155
- ort.InferenceSession.create(POLICIES.sitstand, sessionOpts),
156
- ort.InferenceSession.create(POLICIES.roulade, sessionOpts),
157
  ]);
158
 
159
  setLoading("Compiling physics\u2026");
 
17
  import * as THREE from "three";
18
  import { OrbitControls } from "three/addons/controls/OrbitControls.js";
19
  import { RoomEnvironment } from "three/addons/environments/RoomEnvironment.js";
 
 
20
  import loadMujoco from "https://cdn.jsdelivr.net/npm/@mujoco/mujoco@3.11.0/mujoco.js";
21
  import * as ort from "https://cdn.jsdelivr.net/npm/onnxruntime-web@1.27.0/dist/ort.min.mjs";
22
 
23
+ // Private HF Space auth: the hub iframe URL carries a ?__sign JWT, but
24
+ // subresource requests normally rely on a *.static.hf.space cookie that
25
+ // browsers often block inside the iframe (third-party cookie blocking),
26
+ // which 401s every same-origin fetch. Appending the JWT to each request
27
+ // authenticates them regardless of cookie policy. No-op locally.
28
+ const HF_SIGN = new URLSearchParams(location.search).get("__sign");
29
+ const signed = (url) =>
30
+ HF_SIGN ? `${url}${url.includes("?") ? "&" : "?"}__sign=${encodeURIComponent(HF_SIGN)}` : url;
31
+ window.__hfSigned = signed; // duck.js uses it for kinematics + STL requests
32
+
33
+ // Local modules are imported dynamically through signed() for the same
34
+ // reason: a static import of ./duck.js would 401 without the cookie.
35
+ const { buildRig, loadKinematics, setJoint, setJawOpen, MODEL_DIR, MESH_VERSION } =
36
+ await import(signed("./duck.js"));
37
+ const { VARIANTS, VARIANT_NAMES, materialHookFor, randomVariantName, applyVariant, specToHex } =
38
+ await import(signed("./variants.js"));
39
+
40
  ort.env.wasm.wasmPaths = "https://cdn.jsdelivr.net/npm/onnxruntime-web@1.27.0/dist/";
41
  ort.env.wasm.numThreads = 1; // static hosting sends no COOP/COEP headers
42
 
 
109
  // Stripping them means the MuJoCo VFS only needs the ~10 meshes referenced
110
  // by collision geoms.
111
  async function buildPhysicsXml() {
112
+ const src = await (await fetch(signed(`${MODEL_DIR}/robot_allcollisions.xml`))).text();
113
  const doc = new DOMParser().parseFromString(src, "text/xml");
114
  for (const g of [...doc.querySelectorAll('geom[class="visual"]')]) g.remove();
115
  const usedMeshes = new Set(
 
153
  meshFiles.map(async (f) => {
154
  // Same cache-busted URL as duck.js so the browser reuses the render
155
  // meshes instead of downloading the collision subset a second time.
156
+ const buf = await (await fetch(signed(`${MODEL_DIR}/meshes/${f}?v=${MESH_VERSION}`), { cache: "force-cache" })).arrayBuffer();
157
  // meshdir="assets" in the MJCF, so the compiler looks up "assets/<f>".
158
  vfs.addBuffer(`assets/${f}`, new Uint8Array(buf));
159
  }),
 
166
  })();
167
  const sessionOpts = { executionProviders: ["wasm"] };
168
  [sessions.walk, sessions.sitstand, sessions.roulade] = await Promise.all([
169
+ ort.InferenceSession.create(signed(POLICIES.walk), sessionOpts),
170
+ ort.InferenceSession.create(signed(POLICIES.sitstand), sessionOpts),
171
+ ort.InferenceSession.create(signed(POLICIES.roulade), sessionOpts),
172
  ]);
173
 
174
  setLoading("Compiling physics\u2026");