Overview
The S3MultipartController provides three HTTP endpoints for managing the multipart upload lifecycle: creating uploads, signing part uploads, and completing uploads.
Namespace: MrEduar\S3M\Http\Controllers\S3MultipartController
Base Route: Configured in your routes file (typically /s3m)
Endpoints
POST /multipart
Create a new multipart upload session.
Request
Custom S3 bucket name (must have allow_change_bucket enabled in config)
S3 ACL visibility (private, public-read, etc.)
content_type
string
default:"application/octet-stream"
MIME type of the file being uploaded
Folder path within the bucket (must have allow_change_folder enabled in config)
Response
Success (200)
Error (500)
Unique identifier for this upload session
S3 object key (file path: folder/uuid)
AWS multipart upload ID (required for subsequent requests)
{
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"bucket": "my-bucket",
"key": "tmp/550e8400-e29b-41d4-a716-446655440000",
"uploadId": "exampleUploadId123"
}
Error message describing what went wrong
{
"error": "Unable to issue signed URL. Missing S3M config variables: region"
}
Events
Dispatches MultipartUploadCreated event with uuid, bucket, key, and uploadId.
Example
const response = await fetch('/s3m/create-multipart-upload', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': csrfToken
},
body: JSON.stringify({
content_type: 'video/mp4',
folder: 'videos',
visibility: 'private'
})
});
const { uuid, bucket, key, uploadId } = await response.json();
POST /multipart/sign
Generate a presigned URL for uploading a specific part of the file.
Request
S3 object key from the create upload response
Part number (starting from 1, max 10,000)
Upload ID from the create upload response
content_type
string
default:"application/octet-stream"
MIME type for this part
Response
Success (201)
Error (500)
Presigned URL for uploading this part (valid for 5 minutes)
HTTP headers to include in the upload requestContent type header value
{
"bucket": "my-bucket",
"key": "tmp/550e8400-e29b-41d4-a716-446655440000",
"url": "https://my-bucket.s3.amazonaws.com/tmp/550e8400...?X-Amz-Algorithm=AWS4-HMAC-SHA256&...",
"headers": {
"Content-Type": "video/mp4",
"Host": ["my-bucket.s3.amazonaws.com"]
}
}
{
"error": "Invalid upload ID"
}
Example
// Get presigned URL for part 1
const signResponse = await fetch('/s3m/create-sign-part', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': csrfToken
},
body: JSON.stringify({
key: key,
upload_id: uploadId,
part_number: 1,
content_type: 'video/mp4'
})
});
const { url, headers } = await signResponse.json();
// Upload the part using the presigned URL
const uploadResponse = await fetch(url, {
method: 'PUT',
headers: headers,
body: filePart
});
const etag = uploadResponse.headers.get('ETag');
Presigned URLs expire after 5 minutes. You must upload the part within this timeframe.
POST /multipart/complete
Complete the multipart upload by assembling all uploaded parts.
Request
S3 object key from the create upload response
Upload ID from the create upload response
Array of uploaded parts with their ETagsPart number (must match the part_number used when uploading)
ETag value from the part upload response headers
Response
Success (200)
Error (500)
Public URL of the uploaded file
{
"url": "https://my-bucket.s3.amazonaws.com/tmp/550e8400-e29b-41d4-a716-446655440000",
"key": "tmp/550e8400-e29b-41d4-a716-446655440000"
}
{
"error": "One or more of the specified parts could not be found"
}
Events
Dispatches MultipartUploadCompleted event with bucket, key, upload_id, and location.
Example
const completeResponse = await fetch('/s3m/complete-multipart-upload', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': csrfToken
},
body: JSON.stringify({
key: key,
upload_id: uploadId,
parts: [
{ PartNumber: 1, ETag: '"etag-from-part-1"' },
{ PartNumber: 2, ETag: '"etag-from-part-2"' },
{ PartNumber: 3, ETag: '"etag-from-part-3"' }
]
})
});
const { url, key: uploadedKey } = await completeResponse.json();
console.log('File uploaded to:', url);
Controller Methods
createMultipartUpload()
public function createMultipartUpload(CreateMultipartUploadRequest $request): JsonResponse
See POST /multipart endpoint documentation above.
Source: /home/daytona/workspace/source/src/Http/Controllers/S3MultipartController.php:30
signPartUpload()
public function signPartUpload(SignPartRequest $request): JsonResponse
See POST /multipart/sign endpoint documentation above.
Source: /home/daytona/workspace/source/src/Http/Controllers/S3MultipartController.php:68
completeMultipartUpload()
public function completeMultipartUpload(CompleteMultipartUploadRequest $request): JsonResponse
See POST /multipart/complete endpoint documentation above.
Source: /home/daytona/workspace/source/src/Http/Controllers/S3MultipartController.php:102
Middleware
The controller applies middleware configured in config('s3m.middleware'). By default, this includes authentication and CSRF protection.
Authorization
All endpoints require authorization through the uploadFiles gate, which receives the authenticated user and bucket name.