Pracuję nad projektem obejmującym generowanie adresów URL S3, które ktoś inny może użyć do przesłania plików do mojego zasobnika S3. Oto minimalne przykład praca:AWS PHP SDK: Limit rozmiaru wysyłanego pliku S3 w adresie URL oznaczonym
<?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();
?>
Teraz, jeśli mogę umieścić ten plik w miejscu dostępnym przez internet, mój serwer WWW może być wykorzystywane do pobierania nowych podpisane URL Dodano:
$ 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...
$
Ten pomyślnie przesyła lokalny plik do mojego zasobnika, dzięki czemu mogę grać z nim w S3.
Załóżmy, że nie martwię się zbytnio o ludzi generujących wiele adresów URL i przesyłanie wielu plików do mojego zasobnika w krótkim czasie, ale chciałbym ograniczyć rozmiar przesyłanych plików. Wiele zasobów proponujemy dołączenie politykę podpisanego URL:
<?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();
?>
Ta wersja generuje adresy URL (bez wskazania błędów), które mogą być używane w ten sam sposób. Nie jestem pewien, czy potrzebuję niektórych z tych warunków w polityce (acl
, bucket
, starts-with
), ale nie sądzę, że włączenie ich złamałoby zasady.
Teoretycznie próba użycia tego podpisanego adresu URL do przesłania pliku większego niż 8 KiB powinna spowodować przerwanie przesyłania przez S3. Jednak badanie to z większego pliku pokazuje, że curl
nadal szczęśliwie przesyła plik:
$ 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...
$
Sprawdzanie wiadro pokazuje, że rzeczywiście duży plik został przesłany, a wielkość pliku jest większa niż polityka rzekomo wskazuje.
Ponieważ różne strony pokazują różne sposoby mocowania politykę, Próbowałem również następujących wersjach:
'Policy' => json_encode($policy)
'Policy' => base64_encode(json_encode($policy))
Jednak adresy generowane z dowolnego z tych wersji pozwalają pliki większe niż określony rozmiar, aby być przesłany.
Czy niepoprawnie załączyłem politykę, czy też istnieje zasadnicze ograniczenie w ograniczaniu przesyłania do S3 w ten sposób?
Dla mojego serwera WWW używam HHVM 3.11.1 z wersją 3.14.1 pakietu SDK AWS dla PHP.
wiem, że formularze HTML POST są możliwe, ale nie jestem wyłącznie kierowania przeglądarek, tak że nie jest to rozwiązanie w moim przypadku. Dzieki za sugestie! – millinon
Pola POST są nieco bardziej złożone niż to, do czego dążę - naprawdę chcę wygenerować pojedynczy adres URL, który można skopiować/wkleić do dowolnego klienta obsługującego protokół HTTP PUT. Bardzo lubię to rozwiązanie - klienci obsługujący HTTP PUT prawdopodobnie będą również obsługiwać pola POST, więc postaram się zapewnić to jako metodę przesyłania. – millinon