Skip to content

Commit 49a4464

Browse files
Racer159lunny
andauthored
Allow for resolution of NPM registry paths that match upstream (#21568)
This PR fixes issue #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 0218fa7 commit 49a4464

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

routers/api/packages/api.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ func Routes(ctx gocontext.Context) *web.Route {
215215
r.Get("", npm.DownloadPackageFile)
216216
r.Delete("/-rev/{revision}", reqPackageAccess(perm.AccessModeWrite), npm.DeletePackageVersion)
217217
})
218+
r.Get("/-/{filename}", npm.DownloadPackageFileByName)
218219
r.Group("/-rev/{revision}", func() {
219220
r.Delete("", npm.DeletePackage)
220221
r.Put("", npm.DeletePreview)
@@ -227,6 +228,7 @@ func Routes(ctx gocontext.Context) *web.Route {
227228
r.Get("", npm.DownloadPackageFile)
228229
r.Delete("/-rev/{revision}", reqPackageAccess(perm.AccessModeWrite), npm.DeletePackageVersion)
229230
})
231+
r.Get("/-/{filename}", npm.DownloadPackageFileByName)
230232
r.Group("/-rev/{revision}", func() {
231233
r.Delete("", npm.DeletePackage)
232234
r.Put("", npm.DeletePreview)

routers/api/packages/npm/npm.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,49 @@ func DownloadPackageFile(ctx *context.Context) {
106106
ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime())
107107
}
108108

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

tests/integration/api_packages_npm_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,16 @@ func TestPackageNpm(t *testing.T) {
127127
b, _ := base64.StdEncoding.DecodeString(data)
128128
assert.Equal(t, b, resp.Body.Bytes())
129129

130+
req = NewRequest(t, "GET", fmt.Sprintf("%s/-/%s", root, filename))
131+
req = addTokenAuthHeader(req, token)
132+
resp = MakeRequest(t, req, http.StatusOK)
133+
134+
assert.Equal(t, b, resp.Body.Bytes())
135+
130136
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm)
131137
assert.NoError(t, err)
132138
assert.Len(t, pvs, 1)
133-
assert.Equal(t, int64(1), pvs[0].DownloadCount)
139+
assert.Equal(t, int64(2), pvs[0].DownloadCount)
134140
})
135141

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

0 commit comments

Comments
 (0)