Open LINKIWI opened 7 years ago
Thanks for the thorough report! Would you like to give a patch a shot? I'm not sure what the exact right place to fix this is, either. It's interesting that this only happens when you're dealing with cached stuff, which makes me suspect you're right -- otherwise, my prime suspect would be node-fetch-npm
.
Your suggestion about catching things seems reasonable, though TypeError
without any further checks feels a bit heavy-handed for this sort of task?
Anyway, give it a whirl, and thank you again!
Hm, I agree that blind-catching a TypeError
feels heavy handed, but the logic path invoked by req.headers.get
is quite short and the scope for the try-catch seems limited. I think this is a reasonable solution. I'll give this patch a try and see what I can come up with. Thanks for your input!
@LINKIWI I'm more wondering why the heck Headers
even errors on a read. It's just plain weird to me?
@zkat Just a heads up - I've opened npm/node-fetch-npm#7 to address this, whenever you get a chance to take a look
This issue was originally opened against
npm/npm
at https://github.com/npm/npm/issues/18208 but I believe the scope of the problem applies only tomake-fetch-happen
, so I am moving it here.Core problem The
npm
v5 client fails on cached installs if the original response (which was stored in the cache) contains a malformed HTTPVary
header.Symptom Installations for any package will reliably fail on subsequent installs after its tarball response has been cached locally by
npm
on the first install.Root cause flow
registry.npmjs.org
, but a self-hosted one; in this case, a Sinopia instance behind an Apache reverse proxyVary: Accept-Encoding,User-Agent)
in the response for a request for a package tarballnpm
client successfully installs this package and places it in the local cachemake-fetch-happen
ensures that each of the cached header values specified byVary
matches that in the request payload before attempting to use the cached response. This behavior is correct and in accordance with HTTP spec.node-fetch-npm
throws because one of the comma-delimited header names,User-Agent)
, is malformed and invalid.npm
client aborts installation with the error propagated to the highest level with the stack trace seen above.Reproduction steps Since this error surfaces only because of a self-hosted npm registry, the easiest way to reproduce this is to insert a proxy between the
npm
client and any registry (e.g.registry.npmjs.org
) and forcefully inject/modify a malformed response header.Vary
header to beVary: Accept-Encoding,User-Agent)
npm cache clean --force
npm --proxy=http://localhost:<proxy port> install express
- no errors!npm --proxy=http://localhost:<proxy port> install express
a second time -error User-Agent) is not a legal HTTP header name
and exit nonzero."This is not a problem with
npm
, but a problem with your server" Yes, I agree. Some unfortunate combination of my Apache version, Sinopia version, and various configuration files causes Apache to respond with a malformed response header.However, it is still my opinion that the
npm
client should handle this condition gracefully, and not forcefully exit 1.I would love to contribute to
npm
to fix this bug, but would appreciate guidance as to which level this fix should be performed. My opinion is that https://github.com/zkat/make-fetch-happen/blob/800a8e54581e1b84e53e42a274c1eea7f8c652b6/cache.js#L229 should safelyreq.headers.get
- e.g. catching the possibleTypeError
and skipping the malformed header.