Repository navigation
Allow users to configure forwarded headers? #916
Description
Activity
👍 I imagine most of the time, users might just want their own custom UA, so we should support: (edit: maybe that doesn't make sense actually? Either way, they could manipulate whatever part of the request they want:)
var gcloud = require('gcloud')({ decorateRequest: function(reqOpts) { reqOpts.headers['User-Agent'] = 'My App'; return reqOpts; } });
Then overriding per service should be pretty straightforward:
var dataset = gcloud.datastore.dataset({ decorateRequest: function(reqOpts) { reqOpts.headers['X-App-Id'] = 'app-whatever'; return reqOpts; } });
As far as allowing per-request control, like "got a request for resource X, attach a custom header while we download it then remove it after", maybe we can go even one level deeper:
var bucket = gcloud.storage.bucket('my-app-bucket'); var file = bucket.file('my-app-file', { decorateRequest: function(reqOpts) { reqOpts.headers['X-Requester-Id'] = 'user-ip'; return reqOpts; } });
All of these have the decorated request options, while any other service (Dataset) or object (Bucket, File, Topic, etc) wouldn't be touched.
// X-Requester-Id header in place file.createReadStream(); file.download(); // No X-Requester-Id header in place bucket.upload(); bucket.getMetadata();
Regarding the gist, I put together how this would look: https://gist.github.com/jgeewax/3b351d3522fdf061bdea
Another option:
// Global gcloud.decorateRequest(function(reqOpts) { // modify reqOpts return reqOpts; }); // Service var gcs = gcloud.storage(); gcs.decorateRequest(function(reqOpts) { // modify reqOpts return reqOpts; }); // Service object var bucket = gcs.bucket('my-bucket'); var file = bucket.file('my-file'); file.decorateRequest(function(reqOpts) { // modify reqOpts return reqOpts; });
Let's go with this:
var opts = { projectId: 'my-project-id' }; var storage = gcloud.storage(opts); // Need to set a custom header var newOpts = extend({}, opts, { decorateRequest: function(reqOpts) { reqOpts.headers['X-Cloud-Trace-Context'] = '...'; } }); var newStorage = gcloud.storage(newOpts); storage.getBuckets(); // no custom header sent newStorage.getBuckets(); // custom header sent
gcloudas well as any service object will accept thedecorateRequestfunction.Sound okay?
Reminds me of angular interceptors, a similar interface to that could be nice
var storage = gcloud.storage({ projectId: 'my-project-id' }); storage.interceptors.push({ request: function (reqOptions) { if (someCondition) { reqOptions.headers['X-Yay-Headers'] = 'woot'; } return reqOptions; } });
And as a side note, with the upcoming switch to promises this could potentially provide a nice interface for failed request logic, assuming we followed angular's api.
Looks cool to me. 👍
- added 8 commits that reference this issue
on Jan 27, 2026
The Cloud Trace team wants to make it easy for users to send trace IDs along with various API calls, effectively just adding a special header (
X-Cloud-Trace-Context) with an opaque ID.The issue is that this ID will vary across requests, which presents a bit of an issue in that whole concurrency thing...
For example, here's how I'd want to do this in my app: https://gist.github.com/jgeewax/3b351d3522fdf061bdea
Note that I have zero idea if this is at all reasonable given the isolation model for Node. (I think, for example, that this won't work for Express, and that we should be doing something with
req.locals....? see http://stackoverflow.com/questions/33310324/using-express-middleware-for-per-request-module-configuration)Anyway -- we need to find a way to allow users to...
setTraceContextin my example might do...)