mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-05-31 20:02:09 +00:00
Add support for HEAD requests in Maven registry (#21834)
Related #18543 Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
parent
26f941fbda
commit
fc7a2d5a95
19 changed files with 162 additions and 40 deletions
|
@ -6,7 +6,6 @@ package maven
|
|||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
packages_model "code.gitea.io/gitea/models/packages"
|
||||
|
@ -23,12 +22,8 @@ type MetadataResponse struct {
|
|||
Version []string `xml:"versioning>versions>version"`
|
||||
}
|
||||
|
||||
// pds is expected to be sorted ascending by CreatedUnix
|
||||
func createMetadataResponse(pds []*packages_model.PackageDescriptor) *MetadataResponse {
|
||||
sort.Slice(pds, func(i, j int) bool {
|
||||
// Maven and Gradle order packages by their creation timestamp and not by their version string
|
||||
return pds[i].Version.CreatedUnix < pds[j].Version.CreatedUnix
|
||||
})
|
||||
|
||||
var release *packages_model.PackageDescriptor
|
||||
|
||||
versions := make([]string, 0, len(pds))
|
||||
|
|
|
@ -16,6 +16,8 @@ import (
|
|||
"net/http"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
packages_model "code.gitea.io/gitea/models/packages"
|
||||
|
@ -34,6 +36,10 @@ const (
|
|||
extensionSHA1 = ".sha1"
|
||||
extensionSHA256 = ".sha256"
|
||||
extensionSHA512 = ".sha512"
|
||||
extensionPom = ".pom"
|
||||
extensionJar = ".jar"
|
||||
contentTypeJar = "application/java-archive"
|
||||
contentTypeXML = "text/xml"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -49,6 +55,15 @@ func apiError(ctx *context.Context, status int, obj interface{}) {
|
|||
|
||||
// DownloadPackageFile serves the content of a package
|
||||
func DownloadPackageFile(ctx *context.Context) {
|
||||
handlePackageFile(ctx, true)
|
||||
}
|
||||
|
||||
// ProvidePackageFileHeader provides only the headers describing a package
|
||||
func ProvidePackageFileHeader(ctx *context.Context) {
|
||||
handlePackageFile(ctx, false)
|
||||
}
|
||||
|
||||
func handlePackageFile(ctx *context.Context, serveContent bool) {
|
||||
params, err := extractPathParameters(ctx)
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusBadRequest, err)
|
||||
|
@ -58,7 +73,7 @@ func DownloadPackageFile(ctx *context.Context) {
|
|||
if params.IsMeta && params.Version == "" {
|
||||
serveMavenMetadata(ctx, params)
|
||||
} else {
|
||||
servePackageFile(ctx, params)
|
||||
servePackageFile(ctx, params, serveContent)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,6 +97,11 @@ func serveMavenMetadata(ctx *context.Context, params parameters) {
|
|||
return
|
||||
}
|
||||
|
||||
sort.Slice(pds, func(i, j int) bool {
|
||||
// Maven and Gradle order packages by their creation timestamp and not by their version string
|
||||
return pds[i].Version.CreatedUnix < pds[j].Version.CreatedUnix
|
||||
})
|
||||
|
||||
xmlMetadata, err := xml.Marshal(createMetadataResponse(pds))
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
|
@ -89,6 +109,9 @@ func serveMavenMetadata(ctx *context.Context, params parameters) {
|
|||
}
|
||||
xmlMetadataWithHeader := append([]byte(xml.Header), xmlMetadata...)
|
||||
|
||||
latest := pds[len(pds)-1]
|
||||
ctx.Resp.Header().Set("Last-Modified", latest.Version.CreatedUnix.Format(http.TimeFormat))
|
||||
|
||||
ext := strings.ToLower(filepath.Ext(params.Filename))
|
||||
if isChecksumExtension(ext) {
|
||||
var hash []byte
|
||||
|
@ -110,10 +133,15 @@ func serveMavenMetadata(ctx *context.Context, params parameters) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.PlainTextBytes(http.StatusOK, xmlMetadataWithHeader)
|
||||
ctx.Resp.Header().Set("Content-Length", strconv.Itoa(len(xmlMetadataWithHeader)))
|
||||
ctx.Resp.Header().Set("Content-Type", contentTypeXML)
|
||||
|
||||
if _, err := ctx.Resp.Write(xmlMetadataWithHeader); err != nil {
|
||||
log.Error("write bytes failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func servePackageFile(ctx *context.Context, params parameters) {
|
||||
func servePackageFile(ctx *context.Context, params parameters, serveContent bool) {
|
||||
packageName := params.GroupID + "-" + params.ArtifactID
|
||||
|
||||
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeMaven, packageName, params.Version)
|
||||
|
@ -165,6 +193,23 @@ func servePackageFile(ctx *context.Context, params parameters) {
|
|||
return
|
||||
}
|
||||
|
||||
opts := &context.ServeHeaderOptions{
|
||||
ContentLength: &pb.Size,
|
||||
LastModified: pf.CreatedUnix.AsLocalTime(),
|
||||
}
|
||||
switch ext {
|
||||
case extensionJar:
|
||||
opts.ContentType = contentTypeJar
|
||||
case extensionPom:
|
||||
opts.ContentType = contentTypeXML
|
||||
}
|
||||
|
||||
if !serveContent {
|
||||
ctx.SetServeHeaders(opts)
|
||||
ctx.Status(http.StatusOK)
|
||||
return
|
||||
}
|
||||
|
||||
s, err := packages_module.NewContentStore().Get(packages_module.BlobHash256Key(pb.HashSHA256))
|
||||
if err != nil {
|
||||
apiError(ctx, http.StatusInternalServerError, err)
|
||||
|
@ -177,7 +222,9 @@ func servePackageFile(ctx *context.Context, params parameters) {
|
|||
}
|
||||
}
|
||||
|
||||
ctx.ServeContent(pf.Name, s, pf.CreatedUnix.AsLocalTime())
|
||||
opts.Filename = pf.Name
|
||||
|
||||
ctx.ServeContent(s, opts)
|
||||
}
|
||||
|
||||
// UploadPackageFile adds a file to the package. If the package does not exist, it gets created.
|
||||
|
@ -273,7 +320,7 @@ func UploadPackageFile(ctx *context.Context) {
|
|||
}
|
||||
|
||||
// If it's the package pom file extract the metadata
|
||||
if ext == ".pom" {
|
||||
if ext == extensionPom {
|
||||
pfci.IsLead = true
|
||||
|
||||
var err error
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue