На майские праздники у меня выдалась пара свободных выходных и желание немного покрутить API Yandex.Disk. Была идея сделать своего рода облачный репозиторий для slackbuild-ов. Точнее для пакетов, конечно.
Меньше слов, больше дела. Итак, я взял любимый slapt-get и попробовал сымитировать работу предстоящего приложения. Всё прошло гладко: slapt-get принял 302-е редиректы при обращении к любым файлам, как родные, а это дало повод перейти к хитрому плану по реализации редиректора.
Следующим пунктом было исследование самого yandex disk api. А оно делится на 2 части - это авторизация OAuth2 и собственно Yandex.Disk API. Наличие cpanm, естественно, развязывает руки и вместо того, чтобы вникать особо глубоко в механику работы этих вещей, достаточно взять Yandex::OAuth и Yandex::Disk и… всё бы хорошо, но пришлось в оба этих проекта делать тикеты.
В авторизацию реквест на добавление функции обновления токена (токен истекает раз в год, если есть рефреш-токен, то выписать oauth token можно автоматически). Тривиальная вещь, была принята автором без каких-либо вопросов.
Что касается модуля api yandex disk, то здесь не всё так просто. Мне хотелось иметь возможность получать метаданные по отдельно взятому файлу. Автор модуля так до сих пор и не принял PR на эту тему. Возможно, он просто забил на активность по своим старым репозиториям на github, а возможно дело связано с тем, что абуз yad api не bulk-запросами - это вроде как не комильфо.
Пока суть да дело, я завендорил оба модуля в свой проект, благо они маленькие.
Итак с модулями разобрались, дальше надо накатать PoC-тесты, посмотреть, как это работает и есть ли какие-то недостатки у это самого api. С авторизацией проблем не возникло. Всё работает как часы - однажды зарегистрировав приложение, можно далее обновлять токены либо вручную (утилитой), либо автоматически, по мере получения http-status code 401 или 403.
А что с самими api? А здесь всё интереснее некуда.
Во-первых, оно довольно сильно залимитировано. То есть можно сделать не белее пары запросов в секунду. И, внезапно, по скорости заливки файлов в само хранилище, оно тоже залимитировано. Там порядка 300-600 килобайт в секунду. При этом ещё и до(за)качка (range-запросы) не поддерживается. Бох, с ним - это оборотная сторона медали, она нас мало интересует. Хотя, конечно, невозможность быстро закачивать большие файлы сильно печалит.
И тут нужно сделать небольшое лирическое отступление. Дело в том, что файлы на YaD доступны сами по себе через api безо всякой авторизации. То есть, не надо передавать специальный заголовок, не надо делать запрос с каким-то экзотическим http-методом. Всё банально - имея ссылку, можно прям wget-ом её выкачать (лучше, конечно, взять что-то более умное, например, axel или aria2c - они более корректно работают с именами файлов). Также у YaD есть возможность "опубликовать" файл, то есть создать страничку с прямой ссылкой на него или с предложением сохранить файл к себе на (другой) yandex disk. Такая страничка нам не интересна.
И тут наступает во-вторых. Такая прямая ссылка на файл - абсолютно не перманентна. Она может в любое время измениться.
На этом мои майские исследования приостановились до августа.
И вот буквально позавчера, в связи с рабочей необходимостью, я таки решил немного поковырять этот проект снова (особой мотивации у меня нету, т.к. пока что нужды в таком облачном репозитории не предвидится, во всяком случае в ближайший год).
Соответственно, я решил выяснить сроки, в течение которых ссылка валидна. Ну хоть какие-то намёки отыскать. И вот выясняется, что ни fileinfo на отдельно взятый файл, ни список всех файлов на ya.диске с метаинформацией не содержат никаких прямых или косвенных данных о сроке жизни прямой ссылки. То есть, нету ни expires, ни какого-нибудь другого аналогичного http-заголовка или поля в получаемом json-чике, которое дало бы понять сколько времени ссылка будет валидной. Напротив, в ответе фигурирует http-заголовок Cache-Control: no-cache, что в явной форме даёт нам понять, что ссылка вообще может поменяться в любой момент. Катастрофы в самом этом факте нету, т.к. именно таким образом работает синк в самом клиентском приложении yandex.disk.
Это нас подталкивает к другому моменту - на каждый запрос на файл придётся идти в yad api, узнавать ссылку и выдавать её клиенту. А изначальный план был немного другим. Была идея предварительной генерации страниц с нужными ссылками на yad для dir index-а и генерация 302-х редиректов по факту обращения к файлам из кэшированных данных. Получается, что от такого кэширования придётся отказаться, а это, в свою очередь, ощутимо замедляет работу нашего приложения, так как (смотрим во-первых) api yad залимитировано по количеству запросов в единицу времени. В этом есть и положительная сторона - мы не реализуем кэширование как таковое, всё генерируем на лету.
Пока что продолжение следует.