Ich arbeite an einem Projekt, bei dem S3-URLs generiert werden, die ein anderer Benutzer zum Hochladen von Dateien in meinen S3-Bucket verwenden kann. Hier ist ein minimales Arbeitsbeispiel:AWS PHP SDK: Dateigröße für S3-Datei in vordefinierter URL begrenzen
<?php
require('aws.phar');
use Aws\S3\S3Client;
$s3client = new S3Client(...); // credentials go here
$id = uniqid(); // generate some kind of key
$command = $s3client->getCommand('PutObject', [
'ACL' => 'private',
'Body' => '',
'Bucket' => 'mybucket',
'Key' => 'tmp/' . $id]);
echo (string) $s3client->createPresignedRequest($command, '+5 minutes')->getURI();
?>
Nun, wenn ich diese Datei an einer Stelle gebracht werden, zugänglich durch das Internet, kann mein Web-Server verwendet werden, um neuen signierten Upload-URLs zu holen:
$ curl http://my.domain.com/some/page.php
https://s3.amazonaws.com/mybucket/tmp/someID?x-amz-acl=private&lots-of-aws-params...
$ curl -X PUT -d "@someFile" https://s3.amazonaws.com/mybucket/tmp/someID?x-amz-acl=private&lots-of-aws-params...
$
Diese erfolgreich lädt eine lokale Datei in meinen Bucket, damit ich in S3 damit spielen kann.
Nehmen wir an, ich mache mir keine Gedanken darüber, dass viele Leute in kurzer Zeit viele URLs generieren und viele Dateien in meinen Bucket hochladen, aber ich möchte die Größe der hochgeladenen Dateien begrenzen. Viele Ressourcen empfehlen, eine Politik zu der signierten URL Befestigung:
<?php
require('aws.phar');
use Aws\S3\S3Client;
$s3client = new S3Client(...); // credentials go here
$id = uniqid(); // generate some kind of key
$policy = [
'conditions' => [
['acl' => 'private'],
['bucket' => 'mybucket'],
['content-length-range', 0, 8*1024], // 8 KiB
['starts-with', '$key', 'tmp/']
], 'expiration' =>
(new DateTime())->modify('+5 minutes')->format(DateTime::ATOM)];
$command = $s3client->getCommand('PutObject', [
'ACL' => 'private',
'Body' => '',
'Bucket' => 'mybucket',
'Key' => 'tmp/' . $id,
'Policy' => $policy]);
echo (string) $s3client->createPresignedRequest($command, '+5 minutes')->getURI();
?>
Diese Version erzeugt URLS (ohne Angabe von Fehlern), die in gleicher Weise verwendet werden können. Ich bin nicht sicher, ob ich einige dieser Bedingungen in der Richtlinie (, bucket
, starts-with
) brauche, aber ich denke nicht, dass die Einbeziehung dieser Richtlinien die Richtlinie brechen würde.
Theoretisch sollte der Versuch, diese signierte URL zum Hochladen einer Datei größer als 8 KiB zu verwenden, dazu führen, dass S3 den Upload abbricht. Jedoch mit einer größeren Datei dieser Prüfung zeigt, dass curl
immer noch glücklich die Datei hochgeladen:
$ ls -lh file.txt
-rw-rw-r-- 1 millinon millinon 210K Jan 2 00:41 file.txt
$ curl http://my.domain.com/some/page.php
https://s3.amazonaws.com/mybucket/tmp/someOtherID?x-amz-acl=private&lots-of-aws-params...
$ curl -X PUT -d "@file.txt" https://s3.amazonaws.com/mybucket/tmp/someOtherID?x-amz-acl=private&lots-of-aws-params...
$
den Eimers Überprüfung zeigt, dass in der Tat, die große Datei hochgeladen wurde, und die Größe der Datei größer als die Politik angeblich anzeigt.
Da verschiedene Seiten zeigen verschiedene Möglichkeiten, die Politik anbringen, habe ich versucht, auch die folgenden Versionen:
'Policy' => json_encode($policy)
'Policy' => base64_encode(json_encode($policy))
jedoch URLs erzeugt mit jeder dieser Versionen von Dateien größer als die angegebene Größe erlauben hochgeladen werden.
Füge ich die Richtlinie falsch an, oder gibt es eine grundlegende Einschränkung, um Uploads auf S3 auf diese Weise zu beschränken?
Für meinen Webserver verwende ich HHVM 3.11.1 mit Version 3.14.1 des AWS SDK für PHP.
Ich weiß, dass HTML-POST bildet eine Option, aber ich bin nicht ausschließlich Browser-Targeting, das ist so keine Lösung in meinem Fall. Danke für den Vorschlag! – millinon
POST-Felder sind ein bisschen komplexer als das, was ich anstrebe - ich möchte wirklich nur eine einzige URL erzeugen, die kopiert/eingefügt werden kann in jeden Client, der HTTP PUT unterstützt. Ich mag diese Lösung jedoch sehr - Clients, die HTTP PUT unterstützen, werden wahrscheinlich auch POST-Felder unterstützen, daher werde ich mich bemühen, dies als eine Methode zum Hochladen bereitzustellen. – millinon