mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-31 11:28:24 +00:00 
			
		
		
		
	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>
This commit is contained in:
		| @@ -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) | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -127,10 +127,16 @@ func TestPackageNpm(t *testing.T) { | ||||
| 		b, _ := base64.StdEncoding.DecodeString(data) | ||||
| 		assert.Equal(t, b, resp.Body.Bytes()) | ||||
|  | ||||
| 		req = NewRequest(t, "GET", fmt.Sprintf("%s/-/%s", root, filename)) | ||||
| 		req = addTokenAuthHeader(req, token) | ||||
| 		resp = MakeRequest(t, req, http.StatusOK) | ||||
|  | ||||
| 		assert.Equal(t, b, resp.Body.Bytes()) | ||||
|  | ||||
| 		pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Len(t, pvs, 1) | ||||
| 		assert.Equal(t, int64(1), pvs[0].DownloadCount) | ||||
| 		assert.Equal(t, int64(2), pvs[0].DownloadCount) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("PackageMetadata", func(t *testing.T) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user