Каждый день сотрудники техподдержки Selectel решают задачи клиентов. Что-то не подключается, что-то вдруг удалилось или потерялось. Для ответа на часть тикетов достаточно скинуть инструкцию из базы знаний, но некоторые становятся настоящими техническими квестами.

Сегодня мы решили разобрать несколько из них. В этой подборке все они связаны с работой облачного объектного хранилища. Сейчас в Selectel миграционные каникулы — можно 30 дней не платить за запросы и хранение данных.

Ответы на одну из задач убрали в «спойлеры» — проверьте себя, сможете ли вы сами найти решение на основе «дано». Если вам понравится такой формат текстов, пишите в комментах или голосуйте в опросе, — сделаем еще. А пока — смотрите под кат.

Задача 1. Нужно создать ссылку одноразовой загрузки через API


Дано: Обратившийся в техподдержку клиент развивает собственную образовательную платформу, где нужно сдавать домашние задания. Задача состояла в том, чтобы сформировать уникальную ссылку для загрузки файлов, которая срабатывала бы единожды, могла зафиксировать время загрузки, имела «срок годности», была доступна по паролю.

Создать такую ссылку можно запросом к API. Клиент воспользовался инструкцией из базы знаний.

Пример запроса для приватного контейнера ed_test_private (все названия, секреты и номера контейнера скрыты или изменены):

==========================================
curl -i -XPUT https://api.selcdn.ru/v1/SEL_*****/ed_test_private/ \
-H "X-Auth-Token: $token" \
-H "Content-Type: x-storage/sendmefile+timepostfix" \
-H "X-Object-Meta-Sendmefile-Max-Size: 52428800" \
-H "X-Object-Meta-Sendmefile-Expire: 14400" \
-H "X-Object-Meta-Sendmefile-Secret: $secret" \
-d "Пояснительный текст для страницы загрузки"
==========================================

Полученный ответ
==========================================
curl -i -XPUT api.selcdn.ru/v1/SEL_ххххх/ed_test_private -H «X-Auth-Token: $token» -H «Content-Type: x-storage/sendmefile+timepostfix» -H «X-Object-Meta-Sendmefile-Max-Size: 52428800» -H «X-Object-Meta-Sendmefile-Expire: 14400» -H «X-Object-Meta-Sendmefile-Secret: $secret» -d «Пояснительный текст для страницы загрузки»
HTTP/2 202
access-control-allow-origin: *
access-control-expose-headers: X-Backend-Timestamp, Etag, Last-Modified, X-Object-Manifest, X-Timestamp
content-length: 76
content-type: text/html
date: Thu, 20 Jan 2022 13:45:46 GMT

Accepted

The request is accepted for processing.



Клиент хочет понять, где найти ссылку для загрузки и одноразовый пароль.



Первое, что посоветовала скорректировать сотрудница техподдержки, — это указать имя получаемой ссылки — например, upload или иное:

https://api.selcdn.ru/v1/SEL_*****/ed_test_private/upload

Далее важно понимать, что ссылка на загрузку файла, которой может воспользоваться сторонний юзер (в нашем случае — клиент образовательной платформы), не отдается в ответе на запрос. Но это и не требуется: ссылка на загрузку всегда имеет один и тот же формат, меняется только ее название, которое задается при создании ссылки.

