fix #376: detect localhost urls and proxyfy them

This commit is contained in:
Matthieu Baumann
2026-05-31 14:58:50 +02:00
parent 58ffb782cc
commit 21e52325e9
4 changed files with 62 additions and 30 deletions
+10
View File
@@ -13,6 +13,8 @@ use std::io::Cursor;
use std::ops::Range;
use wasm_bindgen::JsValue;
use fitsrs::hdu::header::ValueMap;
#[derive(Debug)]
pub struct FitsImage<'a> {
// Margin values for HiPS3D cubic tiles
@@ -37,6 +39,9 @@ pub struct FitsImage<'a> {
pub data_byte_offset: Range<usize>,
// raw bytes of the data image (in Big-Endian)
pub raw_bytes: Cow<'a, [u8]>,
// keep the header keywords and their values
pub header: ValueMap
}
impl<'a> FitsImage<'a> {
@@ -76,6 +81,7 @@ impl<'a> FitsImage<'a> {
let wcs = hdu.wcs().ok();
let values: &ValueMap = &*header;
images.push(Self {
trim1,
trim2,
@@ -90,6 +96,7 @@ impl<'a> FitsImage<'a> {
blank,
data_byte_offset,
raw_bytes,
header: values.clone()
});
}
}
@@ -149,6 +156,8 @@ impl<'a> FitsImage<'a> {
};
if let Some(raw_bytes) = raw_bytes {
let values: &ValueMap = &*header;
images.push(Self {
trim1,
trim2,
@@ -163,6 +172,7 @@ impl<'a> FitsImage<'a> {
blank,
data_byte_offset,
raw_bytes: Cow::Owned(raw_bytes),
header: values.clone()
});
}
}
+31 -18
View File
@@ -1176,7 +1176,7 @@ impl App {
layer: String,
bytes: &[u8],
wcs: WCS,
cfg: ImageMetadata,
options: ImageMetadata,
) -> Result<js_sys::Promise, JsValue> {
let gl = self.gl.clone();
@@ -1188,7 +1188,7 @@ impl App {
images: vec![image],
id: layer.clone(),
layer,
meta: cfg,
options,
};
let params = layer.get_params();
@@ -1212,9 +1212,11 @@ impl App {
pub(crate) fn add_fits_image(
&mut self,
bytes: &[u8],
meta: ImageMetadata,
options: ImageMetadata,
layer: String,
) -> Result<js_sys::Promise, JsValue> {
use fitsrs::hdu::header::ValueMap;
let gl = self.gl.clone();
// Stop the current inertia
// And disable it while the fits has not been loaded
@@ -1225,19 +1227,20 @@ impl App {
let gz = fitsrs::gz::GzReader::new(Cursor::new(bytes))
.map_err(|_| JsValue::from_str("Error creating gz wrapper"))?;
let parse_fits_images_from_bytes = |raw_bytes: &[u8]| -> Result<Vec<Image>, JsValue> {
Ok(FitsImage::from_raw_bytes(raw_bytes)?
let parse_fits_images_from_bytes = |raw_bytes: &[u8]| -> Result<(Vec<Image>, Vec<ValueMap>), JsValue> {
let (images, headers) = FitsImage::from_raw_bytes(raw_bytes)?
.into_iter()
.filter_map(
|FitsImage {
bitpix,
bscale,
bzero,
blank,
wcs,
raw_bytes,
..
}| {
bitpix,
bscale,
bzero,
blank,
wcs,
raw_bytes,
header,
..
}| {
if let Some(wcs) = wcs {
let image = Image::from_fits_hdu(
&gl,
@@ -1250,16 +1253,18 @@ impl App {
camera_coo_sys,
)
.ok()?;
Some(image)
Some((image, header))
} else {
None
}
},
)
.collect::<Vec<_>>())
.collect::<(Vec<_>, Vec<_>)>();
Ok((images, headers))
};
let images = match gz {
let (images, headers) = match gz {
fitsrs::gz::GzReader::GzReader(bytes) => parse_fits_images_from_bytes(bytes.get_ref())?,
fitsrs::gz::GzReader::Reader(bytes) => parse_fits_images_from_bytes(bytes.get_ref())?,
};
@@ -1267,12 +1272,13 @@ impl App {
if images.is_empty() {
Err(JsValue::from_str("no images have been parsed"))
} else {
let layer = ImageLayer {
images,
id: layer.clone(),
layer,
meta,
options,
};
let params = layer.get_params();
@@ -1284,7 +1290,14 @@ impl App {
)?;
self.request_redraw = true;
let promise = js_sys::Promise::resolve(&serde_wasm_bindgen::to_value(&params)?);
let obj: js_sys::Object = serde_wasm_bindgen::to_value(&params)?
.dyn_into()?;
use std::iter::FromIterator;
let arr = js_sys::Array::from_iter(headers.iter().map(|header| serde_wasm_bindgen::to_value(&header).unwrap()));
js_sys::Reflect::set(&obj, &"headers".into(), &arr).unwrap();
let promise = js_sys::Promise::resolve(&obj.into());
Ok(promise)
}
}
+5 -4
View File
@@ -103,8 +103,8 @@ pub struct ImageLayer {
pub layer: String,
pub id: String,
pub images: Vec<Image>,
/// Its color
pub meta: ImageMetadata,
/// Display options
pub options: ImageMetadata,
}
impl ImageLayer {
@@ -464,7 +464,8 @@ impl Layers {
layer,
id,
images,
meta,
options,
..
} = image;
// 1. Add the layer name
@@ -479,7 +480,7 @@ impl Layers {
self.layers.insert(idx, layer.to_string());
// 2. Add the meta information of the layer
self.meta.insert(layer.clone(), meta);
self.meta.insert(layer.clone(), options);
// 3. Add the fits image
// The layer does not already exist
+16 -8
View File
@@ -48,6 +48,11 @@ export class SAMPConnector {
let callHandler = cc.callHandler;
this.cc = cc;
let isLocalhost = (url) => {
const { hostname } = new URL(url);
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1";
};
let self = this;
// listen for hub deconnexion/shutdown and unregister if so
callHandler["samp.hub.event.shutdown"] = function(senderId, message, isCall) {
@@ -91,13 +96,12 @@ export class SAMPConnector {
let params = message["samp.params"];
let id = params['table-id'];
let url = params['url'];
let origUrl = params['url'];
let finalUrl = isLocalhost(origUrl) ? cc.connection.translateUrl(origUrl) : origUrl;
let name = params['name'] || id;
console.log(id, url, name)
A.catalogFromURL(
url,
finalUrl,
{name, onClick: 'showTable'},
// Add the catalog if the query has succeded
(catalog) => {
@@ -120,11 +124,13 @@ export class SAMPConnector {
let params = message["samp.params"];
let id = params['table-id'];
let url = params['url'];
let origUrl = params['url'];
let finalUrl = isLocalhost(origUrl) ? cc.connection.translateUrl(origUrl) : origUrl;
let rowList = params['row-list'];
// search for the catalog
let catalog = selectCatalog(id, url)
let catalog = selectCatalog(id, finalUrl)
if (catalog) {
let objects = [];
@@ -140,11 +146,13 @@ export class SAMPConnector {
let params = message["samp.params"];
let id = params['table-id'];
let url = params['url'];
let origUrl = params['url'];
let finalUrl = isLocalhost(origUrl) ? cc.connection.translateUrl(origUrl) : origUrl;
let row = params['row'];
// search for the catalog
let catalog = selectCatalog(id, url)
let catalog = selectCatalog(id, finalUrl)
if (catalog) {
const source = catalog.sources[row];