diff options
author | Wayne Starr <Racer159@users.noreply.github.com> | 2022-10-24 08:50:22 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-24 21:50:22 +0800 |
commit | 49a4464160254604d2c42b760a901952d8bc3c8b (patch) | |
tree | f0367db2ec870b273cb4f6f1fc7c7e93291cc52a /routers | |
parent | 0218fa7cf1a7fe1b54835642165243f10b1324d9 (diff) | |
download | gitea-49a4464160254604d2c42b760a901952d8bc3c8b.tar.gz gitea-49a4464160254604d2c42b760a901952d8bc3c8b.zip |
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 <xiaolunwen@gmail.com>
Diffstat (limited to 'routers')
-rw-r--r-- | routers/api/packages/api.go | 2 | ||||
-rw-r--r-- | routers/api/packages/npm/npm.go | 43 |
2 files changed, 45 insertions, 0 deletions
diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index f6ab961f5e..69c8dd6564 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -215,6 +215,7 @@ func Routes(ctx gocontext.Context) *web.Route { r.Get("", npm.DownloadPackageFile) r.Delete("/-rev/{revision}", reqPackageAccess(perm.AccessModeWrite), npm.DeletePackageVersion) }) + r.Get("/-/{filename}", npm.DownloadPackageFileByName) r.Group("/-rev/{revision}", func() { r.Delete("", npm.DeletePackage) r.Put("", npm.DeletePreview) @@ -227,6 +228,7 @@ func Routes(ctx gocontext.Context) *web.Route { r.Get("", npm.DownloadPackageFile) r.Delete("/-rev/{revision}", reqPackageAccess(perm.AccessModeWrite), npm.DeletePackageVersion) }) + r.Get("/-/{filename}", npm.DownloadPackageFileByName) r.Group("/-rev/{revision}", func() { r.Delete("", npm.DeletePackage) r.Put("", npm.DeletePreview) diff --git a/routers/api/packages/npm/npm.go b/routers/api/packages/npm/npm.go index 2989ce6e7f..82dae0cf43 100644 --- a/routers/api/packages/npm/npm.go +++ b/routers/api/packages/npm/npm.go @@ -106,6 +106,49 @@ func DownloadPackageFile(ctx *context.Context) { ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime()) } +// DownloadPackageFileByName finds the version and serves the contents of a package +func DownloadPackageFileByName(ctx *context.Context) { + filename := ctx.Params("filename") + + pvs, _, err := packages_model.SearchVersions(ctx, &packages_model.PackageSearchOptions{ + OwnerID: ctx.Package.Owner.ID, + Type: packages_model.TypeNpm, + Name: packages_model.SearchValue{ + ExactMatch: true, + Value: packageNameFromParams(ctx), + }, + HasFileWithName: filename, + IsInternal: util.OptionalBoolFalse, + }) + if err != nil { + apiError(ctx, http.StatusInternalServerError, err) + return + } + if len(pvs) != 1 { + apiError(ctx, http.StatusNotFound, nil) + return + } + + s, pf, err := packages_service.GetFileStreamByPackageVersion( + ctx, + pvs[0], + &packages_service.PackageFileInfo{ + Filename: filename, + }, + ) + if err != nil { + if err == packages_model.ErrPackageFileNotExist { + apiError(ctx, http.StatusNotFound, err) + return + } + apiError(ctx, http.StatusInternalServerError, err) + return + } + defer s.Close() + + ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime()) +} + // UploadPackage creates a new package func UploadPackage(ctx *context.Context) { npmPackage, err := npm_module.ParsePackage(ctx.Req.Body) |