feat: S3 client compatibility — virtual-hosted style, CORS, presigned multi-method, ListMultipartUploads, edge case fixes
- Virtual-hosted bucket detection from Host header (extractS3BucketFromHost) - S3 CORS headers + OPTIONS preflight + x-amz-id-2/HostId everywhere - Presigned GET/PUT/HEAD/DELETE via centralized auth (no GET-only restriction) - ListMultipartUploads with DB/xml helpers - UploadPart partNumber range validation (1-10000) - CompleteMultipartUpload ETag matching and ascending order validation - DeleteObjects quiet mode support - CopyObject URL-decode and conditional if-match/if-none-match - encoding-type=url support in ListObjects V1/V2 XML - Safe range-based prefix matching (replaces SQL LIKE) - STREAMING-AWS4-HMAC-SHA256-PAYLOAD → 501 NotImplemented - Traefik wildcard HostRegex for virtual-hosted style - S3_VHOST_DOMAINS config env var
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { applyS3Headers } from './headers';
|
||||
import { contentRange, type RangeParseResult } from './range';
|
||||
|
||||
export interface ObjectPartSource {
|
||||
@@ -97,7 +98,7 @@ export const createGetObjectResponse = async (input: ObjectResponseInput): Promi
|
||||
const end = input.range.type === 'valid' ? input.range.end : input.totalSize - 1;
|
||||
const plannedParts = planParts(input.parts, start, end);
|
||||
const contentLength = end >= start ? end - start + 1 : 0;
|
||||
const headers = baseHeaders(input, contentLength);
|
||||
const headers = applyS3Headers(baseHeaders(input, contentLength), input.reqId);
|
||||
|
||||
if (input.range.type === 'valid') {
|
||||
headers.set('content-range', contentRange(start, end, input.totalSize));
|
||||
|
||||
Reference in New Issue
Block a user