Как Google втихаря ломает интернет

Oct 30, 2018 18:22

В процессе работы с Youtube, через ихний API v3, упёрся я в загрузку видео.

Я принципиально не юзаю их родные библиотеки для питона, потому что считаю их уродливыми.

Справедливо считаю, что раз API у них типа REST, с примесями JSON, то для работы мне вполне хватит классического python-requests. И вполне хватает, что характерно.

Интересное случилось на пункте videos/insert (загрузка видео).

Как правило, во всех примерах в документации есть пример для cURL. Кривой, но дающий представление, что интернет жив, протоколы соблюдаются, а для работы вполне себе хватит тривиальных утилит.

Но нет, для videos/insert про cURL сказано, цитирую,

curl samples are currently only supported for GET requests.

Вау. cURL неспособен к чему-то большему, чем GET? Чё-то новое в интернетах.

Пошел разбираться.
Влоб, как и ожидалось, ничего не работает. Самое вменяемое, что возвращает google при аплоаде файлов - "Entity too large".

Пришлось лазить в потроха googleapiclient.

Оказалось, что загрузка файлов делается в два присеста.

Присест первый - шлём метаданные видео и ждём адрес, куда лить само видео:

curl -i -X POST 'https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&alt=json&part=status%2Csnippet' --data-binary '{"status": {"privacyStatus": "private"}, "snippet": {"tags": null, "categoryId": "22", "description": "Test Description", "title": "Test Title"}}' -H "Authorization: Bearer %классический-токен" -H "content-length: 145" -H "accept-encoding: gzip, deflate" -H "accept: application/json" -H "X-Upload-Content-Length: <размер, чё мы будем потом аплоадить>" -H "X-Upload-Content-Type: <тип будущего файла>" -H "content-type: application/json"

Ответ гугля оооочень интересный:

HTTP/1.1 200 OK
X-GUploader-UploadID: AEnB2UrPv3elzZh0lab4kESHKQNblablablav_tWGa8ly_-pY4nDgyfpUDyGx7kFRRqhrcqdZjjrCdECKyvwnHqw
Location: https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&alt=json&part=status%2Csnippet&upload_id=AEnB2UrPv3elzZh0lab4kESHKQNblablablav_tWGa8ly_-pY4nDgyfpUDyGx7kFRRqhrcqdZjjrCdECKyvwnHqw
ETag: "XI7nbFXulYBIbububuR_gDh3eu1k/TObjzCHMsvnC6T38palOVn6VX7c"
Vary: Origin
Vary: X-Origin
X-Goog-Correlation-Id: JRwDbebe3zi0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Date: Tue, 30 Oct 2018 17:07:02 GMT
Content-Length: 0
Server: UploadServer
Content-Type: text/html; charset=UTF-8
Alt-Svc: quic=":443"; ma=2592000; v="44,43,39,35"

Что мы видим:

1. Гугль возвращает урл, куда надо сделать PUT-запрос. PUT-запрос делается без приключений - просто PUT, content-type, content-length. Детали тут -
https://developers.google.com/drive/api/v3/manage-uploads (google-drive api, дада, а не youtube api)
2. Гугль возвращает урл, куда надо делать PUT-запрос в хедере, а не в теле ответа. Название поля - Location.
3. Нет, у нас не редирект, как показалось по полю Location, а вполне себе "HTTP/1.1 200 OK"

Как бы, я допускаю, что загружать BLOB'ы и метаданные можно на разные адреса, поэтому, типа, урл для загрузки получаем отдельным запросом. Но, как видно, адрес у нас один и тот же. Смысл тогда в этих манипуляциях? Ну и какого хера там данные отдаются так криво? Вроде редирект (судя по Location), но нифига не редирект, ни по статус-коду, ни по логике процесса.

Гугль, блин! Протоколы писаны и для вас тоже! Блюдите их, мать вашу.
Previous post Next post
Up