7cc5448a7c
Backblaze B2's S3-compatible endpoint does not implement the S3 POST Object operation. It returns HTTP 501 to every POST regardless of URL style — both path-style (https://s3.<region>.backblazeb2.com/<bucket>/) and virtual-hosted-style (https://<bucket>.s3.<region>.backblazeb2.com/). Yesterday's BucketLookupDNS fix produced virtual-hosted URLs, which is correct for AWS but doesn't help here — B2 rejects POST on either form. Verified with `curl -X POST https://...backblazeb2.com/honeyDueProd/` returning 501 directly, with no signature involved. Replace minio-go's PresignedPostPolicy with PresignHeader + http.MethodPut. The signed URL now points at a single PUT endpoint, with Content-Type and Content-Length signed via headers — B2/S3/MinIO all accept it. Drop the min/max content-length range (we sign exactly one length now); post-upload size verification still happens in VerifyAndClaim via HEAD. Response shape: - URL (was: signed POST endpoint) → now: signed PUT URL - Fields → renamed to Headers; client sends them as request headers, not multipart form parts - Method (new): always "PUT", emitted explicitly so clients don't have to hardcode Companion KMP/iOS commits switch the client paths from multipart POST to single PUT. Existing builds in the field will need to be rebuilt. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
39 lines
1.6 KiB
Go
39 lines
1.6 KiB
Go
package responses
|
|
|
|
// PresignUploadResponse is what /api/uploads/presign returns to the client.
|
|
//
|
|
// Flow: the client makes one PUT request to URL with the raw object bytes
|
|
// as the body and Headers as the request headers (verbatim — the signature
|
|
// binds them). On success, the client passes ID back via upload_ids[] on
|
|
// POST /api/task-completions/ or POST /api/documents/ to claim and attach
|
|
// the object.
|
|
//
|
|
// We use PUT (not POST) because Backblaze B2's S3-compatible endpoint does
|
|
// not implement the S3 POST Object form upload — it returns HTTP 501 on
|
|
// every request style. PUT works against AWS S3, B2, and MinIO uniformly.
|
|
type PresignUploadResponse struct {
|
|
// ID is the pending_uploads.id the client passes back via upload_ids[].
|
|
ID uint `json:"id"`
|
|
|
|
// URL is the signed PUT URL. Includes all auth as query parameters.
|
|
URL string `json:"upload_url"`
|
|
|
|
// Method is always "PUT" — emitted explicitly so clients don't have to
|
|
// hardcode it. Reserved for the rare case we ever offer alternative
|
|
// upload mechanisms.
|
|
Method string `json:"method"`
|
|
|
|
// Headers must be sent verbatim on the PUT request. Currently includes
|
|
// Content-Type and Content-Length; both are signed, and B2 will reject
|
|
// any PUT whose headers don't match.
|
|
Headers map[string]string `json:"headers"`
|
|
|
|
// Key is the object key chosen by the server. Echoed for client logging
|
|
// and debugging; the canonical reference is via ID.
|
|
Key string `json:"key"`
|
|
|
|
// ExpiresAt is when the signed URL stops working. Clients should retry
|
|
// with a fresh presign rather than relying on long-lived URLs.
|
|
ExpiresAt string `json:"expires_at"`
|
|
}
|