mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-06-18 15:15:18 +00:00
125 lines
5 KiB
Go
125 lines
5 KiB
Go
|
// Copyright 2025 The Forgejo Authors. All rights reserved.
|
||
|
// SPDX-License-Identifier: MIT
|
||
|
|
||
|
package container
|
||
|
|
||
|
import (
|
||
|
"net/http"
|
||
|
"net/http/httptest"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/stretchr/testify/assert"
|
||
|
)
|
||
|
|
||
|
func TestSetResponseHeaders(t *testing.T) {
|
||
|
t.Run("Content-Length for empty content", func(t *testing.T) {
|
||
|
recorder := httptest.NewRecorder()
|
||
|
|
||
|
setResponseHeaders(recorder, &containerHeaders{
|
||
|
Status: http.StatusOK,
|
||
|
ContentLength: 0, // Empty blob
|
||
|
ContentDigest: "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||
|
})
|
||
|
|
||
|
assert.Equal(t, "0", recorder.Header().Get("Content-Length"))
|
||
|
assert.Equal(t, "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", recorder.Header().Get("Docker-Content-Digest"))
|
||
|
assert.Equal(t, "registry/2.0", recorder.Header().Get("Docker-Distribution-Api-Version"))
|
||
|
assert.Equal(t, http.StatusOK, recorder.Code)
|
||
|
})
|
||
|
|
||
|
t.Run("Content-Length for non-empty content", func(t *testing.T) {
|
||
|
recorder := httptest.NewRecorder()
|
||
|
|
||
|
setResponseHeaders(recorder, &containerHeaders{
|
||
|
Status: http.StatusOK,
|
||
|
ContentLength: 1024,
|
||
|
ContentDigest: "sha256:abcd1234",
|
||
|
})
|
||
|
|
||
|
assert.Equal(t, "1024", recorder.Header().Get("Content-Length"))
|
||
|
assert.Equal(t, "sha256:abcd1234", recorder.Header().Get("Docker-Content-Digest"))
|
||
|
})
|
||
|
|
||
|
t.Run("All headers set correctly", func(t *testing.T) {
|
||
|
recorder := httptest.NewRecorder()
|
||
|
|
||
|
setResponseHeaders(recorder, &containerHeaders{
|
||
|
Status: http.StatusAccepted,
|
||
|
ContentLength: 512,
|
||
|
ContentDigest: "sha256:test123",
|
||
|
ContentType: "application/vnd.oci.image.manifest.v1+json",
|
||
|
Location: "/v2/test/repo/blobs/uploads/uuid123",
|
||
|
Range: "0-511",
|
||
|
UploadUUID: "uuid123",
|
||
|
})
|
||
|
|
||
|
assert.Equal(t, "512", recorder.Header().Get("Content-Length"))
|
||
|
assert.Equal(t, "sha256:test123", recorder.Header().Get("Docker-Content-Digest"))
|
||
|
assert.Equal(t, "application/vnd.oci.image.manifest.v1+json", recorder.Header().Get("Content-Type"))
|
||
|
assert.Equal(t, "/v2/test/repo/blobs/uploads/uuid123", recorder.Header().Get("Location"))
|
||
|
assert.Equal(t, "0-511", recorder.Header().Get("Range"))
|
||
|
assert.Equal(t, "uuid123", recorder.Header().Get("Docker-Upload-Uuid"))
|
||
|
assert.Equal(t, "registry/2.0", recorder.Header().Get("Docker-Distribution-Api-Version"))
|
||
|
assert.Equal(t, `"sha256:test123"`, recorder.Header().Get("ETag"))
|
||
|
assert.Equal(t, http.StatusAccepted, recorder.Code)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
// TestResponseHeadersForEmptyBlobs tests the core fix for ORAS empty blob support
|
||
|
func TestResponseHeadersForEmptyBlobs(t *testing.T) {
|
||
|
t.Run("Content-Length set for empty blob", func(t *testing.T) {
|
||
|
recorder := httptest.NewRecorder()
|
||
|
|
||
|
// This tests the main fix: empty blobs should have Content-Length: 0
|
||
|
setResponseHeaders(recorder, &containerHeaders{
|
||
|
Status: http.StatusOK,
|
||
|
ContentLength: 0, // Empty blob (like empty config in ORAS artifacts)
|
||
|
ContentDigest: "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||
|
})
|
||
|
|
||
|
// The key fix: Content-Length should be set even for 0-byte blobs
|
||
|
assert.Equal(t, "0", recorder.Header().Get("Content-Length"))
|
||
|
assert.Equal(t, "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", recorder.Header().Get("Docker-Content-Digest"))
|
||
|
assert.Equal(t, "registry/2.0", recorder.Header().Get("Docker-Distribution-Api-Version"))
|
||
|
assert.Equal(t, `"sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"`, recorder.Header().Get("ETag"))
|
||
|
assert.Equal(t, http.StatusOK, recorder.Code)
|
||
|
})
|
||
|
|
||
|
t.Run("Content-Length set for regular blob", func(t *testing.T) {
|
||
|
recorder := httptest.NewRecorder()
|
||
|
|
||
|
setResponseHeaders(recorder, &containerHeaders{
|
||
|
Status: http.StatusOK,
|
||
|
ContentLength: 1024,
|
||
|
ContentDigest: "sha256:abcd1234",
|
||
|
})
|
||
|
|
||
|
assert.Equal(t, "1024", recorder.Header().Get("Content-Length"))
|
||
|
assert.Equal(t, "sha256:abcd1234", recorder.Header().Get("Docker-Content-Digest"))
|
||
|
})
|
||
|
|
||
|
t.Run("All headers set correctly", func(t *testing.T) {
|
||
|
recorder := httptest.NewRecorder()
|
||
|
|
||
|
setResponseHeaders(recorder, &containerHeaders{
|
||
|
Status: http.StatusAccepted,
|
||
|
ContentLength: 512,
|
||
|
ContentDigest: "sha256:test123",
|
||
|
ContentType: "application/vnd.oci.image.manifest.v1+json",
|
||
|
Location: "/v2/test/repo/blobs/uploads/uuid123",
|
||
|
Range: "0-511",
|
||
|
UploadUUID: "uuid123",
|
||
|
})
|
||
|
|
||
|
assert.Equal(t, "512", recorder.Header().Get("Content-Length"))
|
||
|
assert.Equal(t, "sha256:test123", recorder.Header().Get("Docker-Content-Digest"))
|
||
|
assert.Equal(t, "application/vnd.oci.image.manifest.v1+json", recorder.Header().Get("Content-Type"))
|
||
|
assert.Equal(t, "/v2/test/repo/blobs/uploads/uuid123", recorder.Header().Get("Location"))
|
||
|
assert.Equal(t, "0-511", recorder.Header().Get("Range"))
|
||
|
assert.Equal(t, "uuid123", recorder.Header().Get("Docker-Upload-Uuid"))
|
||
|
assert.Equal(t, "registry/2.0", recorder.Header().Get("Docker-Distribution-Api-Version"))
|
||
|
assert.Equal(t, `"sha256:test123"`, recorder.Header().Get("ETag"))
|
||
|
assert.Equal(t, http.StatusAccepted, recorder.Code)
|
||
|
})
|
||
|
}
|