chudnyi
59a43c8733
fix(packages/npm): use PathEscape for package name in tarball URL ( #39061 )
...
## Summary
Replace `url.QueryEscape` with `url.PathEscape` when building
`dist.tarball` in the npm package registry. `QueryEscape` leaves `@`
unescaped, producing `dist.tarball` URLs like `@scope%2Fname` for scoped
packages — which npm clients cannot resolve. `PathEscape` produces the
RFC 3986 path-segment-safe encoding (`%40scope%2Fname`) that the npm
registry URL format requires.
## Reproduction
1. Publish a scoped npm package (`@scope/name@1.0.0`) to a Gitea package
registry.
2. Inspect the `dist.tarball` field in the metadata response.
3. Observe that the package name in the URL is `@scope%2Fname` instead
of `%40scope%2Fname`.
4. `npm install @scope/name` fails because npm rejects the malformed
tarball URL.
## Fix
One-line change in `routers/api/packages/npm/api.go`:
```diff
-Tarball: fmt.Sprintf("%s/%s/-/%s/%s", registryURL, url.QueryEscape(pd.Package.Name), url.PathEscape(pd.Version.Version), url.PathEscape(pd.Files[0].File.LowerName)),
+Tarball: fmt.Sprintf("%s/%s/-/%s/%s", registryURL, url.PathEscape(pd.Package.Name), url.PathEscape(pd.Version.Version), url.PathEscape(pd.Files[0].File.LowerName)),
```
## Tests
- `routers/api/packages/npm/api_test.go`: extended
`TestCreatePackageMetadataResponse` to use `Package.Name: "@scope/test"`
and added an `assert.Equal` on `Dist.Tarball` (per review feedback to
consolidate the test instead of adding a new one).
- `tests/integration/api_packages_npm_test.go`: switched three
`url.QueryEscape(packageName)` to `url.PathEscape(packageName)` to match
the new production encoding (lines 125, 126, 446). The `TestPackageNpm`
assert at line 219 against `pmv.Dist.Tarball` now passes for scoped
packages.
The unit test fails on `main` (excluding the `QueryEscape` →
`PathEscape` swap) and passes with the fix.
## Related
Closes #39060 .
## Disclosure
This contribution was prepared with assistance from an AI coding
assistant (limited to language polishing in maintainer-facing messages).
The contributor reviewed and validated all changes, including the test
cases.
---------
Signed-off-by: Dmitriy Chudnyi <dmitriy@chudnyi.com >
Signed-off-by: wxiaoguang <wxiaoguang@gmail.com >
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com >
2026-08-24 18:00:44 +00:00
..
2026-04-23 15:18:53 +00:00
2026-07-20 03:42:02 +00:00
2026-06-08 20:07:15 +00:00
2026-08-07 20:56:40 -07:00
2026-06-27 17:56:12 +00:00
2026-08-07 20:56:40 -07:00
2026-08-07 20:56:40 -07:00
2026-05-26 15:49:31 -07:00
2026-08-24 07:28:17 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-07 20:56:40 -07:00
2026-08-07 20:56:40 -07:00
2026-08-07 20:56:40 -07:00
2026-08-12 19:03:44 +02:00
2026-08-07 20:56:40 -07:00
2026-07-15 02:36:03 +00:00
2026-07-25 21:31:19 +00:00
2026-08-07 20:56:40 -07:00
2026-07-27 17:45:27 +00:00
2026-08-07 20:56:40 -07:00
2026-05-26 15:49:31 -07:00
2026-08-13 09:36:41 +02:00
2026-05-26 15:49:31 -07:00
2026-06-27 12:09:01 +00:00
2026-08-14 22:23:30 +08:00
2026-08-12 19:55:26 +00:00
2026-08-22 18:47:55 +00:00
2026-05-26 15:49:31 -07:00
2026-08-07 20:56:40 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-22 09:29:25 +02:00
2026-08-22 21:32:59 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-06-10 17:34:10 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-09 10:25:06 +00:00
2026-05-26 15:49:31 -07:00
2026-08-17 20:30:24 +00:00
2026-07-25 20:39:36 +08:00
2026-07-12 17:14:09 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-17 20:30:24 +00:00
2026-06-09 06:12:09 +00:00
2026-07-12 17:14:09 +00:00
2026-08-20 15:57:17 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-06-17 06:39:22 +00:00
2026-08-23 07:23:16 +00:00
2026-07-16 11:51:36 +02:00
2026-05-26 15:49:31 -07:00
2026-07-28 17:04:22 +00:00
2026-05-26 15:49:31 -07:00
2026-08-24 07:28:17 +00:00
2026-08-09 10:25:06 +00:00
2026-05-26 15:49:31 -07:00
2026-08-09 10:25:06 +00:00
2026-05-26 15:49:31 -07:00
2026-08-17 17:43:34 +00:00
2026-07-12 17:14:09 +00:00
2026-05-26 15:49:31 -07:00
2026-08-09 12:55:43 +00:00
2026-08-09 10:25:06 +00:00
2026-08-24 18:00:44 +00:00
2026-08-24 07:28:17 +00:00
2026-08-07 11:49:23 +00:00
2026-08-09 10:25:06 +00:00
2026-08-24 07:28:17 +00:00
2026-08-24 07:28:17 +00:00
2026-08-09 10:25:06 +00:00
2026-05-26 15:49:31 -07:00
2026-08-17 20:30:24 +00:00
2026-08-24 07:28:17 +00:00
2026-08-20 15:57:17 +00:00
2026-08-17 20:30:24 +00:00
2026-07-12 17:14:09 +00:00
2026-05-26 15:49:31 -07:00
2026-08-09 10:25:06 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-24 07:28:17 +00:00
2026-05-26 15:49:31 -07:00
2026-06-17 06:39:22 +00:00
2026-06-03 16:21:48 -07:00
2026-05-26 15:49:31 -07:00
2026-08-21 07:06:56 +00:00
2026-07-20 16:07:38 +00:00
2026-08-03 06:41:27 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-03 06:41:27 +00:00
2026-08-20 15:57:17 +00:00
2026-07-28 17:04:22 +00:00
2026-08-03 06:41:27 +00:00
2026-08-03 06:41:27 +00:00
2026-05-26 15:49:31 -07:00
2026-08-05 17:19:31 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-07-28 17:04:22 +00:00
2026-05-26 15:49:31 -07:00
2026-07-12 17:14:09 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-07-31 11:05:41 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-23 06:35:55 +00:00
2026-06-09 06:12:09 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-21 07:28:23 +00:00
2026-05-26 15:49:31 -07:00
2026-08-23 06:35:55 +00:00
2026-05-26 15:49:31 -07:00
2026-06-14 20:05:18 +02:00
2026-07-12 17:14:09 +00:00
2026-06-17 16:06:51 +00:00
2026-06-17 06:39:22 +00:00
2026-05-26 15:49:31 -07:00
2026-07-12 17:14:09 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-06-08 16:58:42 +08:00
2026-08-22 23:11:04 -07:00
2026-05-26 15:49:31 -07:00
2026-07-16 17:38:33 +00:00
2026-05-26 15:49:31 -07:00
2026-07-10 19:30:43 +02:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-22 08:08:36 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-24 17:32:23 +00:00
2026-08-14 02:15:33 +00:00
2026-08-09 10:25:06 +00:00
2023-06-29 23:22:55 +00:00
2026-07-08 00:16:32 +00:00
2026-07-20 16:07:38 +00:00
2026-06-29 15:10:47 +00:00
2026-07-28 17:04:22 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-06-18 12:02:11 +00:00
2026-05-26 15:49:31 -07:00
2026-05-29 01:12:11 +00:00
2026-07-28 17:04:22 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-06-17 06:50:25 +02:00
2026-07-12 17:14:09 +00:00
2026-07-28 17:04:22 +00:00
2026-07-20 16:07:38 +00:00
2026-05-26 15:49:31 -07:00
2026-07-28 17:04:22 +00:00
2026-08-22 11:04:35 +00:00
2026-06-13 12:02:02 +08:00
2026-05-26 15:49:31 -07:00
2026-07-12 17:14:09 +00:00
2026-07-16 21:38:39 +00:00
2026-05-26 15:49:31 -07:00
2026-06-18 12:02:11 +00:00
2026-08-09 10:25:06 +00:00
2026-07-23 14:31:29 +00:00
2026-07-12 17:14:09 +00:00
2026-08-08 07:35:13 +00:00
2026-05-26 15:49:31 -07:00
2026-07-31 11:05:41 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-07-31 14:16:27 +00:00
2026-05-26 15:49:31 -07:00
2026-08-11 18:01:02 +02:00
2026-07-28 17:04:22 +00:00
2026-07-28 17:04:22 +00:00
2026-07-28 17:04:22 +00:00
2026-05-26 15:49:31 -07:00
2026-08-09 10:25:06 +00:00
2026-08-23 08:18:18 +00:00
2026-08-21 07:28:23 +00:00
2026-05-26 15:49:31 -07:00
2026-08-17 20:30:24 +00:00
2026-05-26 15:49:31 -07:00
2026-08-17 20:30:24 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2022-09-02 15:18:23 -04:00
2026-05-26 15:49:31 -07:00
2026-08-08 13:53:28 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-08 07:35:13 +00:00
2026-05-26 15:49:31 -07:00
2026-07-28 17:04:22 +00:00
2026-08-02 21:30:59 +00:00
2026-07-11 19:36:10 +02:00
2026-07-20 16:07:38 +00:00
2026-08-22 08:59:37 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-10 01:25:31 +00:00
2026-05-26 15:49:31 -07:00
2026-06-08 17:16:22 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-23 06:59:58 +00:00
2026-06-17 16:06:51 +00:00
2026-05-26 15:49:31 -07:00
2026-08-17 07:59:41 +00:00
2026-05-26 15:49:31 -07:00
2026-08-05 00:17:07 +08:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-07 20:56:40 -07:00
2026-08-03 06:41:27 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-18 04:02:52 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-09 11:32:50 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-17 18:17:16 +00:00
2026-08-10 01:25:31 +00:00
2026-05-26 15:49:31 -07:00
2026-05-26 15:49:31 -07:00
2026-08-07 00:11:34 +00:00
2026-06-06 11:06:08 +00:00
2026-06-11 17:12:30 +00:00