electron: net.request response is missing content-type header in 304 responses
Preflight Checklist
- [x ] I have read the Contributing Guidelines for this project.
- [ x] I agree to follow the Code of Conduct that this project adheres to.
- [ x] I have searched the issue tracker for an issue that matches the one I want to file, without success.
Issue Details
- Electron Version: 10.1.7
- Operating System: Windows 10 Enterprise 1909
When making a request with net.request, I can see that my response has a content-type header of application/json; charset=utf-8 inside of my webRequest.onHeadersReceived handler:
electron.session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
// details.responseHeaders['content-type'] === 'application/json; charset=utf-8'
});
But by the time the net.request request.on('response') handler receives the headers, the content-type is gone.
request.on('response', (response) => {
/*
response.headers === {
// no content-type
};
*/
});
I haven’t tested if this is an issue in all types of responses, but I can tell you this is occurring without fail for the case when the response.statusCode === 200, but the response.headers.status === 304.
Expected Behavior
For net.request response handler to receive the content-type that clearly should exist on the response (proved by webRequest.onHeadersReceived).
Actual Behavior
net.request response handler is receiving what seems to be a cached set of headers (or something?), which do not match what is seen in webRequest.onHeadersReceived.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 8
- Comments: 19 (6 by maintainers)
This is still an issue in 18.2.2 (and 19.0.0-beta.5). Any news or plans to fix this?
This looks like a regression caused by https://github.com/electron/electron/pull/21552. As an experiment, I tried adding the non-“raw” headers to the internal response object:
(NB. above patch is hacky and doesn’t allow for repeated headers, it was just enough to let me see whether this theory about raw headers was correct.)
The
headersobject contained the correctcontent-typeandcontent-length, even when therawHeadersdidn’t. For example:As further confirmation, the above PR was backported to 7.x in v7.1.10. When I run the fiddle on v7.1.9, it works as expected.
cc @zcbenz
Here is a standalone testcase :
https://gist.github.com/arantes555/99f8976266d340bad42b2894cb50d7d5
This shows that when the server responds with a 200,
responsecorrectly containscontent-typeandcontent-length. But when the server responds with a 304,responseis shown to be a 200 but does not containcontent-typeandcontent-length.I also showed the behaviour of
onHeadersReceivedthat @themadtitanmathos noticed : on this callback, headers are correct.Also, with electron@6, everything is correct.
bump
Any news ? PS:
detailsalso does not return the list of headers that are supposed to be used by the request. This seems to be a precedence error.onBeforeSendHeadersshould be triggered after the “default” headers have been populated.we never got to the point of setting up our own server to test, but testing against GitHub and GitLab APIs, we only got a repro while we had something in the cache. For whatever reason, when we manually set our own
If-None-Matchthat would prompt a 304 from the server, we got back an unmolested 304 (i.e. 304 status code, no body). We came to the conclusion that it was because of a bad interaction with the Electron and/or Chrome request caches. I’m confident that if you cleared both caches and ran the 304 first, you would get back thecontent-typeandcontent-lengthas expected. In other words, I believe it’s some problematic way that the cache results are being “merged” into the final results that causes the headers to drop. The same mechanism is probably also preventing theonHeadersReceivedcallback from working (#27894) by overriding the results after the callback occurs.I just hit the same problem : electron does not repopulate
content-typeandcontent-lengthwhen a 304 is “transformed” in 200 from the cache.Also, I can confirm that the behaviour was different on electron <= 6 : up to electron6, the 200 seen in this case correctly has
content-typeandcontent-length.No repro example yet, but just to add some details we’ve found since:
netseems to be adding thestatusheader on its own. We’ve mostly (but not exclusively) been testing against GitHub’s REST API, and we’ve confirmed through Postman that the servers we’ve hit don’t include thestatusheader, but it consistently comes back304on many requests, unless we obliterate theElectron/Cachefolder from the user data. So far it seems like we’re getting back legitimate 200s and net is arbitrarily addingstatus: 304and deleting thecontent-typeheader (and removing custom headers, #27894 which may be the same issue). When we force GitHub to give us a 304 by including an ETag inIf-None-Match,net.requestgives us back a completely normal-looking 304 with no body. Basically we’re just really perplexed by the inconsistent and arbitrary way thatnetsort-of-does-sort-of-doesn’t transparently populate 304 results from the Electron cache, or just decides not to even attempt such a population at all. We haven’t been able to find any existing issues or documentation that speak to its intended behavior.