@@ -13,7 +13,7 @@ import (
13
13
"errors"
14
14
"io"
15
15
"net/http"
16
- "path/filepath "
16
+ "path"
17
17
"regexp"
18
18
"sort"
19
19
"strconv"
@@ -25,6 +25,7 @@ import (
25
25
"code.gitea.io/gitea/modules/log"
26
26
packages_module "code.gitea.io/gitea/modules/packages"
27
27
maven_module "code.gitea.io/gitea/modules/packages/maven"
28
+ "code.gitea.io/gitea/modules/util"
28
29
"code.gitea.io/gitea/routers/api/packages/helper"
29
30
"code.gitea.io/gitea/services/context"
30
31
packages_service "code.gitea.io/gitea/services/packages"
@@ -44,7 +45,7 @@ const (
44
45
45
46
var (
46
47
errInvalidParameters = errors .New ("request parameters are invalid" )
47
- illegalCharacters = regexp .MustCompile (`[\\/:"<>|?\ *]` )
48
+ illegalCharacters = regexp .MustCompile (`[\\/:"<>|?*]` )
48
49
)
49
50
50
51
func apiError (ctx * context.Context , status int , obj any ) {
@@ -85,8 +86,10 @@ func handlePackageFile(ctx *context.Context, serveContent bool) {
85
86
func serveMavenMetadata (ctx * context.Context , params parameters ) {
86
87
// /com/foo/project/maven-metadata.xml[.md5/.sha1/.sha256/.sha512]
87
88
88
- packageName := params .GroupID + "-" + params .ArtifactID
89
- pvs , err := packages_model .GetVersionsByPackageName (ctx , ctx .Package .Owner .ID , packages_model .TypeMaven , packageName )
89
+ pvs , err := packages_model .GetVersionsByPackageName (ctx , ctx .Package .Owner .ID , packages_model .TypeMaven , params .toInternalPackageName ())
90
+ if errors .Is (err , util .ErrNotExist ) {
91
+ pvs , err = packages_model .GetVersionsByPackageName (ctx , ctx .Package .Owner .ID , packages_model .TypeMaven , params .toInternalPackageNameLegacy ())
92
+ }
90
93
if err != nil {
91
94
apiError (ctx , http .StatusInternalServerError , err )
92
95
return
@@ -116,10 +119,10 @@ func serveMavenMetadata(ctx *context.Context, params parameters) {
116
119
117
120
latest := pds [len (pds )- 1 ]
118
121
// http.TimeFormat required a UTC time, refer to https://pkg.go.dev/net/http#TimeFormat
119
- lastModifed := latest .Version .CreatedUnix .AsTime ().UTC ().Format (http .TimeFormat )
120
- ctx .Resp .Header ().Set ("Last-Modified" , lastModifed )
122
+ lastModified := latest .Version .CreatedUnix .AsTime ().UTC ().Format (http .TimeFormat )
123
+ ctx .Resp .Header ().Set ("Last-Modified" , lastModified )
121
124
122
- ext := strings .ToLower (filepath .Ext (params .Filename ))
125
+ ext := strings .ToLower (path .Ext (params .Filename ))
123
126
if isChecksumExtension (ext ) {
124
127
var hash []byte
125
128
switch ext {
@@ -147,11 +150,12 @@ func serveMavenMetadata(ctx *context.Context, params parameters) {
147
150
}
148
151
149
152
func servePackageFile (ctx * context.Context , params parameters , serveContent bool ) {
150
- packageName := params .GroupID + "-" + params .ArtifactID
151
-
152
- pv , err := packages_model .GetVersionByNameAndVersion (ctx , ctx .Package .Owner .ID , packages_model .TypeMaven , packageName , params .Version )
153
+ pv , err := packages_model .GetVersionByNameAndVersion (ctx , ctx .Package .Owner .ID , packages_model .TypeMaven , params .toInternalPackageName (), params .Version )
154
+ if errors .Is (err , util .ErrNotExist ) {
155
+ pv , err = packages_model .GetVersionByNameAndVersion (ctx , ctx .Package .Owner .ID , packages_model .TypeMaven , params .toInternalPackageNameLegacy (), params .Version )
156
+ }
153
157
if err != nil {
154
- if err == packages_model .ErrPackageNotExist {
158
+ if errors . Is ( err , packages_model .ErrPackageNotExist ) {
155
159
apiError (ctx , http .StatusNotFound , err )
156
160
} else {
157
161
apiError (ctx , http .StatusInternalServerError , err )
@@ -161,14 +165,14 @@ func servePackageFile(ctx *context.Context, params parameters, serveContent bool
161
165
162
166
filename := params .Filename
163
167
164
- ext := strings .ToLower (filepath .Ext (filename ))
168
+ ext := strings .ToLower (path .Ext (filename ))
165
169
if isChecksumExtension (ext ) {
166
170
filename = filename [:len (filename )- len (ext )]
167
171
}
168
172
169
173
pf , err := packages_model .GetFileForVersionByName (ctx , pv .ID , filename , packages_model .EmptyFileKey )
170
174
if err != nil {
171
- if err == packages_model .ErrPackageFileNotExist {
175
+ if errors . Is ( err , packages_model .ErrPackageFileNotExist ) {
172
176
apiError (ctx , http .StatusNotFound , err )
173
177
} else {
174
178
apiError (ctx , http .StatusInternalServerError , err )
@@ -238,15 +242,17 @@ func UploadPackageFile(ctx *context.Context) {
238
242
return
239
243
}
240
244
241
- log .Trace ("Parameters: %+v" , params )
242
-
243
245
// Ignore the package index /<name>/maven-metadata.xml
244
246
if params .IsMeta && params .Version == "" {
245
247
ctx .Status (http .StatusOK )
246
248
return
247
249
}
248
250
249
- packageName := params .GroupID + "-" + params .ArtifactID
251
+ packageName := params .toInternalPackageName ()
252
+ if ctx .FormBool ("use_legacy_package_name" ) {
253
+ // for testing purpose only
254
+ packageName = params .toInternalPackageNameLegacy ()
255
+ }
250
256
251
257
// for the same package, only one upload at a time
252
258
releaser , err := globallock .Lock (ctx , mavenPkgNameKey (packageName ))
@@ -274,13 +280,26 @@ func UploadPackageFile(ctx *context.Context) {
274
280
Creator : ctx .Doer ,
275
281
}
276
282
277
- ext := filepath .Ext (params .Filename )
283
+ // old maven package uses "groupId-artifactId" as package name, so we need to update to the new format "groupId:artifactId"
284
+ legacyPackage , err := packages_model .GetPackageByName (ctx , ctx .Package .Owner .ID , packages_model .TypeMaven , params .toInternalPackageNameLegacy ())
285
+ if err != nil && ! errors .Is (err , packages_model .ErrPackageNotExist ) {
286
+ apiError (ctx , http .StatusInternalServerError , err )
287
+ return
288
+ } else if legacyPackage != nil {
289
+ err = packages_model .UpdatePackageNameByID (ctx , ctx .Package .Owner .ID , packages_model .TypeMaven , legacyPackage .ID , packageName )
290
+ if err != nil {
291
+ apiError (ctx , http .StatusInternalServerError , err )
292
+ return
293
+ }
294
+ }
295
+
296
+ ext := path .Ext (params .Filename )
278
297
279
298
// Do not upload checksum files but compare the hashes.
280
299
if isChecksumExtension (ext ) {
281
300
pv , err := packages_model .GetVersionByNameAndVersion (ctx , pvci .Owner .ID , pvci .PackageType , pvci .Name , pvci .Version )
282
301
if err != nil {
283
- if err == packages_model .ErrPackageNotExist {
302
+ if errors . Is ( err , packages_model .ErrPackageNotExist ) {
284
303
apiError (ctx , http .StatusNotFound , err )
285
304
return
286
305
}
@@ -289,7 +308,7 @@ func UploadPackageFile(ctx *context.Context) {
289
308
}
290
309
pf , err := packages_model .GetFileForVersionByName (ctx , pv .ID , params .Filename [:len (params .Filename )- len (ext )], packages_model .EmptyFileKey )
291
310
if err != nil {
292
- if err == packages_model .ErrPackageFileNotExist {
311
+ if errors . Is ( err , packages_model .ErrPackageFileNotExist ) {
293
312
apiError (ctx , http .StatusNotFound , err )
294
313
return
295
314
}
@@ -343,7 +362,7 @@ func UploadPackageFile(ctx *context.Context) {
343
362
344
363
if pvci .Metadata != nil {
345
364
pv , err := packages_model .GetVersionByNameAndVersion (ctx , pvci .Owner .ID , pvci .PackageType , pvci .Name , pvci .Version )
346
- if err != nil && err != packages_model .ErrPackageNotExist {
365
+ if err != nil && ! errors . Is ( err , packages_model .ErrPackageNotExist ) {
347
366
apiError (ctx , http .StatusInternalServerError , err )
348
367
return
349
368
}
@@ -399,9 +418,26 @@ type parameters struct {
399
418
IsMeta bool
400
419
}
401
420
421
+ func (p * parameters ) toInternalPackageName () string {
422
+ // there cuold be 2 choices: "/" or ":"
423
+ // Maven says: "groupId:artifactId:version" in their document: https://maven.apache.org/pom.html#Maven_Coordinates
424
+ // but it would be slightly ugly in URL: "/-/packages/maven/group-id%3Aartifact-id"
425
+ return p .GroupID + ":" + p .ArtifactID
426
+ }
427
+
428
+ func (p * parameters ) toInternalPackageNameLegacy () string {
429
+ return p .GroupID + "-" + p .ArtifactID
430
+ }
431
+
402
432
func extractPathParameters (ctx * context.Context ) (parameters , error ) {
403
433
parts := strings .Split (ctx .PathParam ("*" ), "/" )
404
434
435
+ // formats:
436
+ // * /com/group/id/artifactId/maven-metadata.xml[.md5|.sha1|.sha256|.sha512]
437
+ // * /com/group/id/artifactId/version-SNAPSHOT/maven-metadata.xml[.md5|.sha1|.sha256|.sha512]
438
+ // * /com/group/id/artifactId/version/any-file
439
+ // * /com/group/id/artifactId/version-SNAPSHOT/any-file
440
+
405
441
p := parameters {
406
442
Filename : parts [len (parts )- 1 ],
407
443
}
0 commit comments