transformRequest headers ignored for Model resources
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 84/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
Research direction
Start with loadGLTFFromURI in dist/mapbox-gl-dev.js around line 53548 and loadGLTF around line 38356, then compare the image-loading path that passes the full request object. Verify that model requests preserve headers returned by transformRequest, and reproduce the authenticated request to confirm the Authorization header is sent.
Written by the indexing model from the issue text.
Description
mapbox-gl-js version
v3.29.0
Browser and version
All browsers (Chrome, Firefox, Safari) - tested on Chrome 151.0.7922.175
Expected behavior
The transformRequest callback should apply custom headers to Model (GLTF/GLB) resource requests, just like it does for all other resource types (tiles, images, sprites, glyphs, etc.).
When a user returns headers from transformRequest for a Model resource, those headers should be included in the HTTP request.
Actual behavior
The transformRequest callback IS called for Model resources, but the returned headers are completely ignored. Only the URL is used, and the request is made without any custom headers.
This is inconsistent with how all other resource types behave, where headers are correctly applied.
Link to the demonstration
N/A - Bug is in library internals (loadGLTF function). Code analysis and reproduction steps provided below.
Steps to trigger the unexpected behavior
- Create a map with a transformRequest callback that adds authentication headers:
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/standard',
transformRequest: (url, resourceType) => {
console.log('Transform request:', resourceType, url);
if (resourceType === 'Model') {
return {
url: url,
headers: { 'Authorization': 'Bearer my-secret-token' }
};
}
return { url };
}
});
- Add a model layer that loads from a server requiring authentication:
map.on('style.load', () => {
map.addSource('my-model', {
type: 'model',
models: {
'my-model-id': 'https://my-server.com/model.glb'
}
});
map.addLayer({
id: 'model-layer',
type: 'model',
source: 'my-model',
paint: { 'model-id': 'my-model-id' }
});
});
- Check the network request in DevTools - the Authorization header will be missing despite being returned from transformRequest
Root Cause
Bug is in loadGLTFFromURI (line ~53548 in dist/mapbox-gl-dev.js):
async loadGLTFFromURI(uri, signal) {
const request = await this.map._requestManager.transformRequest(uri, ResourceType.Model, signal);
return loadGLTF(request.url, signal); // Only passes URL, discards headers
}
And loadGLTF (line ~38356):
async function loadGLTF(url, signal) {
const { data: buffer } = await getArrayBuffer({ url }, signal); // Creates new object with only URL
return decodeGLTF(buffer, 0, url, signal);
}
Compare with correct implementation for Images:
const request = await this._requestManager.transformRequest(url, ResourceType.Image);
const { data } = await getImage(request); // Passes full request object with headers
Proposed Fix
async loadGLTFFromURI(uri, signal) {
const request = await this.map._requestManager.transformRequest(uri, ResourceType.Model, signal);
return loadGLTF(request, signal); // Pass full request object
}
async function loadGLTF(requestParameters, signal) {
const { data: buffer } = await getArrayBuffer(requestParameters, signal); // Use full request
return decodeGLTF(buffer, 0, requestParameters.url, signal);
}
Relevant log output
Console output shows transformRequest is called:
Transform request: Model https://my-server.com/model.glb
Network tab in DevTools shows the request is made WITHOUT the Authorization header:
Request URL: https://my-server.com/model.glb
Request Method: GET
Status: 401 Unauthorized (if server requires auth)
Expected header is missing:
Authorization: Bearer my-secret-token
- Dominant language
- TypeScript
- Stars
- 12.4k
- Forks
- 2.4k
- PR merge metrics
- No merged PRs in 30d
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from mapbox/mapbox-gl-js
-
auto-triaged bug :lady_beetle:
Difficulty 1/5 Under an hour Newbie friendliness 86/100
mapbox/mapbox-gl-js#13717 ·
-
auto-triaged bug :lady_beetle:
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
mapbox/mapbox-gl-js#13714 ·
-
auto-triaged feature :green_apple:
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
mapbox/mapbox-gl-js#13676 · 2 comments ·
-
auto-triaged bug :lady_beetle:
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
mapbox/mapbox-gl-js#13639 · 1 reaction ·
-
docs :scroll:
Difficulty 1/5 Under an hour Newbie friendliness 68/100
mapbox/mapbox-gl-js#13523 ·
All issues in mapbox/mapbox-gl-js
Similar issues
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 91/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 95/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Automattic/studio#4908 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100