Pull to refresh

Comments 8

Почему бы upload'ом и download'ом самих файлов не озадачить сам S3 и не гонять через сервис лишние мегабайты?

Обращаемся к S3, формируем presigned url для upload, отдаем ее фронту и ждем пока фронт сам загрузит файл.

Аналогично и с download, обращаемся к S3, формируем presigned url для download и отдаем ссылку фронту.

С download не совсем согласен. Например, мы можем хранить в S3-картинки и хотеть их отдавать прямо браузеру, который встречает тэги типа img, css-стили и т. д. И там мы не контролируем поведение "фронта" (по сути встроенных алгоритмов браузера).

Хотя в идеале надо грузить с ACL public и проксировать напрямую веб-сервером в S3 (либо настроить веб-сервер, чтобы добавлял нужные заголовки авторизации, срезал лишние заголовки и запрещал методы отличные от GET). Но всё равно приятно иметь download в бекэнде как минимум для локальной разработки, чтобы не было необходимости настраивать веб-сервер.

Крч многоступенчатый download неудобен в данном сценарии.

С upload в целом, действительно, может быть хорошая идея, но с другой стороны у нас течёт абстракция. Теперь фронт должен быть в курсе, что у нас S3-хранилище и как с ним работать. А так мы полностью абстрагируем хранилище. Можно грузить файлы хоть HTML формой без JS.

К тому же бекэнд на Rust должен иметь очень высокую производительность в пересылке бинарных потоков, вполне возможно на уровне всяких nginx. И зачем нам тогда усложнять систему.

С download решается просто, если не хочется усложнять фронт - бек отдает redirect 301 с ссылкой на объект в S3, при этом все проверки прав доступа и т.п. делается на беке, а ссылка формируется с ограниченным сроком существования (срок можно выставить любой, от секунд до месяцев, тут зависит от задачи).

С upload тоже все не сильно сложно, загрузка в s3 по presigned url тоже решается достаточно просто (обычным axios или fetch), но да, логики придется добавить и с голой html формой фокус не прокатит.

А ещё я генерирую имена файлов с помощью SHA256 (борьба с дубликатами, плюс борьба с одноимёнными файлами с разным содержимым). Как это сделать c presigned request? Считать хеш файла на фронте? Ненадёжно, фронт может быть свободно модифицирован пользователем.

А ещё может захотеться всяких других валидаций типа ограничения mime типа файла, а может даже содержимого (в моём коде можно не только считать хеш, но и что-нибудь ещё, можно даже в реальном времени модифицировать данные загружаемого файла, например, сжимать gzip) и т. п. А ещё мы можем хотеть выполнить какие-то дополнительные действия после загрузки (например, внести запись о файле в БД). Причём хотим обеспечить некоторую транзакцинность (на случай неудачи в середине загрузки, закрытия вкладки браузера или потерю соединения пользователем сразу после загрузки и т. д.).

Когда формируется presigned url, имя объекта зашивается в ссылке и именно под ним будет сохранен файл, независимо от имени файла на компе пользователя.

Вообще советую почитать документацию для начала, отпадет много вопросов (но скорее всего появятся новые)

https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html

Всё ещё нельзя генерировать имя файла на основе хеша.

А, вы считаете хеш по содержимому файла? Ну тогда ой, я бы сделал по другому, но в вашем случае вам виднее как лучше.

Быстро нагуглил, оказывается S3 умеет само считать чексуммы файлов (файл грузить на бэк не придется), потом будет достаточно просто файл переименовать.

https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObjectAttributes.html

Еще амазоновский S3 умеет в лямба-функции, которые умеют файлы преобразовывать или обогащать данными. Но скорее всего это амазон-only фишка (никогда не обращал внимания на этот функционал, мне он не нужен был никогда)

https://docs.aws.amazon.com/AmazonS3/latest/userguide/transforming-objects.html

Sign up to leave a comment.

Articles