From 49398593bd4cee4bf89749c835a6d4fd76231a43 Mon Sep 17 00:00:00 2001 From: Prakash Date: Tue, 26 May 2026 21:59:50 +0530 Subject: [PATCH] @uppy/aws-s3: update examples (#6311) - update outdated examples based on latest api changes --- examples/aws-nodejs/public/index.html | 2 +- examples/aws-php/main.js | 32 ++++------ examples/aws-php/s3-sign.php | 63 +++++++++++++------ .../companion-digitalocean-spaces/README.md | 4 +- .../companion-digitalocean-spaces/main.js | 2 +- 5 files changed, 60 insertions(+), 43 deletions(-) diff --git a/examples/aws-nodejs/public/index.html b/examples/aws-nodejs/public/index.html index d3a09d7b5..1173b0c2c 100644 --- a/examples/aws-nodejs/public/index.html +++ b/examples/aws-nodejs/public/index.html @@ -57,7 +57,7 @@ height: 400, }) .use(AwsS3, { - bucket: window.UPPY_S3_BUCKET, + s3Endpoint: `https://${window.UPPY_S3_BUCKET}.s3.${window.UPPY_S3_REGION}.amazonaws.com`, region: window.UPPY_S3_REGION, getCredentials: async ({ signal }) => { const response = await fetch('/s3/sts', { signal }) diff --git a/examples/aws-php/main.js b/examples/aws-php/main.js index 4704663bf..fbff325cb 100644 --- a/examples/aws-php/main.js +++ b/examples/aws-php/main.js @@ -11,34 +11,24 @@ uppy.use(Dashboard, { target: 'body', }) uppy.use(AwsS3, { - shouldUseMultipart: false, // The PHP backend only supports non-multipart uploads + // The PHP backend only signs single PutObject URLs (no multipart). + shouldUseMultipart: false, - getUploadParameters(file) { - // Send a request to our PHP signing endpoint. - return fetch('/s3-sign.php', { - method: 'post', - // Send and receive JSON. + // signRequest is called for each S3 operation. For single PUTs the + // request is `{ method: 'PUT', key }`. The server returns a presigned URL. + signRequest: async (request) => { + const response = await fetch('/s3-sign.php', { + method: 'POST', headers: { accept: 'application/json', 'content-type': 'application/json', }, body: JSON.stringify({ - filename: file.name, - contentType: file.type, + method: request.method, + key: request.key, }), }) - .then((response) => { - // Parse the JSON response. - return response.json() - }) - .then((data) => { - // Return an object in the correct shape. - return { - method: data.method, - url: data.url, - fields: data.fields, - headers: data.headers, - } - }) + if (!response.ok) throw new Error('Failed to get presigned URL') + return response.json() }, }) diff --git a/examples/aws-php/s3-sign.php b/examples/aws-php/s3-sign.php index b6ea7b828..6dae3d51c 100644 --- a/examples/aws-php/s3-sign.php +++ b/examples/aws-php/s3-sign.php @@ -2,7 +2,14 @@ require 'vendor/autoload.php'; header('Access-Control-Allow-Origin: *'); -header("Access-Control-Allow-Headers: GET"); +header('Access-Control-Allow-Methods: POST, OPTIONS'); +header('Access-Control-Allow-Headers: Content-Type'); + +// Short-circuit CORS preflight before any further processing. +if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { + http_response_code(204); + exit; +} // CONFIG: Change these variables to a valid region and bucket. $awsEndpoint = getenv('COMPANION_AWS_ENDPOINT') ?: null; @@ -11,36 +18,56 @@ $bucket = getenv('COMPANION_AWS_BUCKET') ?: 'uppy-test'; // Directory to place uploaded files in. $directory = 'uppy-php-example'; -// Create the S3 client. -$s3 = new Aws\S3\S3Client([ +// Read credentials from the repo's Companion-style env vars (matches the +// .env used by the rest of the examples). Fall back to the AWS SDK's default +// credential chain (~/.aws/credentials, AWS_ACCESS_KEY_ID, etc.) if these +// aren't set. +$awsKey = getenv('COMPANION_AWS_KEY') ?: null; +$awsSecret = getenv('COMPANION_AWS_SECRET') ?: null; + +$clientConfig = [ 'version' => 'latest', 'endpoint' => $awsEndpoint, 'region' => $awsRegion, -]); +]; +if ($awsKey && $awsSecret) { + $clientConfig['credentials'] = [ + 'key' => $awsKey, + 'secret' => $awsSecret, + ]; +} -// Retrieve data about the file to be uploaded from the request body. +$s3 = new Aws\S3\S3Client($clientConfig); + +// The @uppy/aws-s3 plugin sends `{ method, key }` per operation. +// This example only handles PUT (PutObject) — multipart is disabled client-side. $body = json_decode(file_get_contents('php://input')); -$filename = $body->filename; -$contentType = $body->contentType; +if (!is_object($body)) { + http_response_code(400); + header('content-type: application/json'); + echo json_encode(['error' => 'Invalid or empty JSON body']); + exit; +} + +$method = $body->method ?? 'PUT'; +$key = $body->key ?? null; + +if ($method !== 'PUT' || !$key) { + http_response_code(400); + header('content-type: application/json'); + echo json_encode(['error' => 'Only PUT requests with a key are supported']); + exit; +} -// Prepare a PutObject command. $command = $s3->getCommand('putObject', [ 'Bucket' => $bucket, - 'Key' => "{$directory}/{$filename}", - 'ContentType' => $contentType, - 'Body' => '', + 'Key' => "{$directory}/{$key}", ]); $request = $s3->createPresignedRequest($command, '+5 minutes'); header('content-type: application/json'); +// signRequest expects a `{ url }` response — no method/fields/headers. echo json_encode([ - 'method' => $request->getMethod(), 'url' => (string) $request->getUri(), - 'fields' => [], - // Also set the content-type header on the request, to make sure that it is the same as the one we used to generate the signature. - // Else, the browser picks a content-type as it sees fit. - 'headers' => [ - 'content-type' => $contentType, - ], ]); diff --git a/examples/companion-digitalocean-spaces/README.md b/examples/companion-digitalocean-spaces/README.md index a9b4a9cab..f1cd992bc 100644 --- a/examples/companion-digitalocean-spaces/README.md +++ b/examples/companion-digitalocean-spaces/README.md @@ -3,7 +3,7 @@ This example uses Uppy to upload files to a [DigitalOcean Space](https://digitaloceanspaces.com/). DigitalOcean Spaces has an identical API to S3, so we can use the -[AwsS3](https://uppy.io/docs/aws-s3-multipart) plugin. We use @uppy/companion +[AwsS3](https://uppy.io/docs/aws-s3) plugin. We use @uppy/companion with a [custom `endpoint` configuration](./server.cjs#L39) that points to DigitalOcean. @@ -30,7 +30,7 @@ copy the `.env.example` file: ``` To setup the CORS settings of your Spaces bucket in accordance with -[the plugin docs](https://uppy.io/docs/aws-s3-multipart/#setting-up-your-s3-bucket), +[the plugin docs](https://uppy.io/docs/aws-s3/#setting-up-your-s3-bucket), you can use the [example XML config file](./setcors.xml) with the [`s3cmd` CLI](https://docs.digitalocean.com/products/spaces/reference/s3cmd/): diff --git a/examples/companion-digitalocean-spaces/main.js b/examples/companion-digitalocean-spaces/main.js index c1be7320c..4510daaea 100644 --- a/examples/companion-digitalocean-spaces/main.js +++ b/examples/companion-digitalocean-spaces/main.js @@ -15,4 +15,4 @@ uppy.use(Dashboard, { }) // No client side changes needed! -uppy.use(AwsS3, { companionUrl: '/companion' }) +uppy.use(AwsS3, { companionEndpoint: '/companion' })