Skip to content

Commit 32a5288

Browse files
Racer159lunny
andcommitted
Allow for resolution of NPM registry paths that match upstream (go-gitea#21568)
Backport (go-gitea#21568) This PR fixes issue go-gitea#21567 allowing for package tarball URLs to match the upstream registry (and GitLab/JFrog Artifactory URLs). It uses a regex to parse the filename (which contains the NPM version) and does a fuzzy search to pull it out. The regex was built/expanded from http://json.schemastore.org/package, https://github.com/Masterminds/semver, and https://docs.npmjs.com/cli/v6/using-npm/semver and is testable here: https://regex101.com/r/OydBJq/5 Co-authored-by: Lunny Xiao <[email protected]>
1 parent d6d62c0 commit 32a5288

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

integrations/api_packages_npm_test.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,16 @@ func TestPackageNpm(t *testing.T) {
123123
b, _ := base64.StdEncoding.DecodeString(data)
124124
assert.Equal(t, b, resp.Body.Bytes())
125125

126+
req = NewRequest(t, "GET", fmt.Sprintf("%s/-/%s", root, filename))
127+
req = addTokenAuthHeader(req, token)
128+
resp = MakeRequest(t, req, http.StatusOK)
129+
130+
assert.Equal(t, b, resp.Body.Bytes())
131+
126132
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm)
127133
assert.NoError(t, err)
128134
assert.Len(t, pvs, 1)
129-
assert.Equal(t, int64(1), pvs[0].DownloadCount)
135+
assert.Equal(t, int64(2), pvs[0].DownloadCount)
130136
})
131137

132138
t.Run("PackageMetadata", func(t *testing.T) {

routers/api/packages/api.go

+2
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,13 @@ func Routes() *web.Route {
199199
r.Get("", npm.PackageMetadata)
200200
r.Put("", reqPackageAccess(perm.AccessModeWrite), npm.UploadPackage)
201201
r.Get("/-/{version}/{filename}", npm.DownloadPackageFile)
202+
r.Get("/-/{filename}", npm.DownloadPackageFileByName)
202203
})
203204
r.Group("/{id}", func() {
204205
r.Get("", npm.PackageMetadata)
205206
r.Put("", reqPackageAccess(perm.AccessModeWrite), npm.UploadPackage)
206207
r.Get("/-/{version}/{filename}", npm.DownloadPackageFile)
208+
r.Get("/-/{filename}", npm.DownloadPackageFileByName)
207209
})
208210
r.Group("/-/package/@{scope}/{id}/dist-tags", func() {
209211
r.Get("", npm.ListPackageTags)

routers/api/packages/npm/npm.go

+43
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,49 @@ func DownloadPackageFile(ctx *context.Context) {
105105
ctx.ServeStream(s, pf.Name)
106106
}
107107

108+
// DownloadPackageFileByName finds the version and serves the contents of a package
109+
func DownloadPackageFileByName(ctx *context.Context) {
110+
filename := ctx.Params("filename")
111+
112+
pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{
113+
OwnerID: ctx.Package.Owner.ID,
114+
Type: packages_model.TypeNpm,
115+
Name: packages_model.SearchValue{
116+
ExactMatch: true,
117+
Value: packageNameFromParams(ctx),
118+
},
119+
HasFileWithName: filename,
120+
IsInternal: util.OptionalBoolFalse,
121+
})
122+
if err != nil {
123+
apiError(ctx, http.StatusInternalServerError, err)
124+
return
125+
}
126+
if len(pvs) != 1 {
127+
apiError(ctx, http.StatusNotFound, nil)
128+
return
129+
}
130+
131+
s, pf, err := packages_service.GetFileStreamByPackageVersion(
132+
ctx,
133+
pvs[0],
134+
&packages_service.PackageFileInfo{
135+
Filename: filename,
136+
},
137+
)
138+
if err != nil {
139+
if err == packages_model.ErrPackageFileNotExist {
140+
apiError(ctx, http.StatusNotFound, err)
141+
return
142+
}
143+
apiError(ctx, http.StatusInternalServerError, err)
144+
return
145+
}
146+
defer s.Close()
147+
148+
ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime())
149+
}
150+
108151
// UploadPackage creates a new package
109152
func UploadPackage(ctx *context.Context) {
110153
npmPackage, err := npm_module.ParsePackage(ctx.Req.Body)

0 commit comments

Comments
 (0)