A container registry that uses the AT Protocol for manifest storage and S3 for blob storage. atcr.io
docker container atproto go

more s3 fixes

evan.jarrett.net 0d723cb7 f307d6ea

verified
+38
+33
pkg/hold/pds/xrpc_test.go
··· 220 220 return &header, &commit 221 221 } 222 222 223 + // skipAccountEvent reads and discards the initial #account event that the 224 + // EventBroadcaster sends to every new subscriber. 225 + func skipAccountEvent(t *testing.T, conn *websocket.Conn) { 226 + t.Helper() 227 + msgType, message, err := conn.ReadMessage() 228 + if err != nil { 229 + t.Fatalf("Failed to read account event: %v", err) 230 + } 231 + if msgType != websocket.BinaryMessage { 232 + t.Fatalf("Expected binary message for account event, got type %d", msgType) 233 + } 234 + reader := bytes.NewReader(message) 235 + var header events.EventHeader 236 + if err := header.UnmarshalCBOR(reader); err != nil { 237 + t.Fatalf("Failed to decode account event header: %v", err) 238 + } 239 + if header.MsgType != "#account" { 240 + t.Fatalf("Expected #account event, got %s", header.MsgType) 241 + } 242 + } 243 + 223 244 // assertCARResponse validates CAR file response 224 245 func assertCARResponse(t *testing.T, w *httptest.ResponseRecorder, expectedCode int) []byte { 225 246 t.Helper() ··· 2851 2872 } 2852 2873 defer conn.Close() 2853 2874 2875 + // Skip the initial #account event 2876 + skipAccountEvent(t, conn) 2877 + 2854 2878 // Should receive the 3 historical events 2855 2879 for i := 0; i < 3; i++ { 2856 2880 messageType, message, err := conn.ReadMessage() ··· 2889 2913 t.Fatalf("Failed to connect to WebSocket: %v", err) 2890 2914 } 2891 2915 defer conn.Close() 2916 + 2917 + // Skip the initial #account event 2918 + skipAccountEvent(t, conn) 2892 2919 2893 2920 // Should only receive event 3 (after cursor=2) 2894 2921 messageType, message, err := conn.ReadMessage() ··· 2926 2953 } 2927 2954 defer conn.Close() 2928 2955 2956 + // Skip the initial #account event 2957 + skipAccountEvent(t, conn) 2958 + 2929 2959 // Verify no historical events by broadcasting immediately and checking 2930 2960 // that we only receive the new event (not historical ones) 2931 2961 // Give subscriber time to register first ··· 2977 3007 t.Fatalf("Failed to connect to WebSocket: %v", err) 2978 3008 } 2979 3009 defer conn.Close() 3010 + 3011 + // Skip the initial #account event 3012 + skipAccountEvent(t, conn) 2980 3013 2981 3014 // Read and discard the 4 historical events (seq 1-4) 2982 3015 for i := 0; i < 4; i++ {
+5
pkg/s3/types.go
··· 192 192 o.BaseEndpoint = aws.String(endpoint) 193 193 o.UsePathStyle = true 194 194 } 195 + // Disable automatic CRC32 checksum calculation on uploads. 196 + // SDK v2 v1.71.0+ adds checksums by default using chunked encoding 197 + // with trailers, which causes XAmzContentSHA256Mismatch errors on 198 + // S3-compatible services that don't support this. 199 + o.RequestChecksumCalculation = aws.RequestChecksumCalculationWhenRequired 195 200 }) 196 201 197 202 var s3PathPrefix string