@@ -5,8 +5,6 @@ package packages
55
66import (
77 "net/http"
8- "regexp"
9- "strings"
108
119 auth_model "code.gitea.io/gitea/models/auth"
1210 "code.gitea.io/gitea/models/perm"
@@ -282,42 +280,10 @@ func CommonRoutes() *web.Router {
282280 })
283281 })
284282 }, 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 )
321287 }, reqPackageAccess (perm .AccessModeRead ))
322288 r .Group ("/cran" , func () {
323289 r .Group ("/src" , func () {
@@ -358,60 +324,16 @@ func CommonRoutes() *web.Router {
358324 }, reqPackageAccess (perm .AccessModeRead ))
359325 r .Group ("/go" , func () {
360326 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 )
364328
365329 // Manual mapping of routes because the package name contains slashes which chi does not support
366330 // 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
415337 })
416338 }, reqPackageAccess (perm .AccessModeRead ))
417339 r .Group ("/generic" , func () {
@@ -532,82 +454,23 @@ func CommonRoutes() *web.Router {
532454 })
533455 })
534456 }, reqPackageAccess (perm .AccessModeRead ))
457+
535458 r .Group ("/pypi" , func () {
536459 r .Post ("/" , reqPackageAccess (perm .AccessModeWrite ), pypi .UploadPackageFile )
537460 r .Get ("/files/{id}/{version}/{filename}" , pypi .DownloadPackageFile )
538461 r .Get ("/simple/{id}" , pypi .PackageMetadata )
539462 }, 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- })
545463
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 )
610472 }, reqPackageAccess (perm .AccessModeRead ))
473+
611474 r .Group ("/rubygems" , func () {
612475 r .Get ("/specs.4.8.gz" , rubygems .EnumeratePackages )
613476 r .Get ("/latest_specs.4.8.gz" , rubygems .EnumeratePackagesLatest )
@@ -621,6 +484,7 @@ func CommonRoutes() *web.Router {
621484 r .Delete ("/yank" , rubygems .DeletePackage )
622485 }, reqPackageAccess (perm .AccessModeWrite ))
623486 }, reqPackageAccess (perm .AccessModeRead ))
487+
624488 r .Group ("/swift" , func () {
625489 r .Group ("" , func () { // Needs to be unauthenticated.
626490 r .Post ("" , swift .CheckAuthenticate )
@@ -632,31 +496,12 @@ func CommonRoutes() *web.Router {
632496 r .Get ("" , swift .EnumeratePackageVersions )
633497 r .Get (".json" , swift .EnumeratePackageVersions )
634498 }, 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 )
660505 })
661506 })
662507 r .Get ("/identifiers" , swift .CheckAcceptMediaType (swift .AcceptJSON ), swift .LookupPackageIdentifiers )
@@ -703,18 +548,13 @@ func ContainerRoutes() *web.Router {
703548 r .PathGroup ("/*" , func (g * web.RouterPathGroup ) {
704549 g .MatchPath ("POST" , "/<image:*>/blobs/uploads" , reqPackageAccess (perm .AccessModeWrite ), container .VerifyImageName , container .PostBlobsUploads )
705550 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+
718558 g .MatchPath ("HEAD" , `/<image:*>/blobs/<digest>` , container .VerifyImageName , container .HeadBlob )
719559 g .MatchPath ("GET" , `/<image:*>/blobs/<digest>` , container .VerifyImageName , container .GetBlob )
720560 g .MatchPath ("DELETE" , `/<image:*>/blobs/<digest>` , container .VerifyImageName , reqPackageAccess (perm .AccessModeWrite ), container .DeleteBlob )
0 commit comments