feat: support ranged S3 GetObject responses

Wire createGetObjectResponse into single-part GetObject handler for
proper Range/Content-Range support (200, 206, 416). Update presigned
E2E test to require 200. Add SDK Range request test.
This commit is contained in:
asepharyana
2026-07-07 04:30:04 +07:00
parent 378a084fd3
commit ad45404132
4 changed files with 69 additions and 31 deletions
+22 -11
View File
@@ -369,17 +369,28 @@ describe('S3 API (production, SigV4)', () => {
const presignedUrl = `${BASE_URL}/${bucketName}/presigned-test.txt?${sp.toString()}`;
const r = await fetch(presignedUrl);
// Presigned URL: 200 (proxied body), 302 (redirect), or 403 (auth fail)
if (r.status === 403) {
console.warn('⚠️ Presigned URL returned 403 — verification mismatch');
}
expect([200, 302, 403]).toContain(r.status);
if (r.status === 200) {
const text = await r.text();
expect(text).toContain('presigned content');
} else if (r.status === 302) {
expect(r.headers.get('location')).toBeTruthy();
}
expect(r.status).toBe(200);
const text = await r.text();
expect(text).toContain('presigned content');
});
it('GetObject Range — returns partial single-part content', async () => {
const r = await s3Request('GET', `/${bucketName}/test-file.txt`, {
headers: { range: 'bytes=0-4' },
});
expect(r.status).toBe(206);
expect(r.headers.get('content-range')).toBe('bytes 0-4/8');
expect(await r.text()).toBe('hello');
});
it('GetObject Range — invalid range returns 416 XML', async () => {
const r = await s3Request('GET', `/${bucketName}/test-file.txt`, {
headers: { range: 'bytes=999-1000' },
});
expect(r.status).toBe(416);
expect(r.headers.get('content-range')).toBe('bytes */8');
const xml = await r.text();
expect(xml).toContain('InvalidRange');
});
it('Delete bucket — must be empty first', async () => {
+9
View File
@@ -174,6 +174,15 @@ describe('S3 SDK compatibility', () => {
expect(ETag).toBeTruthy();
});
it('GetObject supports Range requests', async () => {
const { Body, ContentRange, ContentLength } = await s3.send(
new GetObjectCommand({ Bucket: BUCKET, Key: 'hello-sdk.txt', Range: 'bytes=0-4' }),
);
expect(ContentRange).toMatch(/^bytes 0-4\//);
expect(ContentLength).toBe(5);
expect(await Body!.transformToString()).toBe('Hello');
});
it('GetObject returns 404 (NoSuchKey) for missing key', async () => {
await expect(
s3.send(new GetObjectCommand({ Bucket: BUCKET, Key: 'does-not-exist.txt' })),