Issues with current state of WebRequest.CustomRequestHeaders / CustomRequestModifiers

With the current state of the CustomRequestHeaders/CustomRequestModifieres we are running into issues with our Web application once it needs to load data from external sources.

The application loads models and textures from an rest api endpoint within the same base url (though it is routed to another container that actually hosts the rest api)
This endpoint requires correct Authorization tokens sent alongside the requests.

So far we achive this by using the WebRequest.CustomRequestHeaders.
This works for models but not for textures, as textures are loaded internally from babylon by creating an image element and setting the url property. We currently work around this by wrapping the Tools.LoadImage method to manually inject the authorization header.

When we started to play around with WebXR which dynamically loads controller definitions and models from and controllers.babylonjs… url’s we got hit by CORS errors.
This was the result of our code leaking the tokens to the “outside world”.

One thought was inejcting the Authorization headers with CustomRequestModifiers. However they are called before the underlying XMLHttpRequest is open which will result in a similar crash back when CustomRequestHeaders were injected to early. (#6055).

As a temporary workaround we removed the Authorization headers from CustomRequestHeaders and inject them inside CustomRequestModifiers by inside an eventlistener to ready state open only if the request goes to our rest endpoint.

The same crash might occur if one constructs a new WebRequest object and calls the recently added setRequestHeader method before the WebRequest is actually open.

I would like to get some feedback on what side effects this might cause moving down the CustomRequestModifiers handling from to WebRequest.send right after CustomRequestHeaders have been injected.

Or would it even make sense to provide OnBeforeOpen, OnBeforeSend observers as a convenient way to do some work on the underlying XMLHttpRequest ? This might go along with some refacturing i.e. renaming CustomRequestModifiers and/or removing CustomRequestHeaders since the CustomRequestModifiers could be used to achieve the same goal.

While digging deeper into the refacturing hole another option would be to derrive from XMLHttpRequest itself saving quite a few lines of code. Taking it would be usable by all supported browsers.

And even further in… The long run would it make sense to shift towards the fetch API in order to benefit from Promises and flat awaitable async functions? Though this is probably long down the road.

Yes as we need to support all browsers (including IE). So moving to fetch will force us to write a polyfill (not impossible thought).

To your question, can you repro in the PG the issues you are facing. This seems a bit unclear to me

Or is there no question and you would like to offer an improvement to the way we do CustormRequestModifier?

1 Like

here is a PlayGround demonstrating the WebRequest issues.
load the playground and check the output on the javascript console.

I hope the comments somewhat explain on what we are doing.

I used BABYLON.Tools.LoadFileAsync but the issue would arrise with any method in BabylonJS that uses the WebRequest class. i.e. loading meshes.

so the short term question would be.

Can you see any negative side effects moving CustomRequestModifiers down to the send method of WebRequest instead of open(). right after the CustomRequestHeaders have been injected. as a short term change.

I just didn’t want to go ahead and drop a PR without getting more feedback/information on possible issues this might bring up.

Since all ‘internal’ loading goes through the web/rest service the authorization header is mandatory as it decides what models will be loaded for what user group as well other access rights to parts of the application.

The issues started when we did some experiments with the WebXR classes from BabylonJS as they are some kind of “blackboxes” loading models of their own just from external url’s.

For WebXR, let me add @RaananW but I think you can control where the models (for the controllers) are loaded from.

We are now closing 4.1 but maybe we can start with a PR to see what you want to change and so we can discuss on the PR itself

Yes, WebXR is using a repository for the controllers, that can be changed according to your needs. You can also decide not to load the models (or load your own) if it makes more sense to you.

We support the official WebXR assets repository (webxr-input-profiles/ at master · immersive-web/webxr-input-profiles · GitHub) , which you can deploy on your own server. When you have the base URL of this npm package, change it in the WebXRMotionControllerManager:

const baseUrl = "";
WebXRMotionControllerManager.BaseRepositoryUrl = baseUrl;

baseUrl + “/profiles” should have the profielsList.json file.

Make sure you change the base URL prior to initializing XR, otherwise the profiles list will be loaded from the base repository.
If you cange it afterwars, call the static WebXRMotionCOntrollerManager.UpdateProfilesList(), which returns a promise. when the promise is done, the new repository has initialized. This is done when initializing XR so in general you won’t have to do it yourself.

Afterwards, the motion controller manager (and the WebXRProfiledMotionController) are using SceneLoader.ImportMesh to load the controller mesh(es).

1 Like