WEB: Base Path added

This commit is contained in:
Alexey
2026-09-26 13:49:28 +03:00
parent 326c0ecdb9
commit 5feded2919
32 changed files with 1094 additions and 125 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
(()=>{'use strict';
let bootstrap="__BOOTSTRAP__",hello=false,emitted=0,boundaryTimer=null;
const relayOrigin='https://__HOST__',requestMs=__BRIDGE_REQUEST_SECS__*1000;
const relayOrigin='https://__HOST__',relayBase=relayOrigin+'__BASE_PREFIX__',requestMs=__BRIDGE_REQUEST_SECS__*1000;
function eventBit(event){
if(event==='runtime_started')return 1;if(event==='status_posted')return 2;if(event==='hello_received')return 4;if(event==='boundary_timeout')return 8;
if(event==='hello_timeout')return 16;if(event==='client_close_before_hello')return 32;if(event==='document_unloaded_before_hello')return 64;
@@ -12,7 +12,7 @@ function report(event){
let timer=null;
try{
const controller=new AbortController(),body=JSON.stringify({v:1,event});timer=setTimeout(()=>controller.abort(),requestMs);
fetch(relayOrigin+'/api/v1/diagnostic',{method:'POST',body,signal:controller.signal,keepalive:true,mode:'same-origin',credentials:'omit',cache:'no-store',redirect:'error',referrerPolicy:'no-referrer',headers:{Authorization:'Bearer '+bootstrap,'Content-Type':'application/json'}})
fetch(relayBase+'/api/v1/diagnostic',{method:'POST',body,signal:controller.signal,keepalive:true,mode:'same-origin',credentials:'omit',cache:'no-store',redirect:'error',referrerPolicy:'no-referrer',headers:{Authorization:'Bearer '+bootstrap,'Content-Type':'application/json'}})
.then(discard,()=>{}).then(()=>clearTimeout(timer),()=>clearTimeout(timer));
}catch(error){if(timer)clearTimeout(timer)}
}
+1 -1
View File
@@ -40,7 +40,7 @@ function create(settings){
const timer=setTimeout(()=>{timedOut=true;controller.abort()},Math.max(1,Math.min(attemptLimit,remaining)));
let response=null,wait=0;
try{
const fetched=await fetch(settings.origin()+path,requestOptions);
const fetched=await fetch(settings.base()+path,requestOptions);
if(retryableStatus(fetched.status)){
lastReason='http';wait=retryAfterMs(fetched);settings.cancel(fetched);
}else{
+4 -4
View File
@@ -1,6 +1,6 @@
(()=>{'use strict';
let bootstrap="__BOOTSTRAP__";
const relayOrigin='https://__HOST__',carrierCapabilities='https,https-lanes,websocket,websocket-lanes';
const relayOrigin='https://__HOST__',relayBase=relayOrigin+'__BASE_PREFIX__',carrierCapabilities='https,https-lanes,websocket,websocket-lanes';
__DIAGNOSTIC_BINDING__;
__DIAGNOSTIC_RUNTIME_STARTED__;
const responseBody=globalThis.TelemtBridgeResponse;if(!responseBody)throw new Error('missing response runtime');
@@ -26,9 +26,9 @@ const canonicalFailures=['timeout','network','upgrade','http','protocol'];
const failure=(reason,message)=>Object.assign(new Error(message||reason),{telemtReason:reason});
const failureReason=(error,fallback)=>error&&canonicalFailures.includes(error.telemtReason)?error.telemtReason:fallback;
const status=__STATUS_FUNCTION__;
const socketURL=()=>relayOrigin.replace(/^https:/,'wss:')+'/api/v1/ws';
const socketURL=()=>relayBase.replace(/^https:/,'wss:')+'/api/v1/ws';
const requestClient=requestSupport.create({
origin:()=>relayOrigin,closed:()=>closed,retryMs:()=>bridgeRetryMs,longPollMs:()=>longPollMs,requestMs:()=>bridgeRequestMs,
base:()=>relayBase,closed:()=>closed,retryMs:()=>bridgeRetryMs,longPollMs:()=>longPollMs,requestMs:()=>bridgeRequestMs,
batchLimit:()=>batchLimit,read:(response,limit,exact,signal)=>responseBody.read(response,limit,exact,signal),cancel:responseBody.cancel,
failure,reason:failureReason,retrying:()=>status('reconnecting')
});
@@ -478,7 +478,7 @@ async function pollLane(lane){
}
function deleteSession(){
const token=cleanupToken||sessionToken,headers=canonicalFailures.includes(terminalFailure)?{'X-Carrier-Failure':terminalFailure}:null;
if(token)fetch(relayOrigin+'/api/v1/session',options('DELETE',token,null,headers,undefined,true)).catch(()=>{});
if(token)fetch(relayBase+'/api/v1/session',options('DELETE',token,null,headers,undefined,true)).catch(()=>{});
}
function close(notifyServer){
if(closed)return;closed=true;if(recoveryController)recoveryController.cancel();rejectRecoveryCommit(failure('network','bridge closed'));if(helloTimer)clearTimeout(helloTimer);helloTimer=null;if(carrierTimer)clearTimeout(carrierTimer);clearProbeTimer();if(schedulerTimer)clearTimeout(schedulerTimer);schedulerTimer=null;if(attemptController)attemptController.abort();if(pollController)pollController.abort();
+42 -1
View File
@@ -3,6 +3,7 @@ use super::*;
fn render_page(bootstrap: &str, candidate_count: usize) -> BridgePage {
render(
"proxy.example.com",
"/",
bootstrap,
2 * 1024 * 1024,
32 * 1024 * 1024,
@@ -26,6 +27,7 @@ fn render_page(bootstrap: &str, candidate_count: usize) -> BridgePage {
fn render_diagnostic_page(bootstrap: &str) -> BridgePage {
render(
"proxy.example.com",
"/",
bootstrap,
2 * 1024 * 1024,
32 * 1024 * 1024,
@@ -72,6 +74,43 @@ fn rendered_page_contains_bounded_negotiation_contract() {
);
}
#[test]
fn rendered_page_resolves_carriers_against_the_exact_base_path() {
let page = render(
"proxy.example.com",
"/Dobry-Cola/super_app/",
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
2 * 1024 * 1024,
32 * 1024 * 1024,
16 * 1024,
1024,
true,
4,
[3, 5, 8, 12],
25,
10,
90,
15,
15,
120,
0,
true,
&SecureRandom::new(),
);
assert!(page.body.contains(
"relayBase=relayOrigin+'/Dobry-Cola/super_app'"
));
assert!(page.body.contains("fetch(settings.base()+path"));
assert!(page.body.contains(
"relayBase.replace(/^https:/,'wss:')+'/api/v1/ws'"
));
assert!(page.body.contains("fetch(relayBase+'/api/v1/diagnostic'"));
assert!(page.body.contains("url:()=>relayOrigin+recoveryPath"));
assert!(!page.body.contains("/Dobry-Cola/super_app/Dobry-Cola/super_app"));
assert!(!page.body.contains("__BASE_PREFIX__"));
}
#[test]
fn rendered_page_preserves_the_ios_bootstrap_literal() {
let bootstrap = "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
@@ -86,6 +125,7 @@ fn rendered_page_preserves_the_ios_bootstrap_literal() {
fn rendered_page_embeds_the_configured_bridge_timing_policy() {
let page = render(
"proxy.example.com",
"/",
"GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG",
2 * 1024 * 1024,
32 * 1024 * 1024,
@@ -138,6 +178,7 @@ fn effective_deadline_formula_uses_the_final_checkpoint() {
fn disabled_negotiation_does_not_arm_a_carrier_deadline() {
let page = render(
"proxy.example.com",
"/",
"DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD",
2 * 1024 * 1024,
32 * 1024 * 1024,
@@ -284,7 +325,7 @@ fn enabled_bridge_diagnostics_use_the_https_sideband_only() {
let page = render_diagnostic_page("JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ");
assert!(!page.body.contains("__"));
assert!(page.body.contains("fetch(relayOrigin+'/api/v1/diagnostic'"));
assert!(page.body.contains("fetch(relayBase+'/api/v1/diagnostic'"));
assert!(page.body.contains("JSON.stringify({v:1,event})"));
assert!(page.body.contains("'Content-Type':'application/json'"));
assert!(page.body.contains("keepalive:true"));