Skip to content

npm: version lookup returns 502 - #419

Merged
andrew merged 6 commits into
git-pkgs:mainfrom
kokes:kokes/npm-version-lookup-502
Oct 12, 2026
Merged

andrew merged 6 commits into
git-pkgs:mainfrom
kokes:kokes/npm-version-lookup-502

Conversation

@kokes

@kokes kokes commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Looking up a version (latest or e.g. 4.18.1) returns a 502, because it mistreats the slash in lodash/latest as a namespace separator and escapes it.

$ curl -i http://localhost:8080/npm/lodash/latest
HTTP/1.1 502 Bad Gateway
Content-Type: application/json
X-Request-Id: mbp.local/Z9um7GRQhM-000001
Date: Thu, 08 Oct 2026 11:09:00 GMT
Content-Length: 41

{"error":"failed to fetch from upstream"}

With this PR in place:

$ curl -i http://localhost:8080/npm/lodash/latest
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: mbp.local/OOnSt03Chy-000001
Date: Thu, 08 Oct 2026 11:10:06 GMT
Content-Length: 1668

{"bugs":{"url":"https://github.com/lodash/lodash/issues"},"dist":{"shasum":"ff2b66c1f6326d59513de2407bf881439812771c","tarball":"http://localhost:8080/npm/lodash/-/lodash-4.18.1.tgz","fileCount":1051,"integrity":"sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==","signatures":[{"sig":"MEUCIQDZo+W4JJ5T/9RkS8Wz1uN7Gw+CBvP16yGeT8H9lnb+sAIgKM5Nqj636zyRL2YOUuhbSK2e1DhK2VBaMXiVNIYMq1M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1413741},"icon":"https://lodash.com/icon.svg","main":"lodash.js","name":"lodash","author":{"name":"John-David Dalton","email":"john.david.dalton@gmail.com"},"gitHead":"4f0b76e2eca13de1c1fe8b4305abc1f7d63f4b86","license":"MIT","scripts":{"test":"echo \"See https://travis-ci.org/lodash-archive/lodash-cli for testing details.\""},"_npmUser":{"name":"jdalton","email":"john.david.dalton@gmail.com"},"homepage":"https://lodash.com/","keywords":["modules","stdlib","util"],"repository":{"url":"git+https://github.com/lodash/lodash.git","type":"git"},"_npmVersion":"10.9.4","description":"Lodash modular utilities.","directories":{},"maintainers":[{"name":"mathias","email":"mathias@qiwi.be"},{"name":"jdalton","email":"john.david.dalton@gmail.com"},{"name":"bnjmnt4n","email":"benjamin@dev.ofcr.se"}],"_nodeVersion":"22.21.1","contributors":[{"name":"John-David Dalton","email":"john.david.dalton@gmail.com"},{"name":"Mathias Bynens","email":"mathias@qiwi.be"}],"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/lodash_4.18.1_1775077280191_0.6534118914634555","host":"s3://npm-registry-packages-npm-production"},"_id":"lodash@4.18.1","version":"4.18.1"}

Looking up a specific version will trigger a 502 instead of return the version metadata.
@kokes
kokes marked this pull request as draft October 8, 2026 11:11
@kokes
kokes marked this pull request as ready for review October 8, 2026 11:17

@andrew andrew left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new version lookup path needs to apply cooldown consistently with package metadata and tarball downloads.

Comment thread internal/handler/npm.go
}
var out bytes.Buffer
h.writeNPMVersion(&out, packageName, version, body)
return out.Bytes(), nil

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This single-version response returns before cooldown filtering. I reproduced it through Routes() with a seven-day cooldown and a version published one hour ago: /demo hides 2.0.0 and sets latest to 1.0.0, but /demo/latest and /demo/2.0.0 both return HTTP 200 with 2.0.0. Following its rewritten tarball URL then returns 404 because the download path enforces cooldown. Apply cooldown to explicit version lookups and resolve tags consistently with the filtered package metadata, with handler-level regression tests.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, my bad. Tested it with default cooldown set to 7d and looked up @babel/core 8.0.7 (published five days ago). 8.0.6 works just fine, so does latest (returns 8.0.6)

$ curl -sS 'http://localhost:8080/npm/https://github.com/babel%2Fcore/8.0.7' | jq
{
  "error": "package not found"
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, "package not found" is rather misleading here - the package is found, just the version falls under the cooldown policy. Let me reword that.

Also, npm itself has a different copy for non-existent versions (the cooldown-masked version is similar to a non-existent one)

$ curl -s https://registry.npmjs.org/@babel%2Fcore/8.0.8
"version not found: 8.0.8"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, addressed the copy in the latest commit.

kokes added 4 commits October 12, 2026 14:08
tested (set default cooldown to 7d and 8.0.7 is released four days ago or something):

```
$ curl -sS 'http://localhost:8080/npm/@babel%2Fcore/8.0.7' | jq
{
  "error": "package not found"
}
```

@andrew andrew left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cooldown issue from #419 (comment) is resolved. Version and tag lookups now use filtered package metadata, with HTTP regression coverage.

@andrew
andrew merged commit 6e334b4 into git-pkgs:main Oct 12, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants