working commit

This commit is contained in:
2026-02-04 12:32:54 +02:00
parent 24b9acd678
commit 219a4cb890
17 changed files with 736 additions and 43 deletions
+82
View File
@@ -0,0 +1,82 @@
package handler
import (
"mstore/app/operator"
"mstore/app/router"
)
// HEAD /v2/<name>/blobs/<digest> 200 404
func (hand *Handler) BlobExists(rctx *router.Context) {
name, _ := rctx.GetSubpath("name")
digest, _ := rctx.GetSubpath("digest")
hand.logg.Debugf("Handle BlobExists with name=[%s] digest=[%s]", name, digest)
params := &operator.BlobExistsParams{
Name: name,
Digest: digest,
}
ctx := rctx.GetContext()
res, code, err := hand.oper.BlobExists(ctx, params)
if err != nil {
hand.logg.Errorf("BlobExist error: %v", err)
} else if res.Exists {
rctx.SetHeader("Docker-Content-Digest", res.DockerContentDigest)
rctx.SetHeader("Content-Length", res.ContentLength)
}
rctx.SetStatus(code)
}
// POST /v2/<name>/blobs/uploads/ 202 404
func (hand *Handler) PostUpload(rctx *router.Context) {
name, _ := rctx.GetSubpath("name")
digest := rctx.GetQuery("digest")
mount := rctx.GetQuery("mount")
from := rctx.GetQuery("from")
hand.logg.Debugf("Handle PostUpload with name=[%s] digest=[%s]", name, digest)
params := &operator.PostUploadParams{
Name: name,
Digest: digest,
Mount: mount,
From: from,
}
res, code, err := hand.oper.PostUpload(rctx.Ctx, params)
if err != nil {
hand.logg.Errorf("PostUpload error: %v", err)
} else {
hand.logg.Debugf("PostUpload send location=[%s] code=%d", res.Location, code)
rctx.SetHeader("Location", res.Location)
rctx.SetHeader("Content-Length", res.ContentLength)
rctx.SetHeader("Docker-Upload-UUID", res.DockerUploadUUID)
}
rctx.SetStatus(code)
}
// POST /v2/<name>/blobs/uploads/?digest=<digest> 201/202 404/400
// POST /v2/<name>/blobs/uploads/?mount=<digest>&from=<other_name> 201 404
// PATCH /v2/<name>/blobs/uploads/<reference> 202 404/416
func (hand *Handler) PatchUpload(rctx *router.Context) {
contentLength := rctx.GetHeader("Content-Length")
contentType := rctx.GetHeader("Content-Type")
name, _ := rctx.GetSubpath("name")
reference, _ := rctx.GetSubpath("reference")
reader := rctx.Request.Body
params := &operator.PatchUploadParams{
ContentLength: contentLength,
ContentType: contentType,
Name: name,
Reference: reference,
Reader: reader,
}
ctx := rctx.GetContext()
res, code, err := hand.oper.PatchUpload(ctx, params)
if err != nil {
hand.logg.Errorf("PatchUpload error: %v", err)
}
rctx.SetHeader("Location", res.Location)
rctx.SetStatus(code)
}
+4 -4
View File
@@ -24,10 +24,10 @@ func (hand *Handler) FileExists(rctx *router.Context) {
return
}
// TODO
rctx.SetHeader("X-Content-Type", res.ContentType)
rctx.SetHeader("X-Content-Length", res.ContentLength)
rctx.SetHeader("X-Content-Digest", res.ContentDigest)
rctx.SetHeader("Content-Length", zeroContentLength)
rctx.SetHeader("Content-Type", res.ContentType)
rctx.SetHeader("Content-Length", res.ContentLength)
rctx.SetHeader("Content-Digest", res.ContentDigest)
//rctx.SetHeader("Content-Length", zeroContentLength)
rctx.SetStatus(code)
}
+107
View File
@@ -0,0 +1,107 @@
package handler
import (
//"mstore/app/descr"
"mstore/app/operator"
"mstore/app/router"
)
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md
//
// Open Container Initiative Distribution Specification
//
// Existing Manifests
//
// The image manifest can be checked for existence with the following url:
//
// HEAD /v2/<name>/manifests/<reference>
//
// The name and reference parameter identify the image and are required. The reference may include a tag or digest.
//
// A 404 Not Found response will be returned if the image is unknown to the registry.
// If the image exists and the response is successful the response will be as follows:
//
// 200 OK
// Content-Length: <length of manifest>
// Docker-Content-Digest: <digest>
func (hand *Handler) ManifestExists(rctx *router.Context) {
name, _ := rctx.GetSubpath("name")
reference, _ := rctx.GetSubpath("reference")
params := &operator.ManifestExistsParams{
Name: name,
Reference: reference,
}
ctx := rctx.GetContext()
res, code, err := hand.oper.ManifestExists(ctx, params)
if err != nil {
hand.logg.Errorf("ManifestExist error: %v", err)
} else if res.Exists {
rctx.SetHeader("Content-Length", res.ContentLength)
rctx.SetHeader("Content-Type", res.ContentType)
rctx.SetHeader("Docker-Content-Digest", res.DockerContentDigest)
}
rctx.SetStatus(code)
}
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md
//
// Pushing Manifests
//
// To push a manifest, perform a PUT request to a path in the following format,
// and with the following headers and body: /v2/<name>/manifests/<reference>
//
// Clients SHOULD set the Content-Type header to the type of the manifest being pushed.
// The client SHOULD NOT include parameters on the Content-Type header (see RFC7231).
// The registry SHOULD ignore parameters on the Content-Type header.
//
// All manifests SHOULD include a mediaType field declaring the type of the manifest being pushed.
// If a manifest includes a mediaType field, clients MUST set the Content-Type header to
// the value specified by the mediaType field.
//
// Content-Type: application/vnd.oci.image.manifest.v1+json
//
// <name> is the namespace of the repository, and the <reference> MUST be either a) a digest or b) a tag.
//
// The uploaded manifest MUST reference any blobs that make up the object.
// However, the list of blobs MAY be empty.
//
// The registry MUST store the manifest in the exact byte representation provided by the client.
// Upon a successful upload, the registry MUST return response code 201 Created,
// and MUST have the following header:
//
// Location: <location>
//
// The <location> is a pullable manifest URL. The Docker-Content-Digest header returns
// the canonical digest of the uploaded blob, and MUST be equal to the client provided digest.
// Clients MAY ignore the value but if it is used, the client SHOULD verify
// the value against the uploaded blob data.
//
// An attempt to pull a nonexistent repository MUST return response code 404 Not Found.
//
// A registry SHOULD enforce some limit on the maximum manifest size that it can accept.
// A registry that enforces this limit SHOULD respond to a request to push a manifest over this
// limit with a response code 413 Payload Too Large.
// Client and registry implementations SHOULD expect to be able to support manifest
// pushes of at least 4 megabytes.
// PUT /v2/<name>/manifests/<reference> 201 404
func (hand *Handler) PutManifest(rctx *router.Context) {
name, _ := rctx.GetSubpath("name")
reference, _ := rctx.GetSubpath("reference")
contentType := rctx.GetHeader("Content-Type")
params := &operator.PutManifestParams{
ContentType: contentType,
Name: name,
Reference: reference,
Reader: rctx.Request.Body,
}
ctx := rctx.GetContext()
res, code, err := hand.oper.PutManifest(ctx, params)
if err != nil {
hand.logg.Errorf("PutManifest error: %v", err)
} else {
rctx.SetHeader("Location", res.Location)
}
rctx.SetStatus(code)
}