Skip to content

npm: decouple upstream Accept header choice from cooldown configuration #228

Description

@pgarbe

Summary

When cooldown is not configured (the default), the npm handler requests upstream metadata with Accept: application/vnd.npm.install-v1+json (abbreviated packuments). Some upstream registries — specifically JFrog Artifactory npm virtual repositories — return 406 Not Acceptable for this content type. The proxy then logs "failed to fetch npm metadata" error="upstream returned 406" and returns 502 to the client.

The only way to force Accept: application/json (which Artifactory accepts) is to enable cooldown, because the Accept header choice is hardwired to Cooldown.Enabled() in internal/handler/npm.go:

accept := npmAbbreviatedCT
if h.proxy.Cooldown != nil && h.proxy.Cooldown.Enabled() {
    accept = contentTypeJSON
}

Reproduction

  1. Deploy the proxy with the default config (no cooldown block)
  2. Point the upstream at a JFrog Artifactory npm virtual repository
  3. Request any package metadata: curl https://<proxy>/npm/lodash
  4. Proxy logs "failed to fetch npm metadata" error="upstream returned 406", client receives 502

Current workaround
Setting cooldown.default: "1s" enables Cooldown.Enabled() → forces application/json → Artifactory responds correctly. The 1s duration has no practical effect on version filtering since all published versions are older than 1 second.

Proposed fix

Add a dedicated config option to control the npm Accept header independently of cooldown, e.g.:

npm:
  full_metadata: true   # always use application/json, regardless of cooldown

Or invert the logic: always request application/json from upstream (Artifactory and the public npm registry both support it), and only switch to abbreviated when explicitly opted in. The abbreviated format's main benefit is size — but given the proxy already buffers and caches metadata, the savings may not justify the compatibility cost.

Environment

git-pkgs/proxy v0.6.0
Upstream: JFrog Artifactory npm virtual repository (/artifactory/api/npm//)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions