-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added hook to address 400 error returned during redirect #329
Conversation
During tarball resolution, some redirects would return 400 error if authentication headers are present. These hooks will intercept a 400 error and remove the authorization header.
Thanks for that! 😀 I'll look at the code later this week end, but in the meantime I just wanted to say that I think we should remove the authorization header for all redirects. It seems to match the behavior of the |
I will change it later. That will simplify it a lot. |
Pulling commits from original repository.
Nevermind, I just did a quick hack. Removed the |
Awesome, thanks 😃 |
I just noticed that the |
Errata, I've submitted #334 to fix this 🙂 |
During tarball resolution, some npm registries will redirect to the actual file location. In my case, using Azure Artifact feeds, that redirect will return a 400 error if authentication headers are present. See #316.
Since
got
follows redirects automatically, I thought it would be best to hook into their process to update headers. Since I can't be certain that redirects made by all npm registries will have the same requirements for noAuthorization:
header, this will wait until a 400 error is returned, after a redirect. Then the request will be retried, and the authentication header removed.Because this is forcing request retries, it has the potential to slow down the package fetching. So, I also added a redirect cache. It makes the assumption that once the original host returns a redirect, and that redirect returns 400, all redirects from that host will return the same. Thereafter, any redirect by that host will follow the same rules (i.e. remove the authentication headers). The other option would have been to cache by the redirected host, but that would not have been as effective, because (in my case), those redirected URLs were always different.
For example,
pkgs.dev.azure.com
would return1yovsblobprodeus2184.blob.core.windows.net
for one package, andpuxvsblobprodeus216.blob.core.windows.net
for another. This means the cache would be ineffectual, and every single request made topkgs.dev.azure.com
would need to be retried a minimum of one time. Therefore, the host cached will bepkgs.dev.azure.com
.Since these calls are made async, there might be one or two packages that have to retry their request once, because the cache hasn't yet been populated with that host. However, once it has been populated, the original request does not fail, because the
beforeRedirect()
hook is processed correctly. This was apparent during debugging, where sometimes both theafterResponse()
hook with a 400 error and thebeforeRedirect()
was hit for two packages; and sometimesafterResponse()
was only hit once, and every request afterwards would only hit thebeforeRedirect()
, and return successfully.One thing I noticed is that
got
does not play nicely with the currentBody
interface. It is unable to infer the type of request, because theBody
interface contains anull
option, and also because of the dynamic key index. It looks like it would take more work here, and/or on thegot
side to make that work. So I just went with the established convention of forcing typescript ignore the type errors. Which is where all the//@ts-ignore
's came from 😆. Honestly, I hate doing that, but I also didn't want to exceed the scope of this issue.