http: add setDefaultHeaders option to http.request #56112
+100
−2
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When sending an HTTP request, for some use cases you want full control of the request headers: controlling the raw format directly and setting only the headers provided, with no other headers automatically included whatsoever.
That is not currently possible, because:
req.removeHeader
for each of them individually on a request instance, before the headers are sent. Otherwise these are set automatically, even if you pass a raw header array.http.request()
method, and when you do so the headers are passed to_storeHeader
and serialized into_header
immediately, meaning you can't callremoveHeader
afterwards.That means these two use cases (removing default headers & setting raw header formats) are mutually exclusive, which isn't great since they're closely related.
This PR fixes that by adding a
setDefaultHeaders
option tohttp.request
, defaulting totrue
. If you passsetDefaultHeaders: false
then you take responsibility for providing all required headers and Node gets out of the way and gives you full control.With this, you can now control all headers, in raw format, with:
Alternative ideas I've avoided, but might be interesting:
setContentLength
,setTransferEncoding
etc parameters, analogous to the existingsetHost
option. Results in too many options, and I think in the case where this is necessary you almost always want to control all headers. In fact, I think if this PR is merged we could consider deprecatingsetHost
entirely, and suggesting users migrate to this option instead (I expect mostsetHost: false
cases will want this too) but I haven't looked into that for now, we can wait and see how this is used instead.setHeaders
to allow setting raw headers after initial request construction, to handle this use case with justremoveHeader
+setHeaders
calls. This would require that eithersetHeaders
immediately serialize the raw headers to_headers
in this case (blocking any further changes like an implicit flushHeaders, but only in the raw header argument case, with potentially weird differences between setHeaders behaviour for requests vs responses), or some fairly major refactoring to change all internal HTTP header representation to support incrementally adding raw headers (all current raw header APIs -writeHead
andhttp.request
- always serialize & fix the headers immediately). The former is quite an awkward API, the latter is messy and risky, and I'd rather not.request.writeHeaders
method analogous toresponse.writeHead
. This works, but it's yet another headers API with subtly different behaviour that would really only exist for this one use case.http.request
- this seems sensible to me as an API, but it's a huge breaking change that isn't really practical imo.