То есть, если вы создаете ссылку с названием upload (https://api.selcdn.ru/v1/SEL_*****/ed_test_private/upload), то впоследствии к ней можно обращаться по URL: https://******.selcdn.ru/ed_test_private/upload, где:

  • ******.selcdn.ru — базовый домен хранилища аккаунта (его можно посмотреть в панели управления Selectel),
  • ed_test_private — имя контейнера,
  • upload — заданное имя ссылки.

Пароль для ссылки пользователь задает самостоятельно с помощью указания в параметре X-Object-Meta-Sendmefile-Secret sha1-хэша пароля, который пользователь хочет установить для загрузки.

Встроенной генерации пароля в API нет, его необходимо создать отдельно, а затем сгенерировать хэш. Пример генерации хэша с помощью Python:

 import hashlib

# password
password = "12345"

# concatenate password + location and encode it
encoded_pass_loc = (password).encode('utf-8')

# generate sha1-hash
hash_object = hashlib.sha1(encoded_pass_loc)

# convert sha1-hash to hexadecimal digits
link_key = hash_object.hexdigest()

# show calculated value
print(link_key) 

Для генерации хэша также можно использовать специализированную утилиту или генератор — например, sha1sum для Linux или Katvin. Хэш нужно передать в запросе API.

Еще раз: ни один из параметров не возвращается в ответе от хранилища напрямую, в этом нет смысла, потому что параметры устанавливаются пользователем.

Также в ходе тестирования запросов сотрудница техподдержки обнаружила, что один из параметров -H «X-Object-Meta-Sendmefile-Expire: ***** » (определяет время жизни ссылки) не работал ожидаемым образом. После обращения в профильный отдел выяснили, что данный параметр следует заменить на X-Delete-After, указав число секунд действия ссылки. Корректно работающий параметр добавили в документацию API.

Итак, c учетом всех корректировок запрос к API будет выглядеть следующим образом:

curl -i -XPUT https://api.selcdn.ru/v1/SEL_xxxxx/ed_test_private/upload1 \
-H "X-Auth-Token: $token" \
-H "Content-Type: x-storage/sendmefile+timepostfix" \
-H "X-Object-Meta-Sendmefile-Max-Size: 52428800" \
-H "X-Delete-After: 14400" \
-H "X-Object-Meta-Sendmefile-Secret: $secret" \

Ссылка, созданная с помощью запроса, будет выглядеть так:

https://хххххх.selcdn.ru/ed_test_private/upload1

После выполнения запроса к API нужно открыть эту ссылку в браузере и ввести сгенерированный ранее пароль.

Ссылке можно придать большую избирательность, что и сделал клиент облачного хранилища. Например, чтобы ограничить число загрузок по ссылке до одной, нужно добавить параметр x-storage/sendmefile+inplace:

 -H "Content-Type: x-storage/sendmefile+inplace" \ 

Тогда после загрузки файла по https://******.selcdn.ru/ed_test_private/upload3 ссылка будет заменена файлом. Повторно воспользоваться ссылкой не получится.

Также есть параметр -H «X-Object-Meta-Sendmefile-Max-Size: ******** „ — он накладывает ограничение на максимальный размер загружаемого файла. А параметр -H “X-Delete-After: ***** „, как уже было сказано выше, определяет время жизни ссылки.

Подробная инструкция по составлению запроса к API есть в базе знаний Selectel. Подобная документация есть у большинства провайдеров, которые предлагают услуги объектного хранилища, и ее стоит изучить перед генерацией URL.

Создание ссылок для загрузки — удобный функционал, который достаточно легко реализовать через взаимодействие с API. Его можно использовать для предоставления доступа к хранилищу разным пользователям, для загрузки пользовательского контента на сайты, для организации быстрого хранения резервных копий.

Задачу клиента сотрудница техподдержки решила корректировкой его скрипта. Это выходит за рамки техподдержки, но сотрудники техпода всегда помогут, если у них есть время и знание темы запроса.

Задача 2. Загрузка файлов в контейнер с помощью API Swift и PHP


Использование собственных скриптов для работы с объектным хранилищем — привычная для многих история. Немало клиентов пользуются возможностями API, но не всегда получают в выводе то, что хотят. Так случилось и в следующем кейсе.

Дано: Клиент с помощью cURL PHP выполняет запрос на отправку файла в контейнер объектного хранилища. Но после отправки и попадания в контейнер файл перестает работать. Например, клиент отправляет видео mp4, которое весит 10 Мб. Оно приходит в контейнер и весит столько же, но после скачивания его нельзя воспроизвести. Так происходит с любым файлом и форматом, будь то аудио, видео, изображение.

Как выглядел код:

$FILE = curl_file_create(‘тут путь до файла на сервере клиента’);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.selcdn.ru/v1/SEL_******/media/файл’);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, [$FILE]);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["X-Auth-Token: $TOKEN"]);
$season_data = curl_exec($ch);
curl_close($ch); 



Для начала попробуем разобраться с файлом, который отдается хранилищем Selectel, — проверим его заголовки.

Сотрудник техподдержки запросил у клиента ссылку на файл, который перестал воспроизводиться, и проверил его через curl -I. Данный запрос позволяет получить ответ сервера и заголовки без тела файла.

Вот такое изображение с мишкой не проходило тесты.

В итоге запрос будет выглядеть так:

curl -I https://123456.selcdn.ru/media/file_731151773283.jpg
HTTP/2 200 
accept-ranges: bytes
access-control-allow-origin: *
access-control-expose-headers: Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, Pragma, Etag, X-Timestamp, X-Trans-Id, X-Openstack-Request-Id, Content-Length, Accept-Ranges
content-length: 213422
content-type: multipart/form-data; boundary=------------------------ce35dac0d8c70b46
etag: 7d23c8ed7cb5f457ce4db7fd0ca1d947
last-modified: Thu, 10 Feb 2022 15:33:58 GMT
x-timestamp: 1644507237.27371
x-trans-id: 12а3456b7c8999d3
date: Thu, 10 Feb 2022 16:11:40 GMT
age: 0 

Видите проблему? Проверьте себя, нажав на спойлер.
Проверяем заголовки файла. В поле content-type записаны некорректные данные “multipart/form-data; boundary=------------------------ce35dac0d8c70b46», хотя должно быть указано image/jpg, если загружалось изображение. Рабочие и нерабочие файлы отличались именно этим полем.

После указания на некорректный заголовок клиент занялся исправлением скрипта.

Посмотреть заголовки файлов можно через веб-интерфейс, уточнив, все ли заголовки выглядят правильно и консистентно. Заголовки назначаются в момент загрузки объекта. Если нужный заголовок отсутствует у уже загруженного файла, его можно добавить при помощи API.



Если ранее вы не пользовались объектным хранилищем S3 в Selectel, обратите внимание на миграционные каникулы. Они позволят не оплачивать запросы и хранение в течение 30 дней с момента одобрения заявки. Этот период полностью покрывает время на подготовительные работы и снижает нагрузку на бизнес. Заполнить заявку можно по ссылке.

Комментарии (0)