@@ -5,8 +5,6 @@ package packages
5
5
6
6
import (
7
7
"net/http"
8
- "regexp"
9
- "strings"
10
8
11
9
auth_model "code.gitea.io/gitea/models/auth"
12
10
"code.gitea.io/gitea/models/perm"
@@ -282,42 +280,10 @@ func CommonRoutes() *web.Router {
282
280
})
283
281
})
284
282
}, reqPackageAccess (perm .AccessModeRead ))
285
- r .Group ("/conda" , func () {
286
- var (
287
- downloadPattern = regexp .MustCompile (`\A(.+/)?(.+)/((?:[^/]+(?:\.tar\.bz2|\.conda))|(?:current_)?repodata\.json(?:\.bz2)?)\z` )
288
- uploadPattern = regexp .MustCompile (`\A(.+/)?([^/]+(?:\.tar\.bz2|\.conda))\z` )
289
- )
290
-
291
- r .Get ("/*" , func (ctx * context.Context ) {
292
- m := downloadPattern .FindStringSubmatch (ctx .PathParam ("*" ))
293
- if len (m ) == 0 {
294
- ctx .Status (http .StatusNotFound )
295
- return
296
- }
297
-
298
- ctx .SetPathParam ("channel" , strings .TrimSuffix (m [1 ], "/" ))
299
- ctx .SetPathParam ("architecture" , m [2 ])
300
- ctx .SetPathParam ("filename" , m [3 ])
301
-
302
- switch m [3 ] {
303
- case "repodata.json" , "repodata.json.bz2" , "current_repodata.json" , "current_repodata.json.bz2" :
304
- conda .EnumeratePackages (ctx )
305
- default :
306
- conda .DownloadPackageFile (ctx )
307
- }
308
- })
309
- r .Put ("/*" , reqPackageAccess (perm .AccessModeWrite ), func (ctx * context.Context ) {
310
- m := uploadPattern .FindStringSubmatch (ctx .PathParam ("*" ))
311
- if len (m ) == 0 {
312
- ctx .Status (http .StatusNotFound )
313
- return
314
- }
315
-
316
- ctx .SetPathParam ("channel" , strings .TrimSuffix (m [1 ], "/" ))
317
- ctx .SetPathParam ("filename" , m [2 ])
318
-
319
- conda .UploadPackageFile (ctx )
320
- })
283
+ r .PathGroup ("/conda" , func (g * web.RouterPathGroup ) {
284
+ g .MatchPath ("GET" , "/<architecture>/<filename>" , conda .ListOrGetPackages )
285
+ g .MatchPath ("GET" , "/<channel:*>/<architecture>/<filename>" , conda .ListOrGetPackages )
286
+ g .MatchPath ("PUT" , "/<channel:*>/<filename>" , reqPackageAccess (perm .AccessModeWrite ), conda .UploadPackageFile )
321
287
}, reqPackageAccess (perm .AccessModeRead ))
322
288
r .Group ("/cran" , func () {
323
289
r .Group ("/src" , func () {
@@ -358,60 +324,16 @@ func CommonRoutes() *web.Router {
358
324
}, reqPackageAccess (perm .AccessModeRead ))
359
325
r .Group ("/go" , func () {
360
326
r .Put ("/upload" , reqPackageAccess (perm .AccessModeWrite ), goproxy .UploadPackage )
361
- r .Get ("/sumdb/sum.golang.org/supported" , func (ctx * context.Context ) {
362
- ctx .Status (http .StatusNotFound )
363
- })
327
+ r .Get ("/sumdb/sum.golang.org/supported" , http .NotFound )
364
328
365
329
// Manual mapping of routes because the package name contains slashes which chi does not support
366
330
// https://go.dev/ref/mod#goproxy-protocol
367
- r .Get ("/*" , func (ctx * context.Context ) {
368
- path := ctx .PathParam ("*" )
369
-
370
- if strings .HasSuffix (path , "/@latest" ) {
371
- ctx .SetPathParam ("name" , path [:len (path )- len ("/@latest" )])
372
- ctx .SetPathParam ("version" , "latest" )
373
-
374
- goproxy .PackageVersionMetadata (ctx )
375
- return
376
- }
377
-
378
- parts := strings .SplitN (path , "/@v/" , 2 )
379
- if len (parts ) != 2 {
380
- ctx .Status (http .StatusNotFound )
381
- return
382
- }
383
-
384
- ctx .SetPathParam ("name" , parts [0 ])
385
-
386
- // <package/name>/@v/list
387
- if parts [1 ] == "list" {
388
- goproxy .EnumeratePackageVersions (ctx )
389
- return
390
- }
391
-
392
- // <package/name>/@v/<version>.zip
393
- if strings .HasSuffix (parts [1 ], ".zip" ) {
394
- ctx .SetPathParam ("version" , parts [1 ][:len (parts [1 ])- len (".zip" )])
395
-
396
- goproxy .DownloadPackageFile (ctx )
397
- return
398
- }
399
- // <package/name>/@v/<version>.info
400
- if strings .HasSuffix (parts [1 ], ".info" ) {
401
- ctx .SetPathParam ("version" , parts [1 ][:len (parts [1 ])- len (".info" )])
402
-
403
- goproxy .PackageVersionMetadata (ctx )
404
- return
405
- }
406
- // <package/name>/@v/<version>.mod
407
- if strings .HasSuffix (parts [1 ], ".mod" ) {
408
- ctx .SetPathParam ("version" , parts [1 ][:len (parts [1 ])- len (".mod" )])
409
-
410
- goproxy .PackageVersionGoModContent (ctx )
411
- return
412
- }
413
-
414
- ctx .Status (http .StatusNotFound )
331
+ r .PathGroup ("/*" , func (g * web.RouterPathGroup ) {
332
+ g .MatchPath ("GET" , "/<name:*>/@<version:latest>" , goproxy .PackageVersionMetadata ) // <package/name>/@latest
333
+ g .MatchPath ("GET" , "/<name:*>/@v/list" , goproxy .EnumeratePackageVersions ) // <package/name>/@v/list
334
+ g .MatchPath ("GET" , "/<name:*>/@v/<version>.zip" , goproxy .DownloadPackageFile ) // <package/name>/@v/<version>.zip
335
+ g .MatchPath ("GET" , "/<name:*>/@v/<version>.info" , goproxy .PackageVersionMetadata ) // <package/name>/@v/<version>.info
336
+ g .MatchPath ("GET" , "/<name:*>/@v/<version>.mod" , goproxy .PackageVersionGoModContent ) // <package/name>/@v/<version>.mod
415
337
})
416
338
}, reqPackageAccess (perm .AccessModeRead ))
417
339
r .Group ("/generic" , func () {
@@ -532,82 +454,23 @@ func CommonRoutes() *web.Router {
532
454
})
533
455
})
534
456
}, reqPackageAccess (perm .AccessModeRead ))
457
+
535
458
r .Group ("/pypi" , func () {
536
459
r .Post ("/" , reqPackageAccess (perm .AccessModeWrite ), pypi .UploadPackageFile )
537
460
r .Get ("/files/{id}/{version}/{filename}" , pypi .DownloadPackageFile )
538
461
r .Get ("/simple/{id}" , pypi .PackageMetadata )
539
462
}, reqPackageAccess (perm .AccessModeRead ))
540
- r .Group ("/rpm" , func () {
541
- r .Group ("/repository.key" , func () {
542
- r .Head ("" , rpm .GetRepositoryKey )
543
- r .Get ("" , rpm .GetRepositoryKey )
544
- })
545
463
546
- var (
547
- repoPattern = regexp .MustCompile (`\A(.*?)\.repo\z` )
548
- uploadPattern = regexp .MustCompile (`\A(.*?)/upload\z` )
549
- filePattern = regexp .MustCompile (`\A(.*?)/package/([^/]+)/([^/]+)/([^/]+)(?:/([^/]+\.rpm)|)\z` )
550
- repoFilePattern = regexp .MustCompile (`\A(.*?)/repodata/([^/]+)\z` )
551
- )
552
-
553
- r .Methods ("HEAD,GET,PUT,DELETE" , "*" , func (ctx * context.Context ) {
554
- path := ctx .PathParam ("*" )
555
- isHead := ctx .Req .Method == http .MethodHead
556
- isGetHead := ctx .Req .Method == http .MethodHead || ctx .Req .Method == http .MethodGet
557
- isPut := ctx .Req .Method == http .MethodPut
558
- isDelete := ctx .Req .Method == http .MethodDelete
559
-
560
- m := repoPattern .FindStringSubmatch (path )
561
- if len (m ) == 2 && isGetHead {
562
- ctx .SetPathParam ("group" , strings .Trim (m [1 ], "/" ))
563
- rpm .GetRepositoryConfig (ctx )
564
- return
565
- }
566
-
567
- m = repoFilePattern .FindStringSubmatch (path )
568
- if len (m ) == 3 && isGetHead {
569
- ctx .SetPathParam ("group" , strings .Trim (m [1 ], "/" ))
570
- ctx .SetPathParam ("filename" , m [2 ])
571
- if isHead {
572
- rpm .CheckRepositoryFileExistence (ctx )
573
- } else {
574
- rpm .GetRepositoryFile (ctx )
575
- }
576
- return
577
- }
578
-
579
- m = uploadPattern .FindStringSubmatch (path )
580
- if len (m ) == 2 && isPut {
581
- reqPackageAccess (perm .AccessModeWrite )(ctx )
582
- if ctx .Written () {
583
- return
584
- }
585
- ctx .SetPathParam ("group" , strings .Trim (m [1 ], "/" ))
586
- rpm .UploadPackageFile (ctx )
587
- return
588
- }
589
-
590
- m = filePattern .FindStringSubmatch (path )
591
- if len (m ) == 6 && (isGetHead || isDelete ) {
592
- ctx .SetPathParam ("group" , strings .Trim (m [1 ], "/" ))
593
- ctx .SetPathParam ("name" , m [2 ])
594
- ctx .SetPathParam ("version" , m [3 ])
595
- ctx .SetPathParam ("architecture" , m [4 ])
596
- if isGetHead {
597
- rpm .DownloadPackageFile (ctx )
598
- } else {
599
- reqPackageAccess (perm .AccessModeWrite )(ctx )
600
- if ctx .Written () {
601
- return
602
- }
603
- rpm .DeletePackageFile (ctx )
604
- }
605
- return
606
- }
607
-
608
- ctx .Status (http .StatusNotFound )
609
- })
464
+ r .PathGroup ("/rpm" , func (g * web.RouterPathGroup ) {
465
+ r .Methods ("HEAD,GET" , "/repository.key" , rpm .GetRepositoryKey )
466
+ g .MatchPath ("HEAD,GET" , "/<group:*>.repo" , rpm .GetRepositoryConfig )
467
+ g .MatchPath ("HEAD" , "/<group:*>/repodata/<filename>" , rpm .CheckRepositoryFileExistence )
468
+ g .MatchPath ("GET" , "/<group:*>/repodata/<filename>" , rpm .GetRepositoryFile )
469
+ g .MatchPath ("PUT" , "/<group:*>/upload" , reqPackageAccess (perm .AccessModeWrite ), rpm .UploadPackageFile )
470
+ g .MatchPath ("HEAD,GET" , "/<group:*>/package/<name>/<version>/<architecture>" , rpm .DownloadPackageFile )
471
+ g .MatchPath ("DELETE" , "/<group:*>/package/<name>/<version>/<architecture>" , reqPackageAccess (perm .AccessModeWrite ), rpm .DeletePackageFile )
610
472
}, reqPackageAccess (perm .AccessModeRead ))
473
+
611
474
r .Group ("/rubygems" , func () {
612
475
r .Get ("/specs.4.8.gz" , rubygems .EnumeratePackages )
613
476
r .Get ("/latest_specs.4.8.gz" , rubygems .EnumeratePackagesLatest )
@@ -621,6 +484,7 @@ func CommonRoutes() *web.Router {
621
484
r .Delete ("/yank" , rubygems .DeletePackage )
622
485
}, reqPackageAccess (perm .AccessModeWrite ))
623
486
}, reqPackageAccess (perm .AccessModeRead ))
487
+
624
488
r .Group ("/swift" , func () {
625
489
r .Group ("" , func () { // Needs to be unauthenticated.
626
490
r .Post ("" , swift .CheckAuthenticate )
@@ -632,31 +496,12 @@ func CommonRoutes() *web.Router {
632
496
r .Get ("" , swift .EnumeratePackageVersions )
633
497
r .Get (".json" , swift .EnumeratePackageVersions )
634
498
}, swift .CheckAcceptMediaType (swift .AcceptJSON ))
635
- r .Group ("/{version}" , func () {
636
- r .Get ("/Package.swift" , swift .CheckAcceptMediaType (swift .AcceptSwift ), swift .DownloadManifest )
637
- r .Put ("" , reqPackageAccess (perm .AccessModeWrite ), swift .CheckAcceptMediaType (swift .AcceptJSON ), swift .UploadPackageFile )
638
- r .Get ("" , func (ctx * context.Context ) {
639
- // Can't use normal routes here: https://github.com/go-chi/chi/issues/781
640
-
641
- version := ctx .PathParam ("version" )
642
- if strings .HasSuffix (version , ".zip" ) {
643
- swift .CheckAcceptMediaType (swift .AcceptZip )(ctx )
644
- if ctx .Written () {
645
- return
646
- }
647
- ctx .SetPathParam ("version" , version [:len (version )- 4 ])
648
- swift .DownloadPackageFile (ctx )
649
- } else {
650
- swift .CheckAcceptMediaType (swift .AcceptJSON )(ctx )
651
- if ctx .Written () {
652
- return
653
- }
654
- if strings .HasSuffix (version , ".json" ) {
655
- ctx .SetPathParam ("version" , version [:len (version )- 5 ])
656
- }
657
- swift .PackageVersionMetadata (ctx )
658
- }
659
- })
499
+ r .PathGroup ("" , func (g * web.RouterPathGroup ) {
500
+ g .MatchPath ("PUT" , "/<version>" , reqPackageAccess (perm .AccessModeWrite ), swift .CheckAcceptMediaType (swift .AcceptJSON ), swift .UploadPackageFile )
501
+ g .MatchPath ("GET" , "/<version>" , swift .CheckAcceptMediaType (swift .AcceptJSON ), swift .PackageVersionMetadata )
502
+ g .MatchPath ("GET" , "/<version>.json" , swift .CheckAcceptMediaType (swift .AcceptJSON ), swift .PackageVersionMetadata )
503
+ g .MatchPath ("GET" , "/<version>.zip" , swift .CheckAcceptMediaType (swift .AcceptZip ), swift .DownloadPackageFile )
504
+ g .MatchPath ("GET" , "/<version>/Package.swift" , swift .CheckAcceptMediaType (swift .AcceptSwift ), swift .DownloadManifest )
660
505
})
661
506
})
662
507
r .Get ("/identifiers" , swift .CheckAcceptMediaType (swift .AcceptJSON ), swift .LookupPackageIdentifiers )
@@ -703,18 +548,13 @@ func ContainerRoutes() *web.Router {
703
548
r .PathGroup ("/*" , func (g * web.RouterPathGroup ) {
704
549
g .MatchPath ("POST" , "/<image:*>/blobs/uploads" , reqPackageAccess (perm .AccessModeWrite ), container .VerifyImageName , container .PostBlobsUploads )
705
550
g .MatchPath ("GET" , "/<image:*>/tags/list" , container .VerifyImageName , container .GetTagsList )
706
- g .MatchPath ("GET,PATCH,PUT,DELETE" , `/<image:*>/blobs/uploads/<uuid:[-.=\w]+>` , reqPackageAccess (perm .AccessModeWrite ), container .VerifyImageName , func (ctx * context.Context ) {
707
- switch ctx .Req .Method {
708
- case http .MethodGet :
709
- container .GetBlobsUpload (ctx )
710
- case http .MethodPatch :
711
- container .PatchBlobsUpload (ctx )
712
- case http .MethodPut :
713
- container .PutBlobsUpload (ctx )
714
- default : /* DELETE */
715
- container .DeleteBlobsUpload (ctx )
716
- }
717
- })
551
+
552
+ patternBlobsUploadsUuid := g .PatternRegexp (`/<image:*>/blobs/uploads/<uuid:[-.=\w]+>` , reqPackageAccess (perm .AccessModeWrite ), container .VerifyImageName )
553
+ g .MatchRegexp ("GET" , patternBlobsUploadsUuid , container .GetBlobsUpload )
554
+ g .MatchRegexp ("PATCH" , patternBlobsUploadsUuid , container .PatchBlobsUpload )
555
+ g .MatchRegexp ("PUT" , patternBlobsUploadsUuid , container .PutBlobsUpload )
556
+ g .MatchRegexp ("DELETE" , patternBlobsUploadsUuid , container .DeleteBlobsUpload )
557
+
718
558
g .MatchPath ("HEAD" , `/<image:*>/blobs/<digest>` , container .VerifyImageName , container .HeadBlob )
719
559
g .MatchPath ("GET" , `/<image:*>/blobs/<digest>` , container .VerifyImageName , container .GetBlob )
720
560
g .MatchPath ("DELETE" , `/<image:*>/blobs/<digest>` , container .VerifyImageName , reqPackageAccess (perm .AccessModeWrite ), container .DeleteBlob )
0 commit comments