О загрузке мультимедиа

Google Mirror API позволяет вставлять вложение при создании нового элемента временной шкалы.

Параметры загрузки

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

  • Максимальный размер загружаемого файла : максимальный объем данных, которые вы можете сохранить с помощью этого метода.
  • Допустимые MIME-типы носителей : типы двоичных данных, которые можно хранить с помощью этого метода.

Вы можете отправлять запросы на загрузку любым из следующих способов. Укажите метод, который вы используете, с параметром запроса uploadType .

  • Простая загрузка : uploadType=media . Для быстрой передачи небольших файлов, например, 5 МБ или меньше.
  • Многокомпонентная загрузка : uploadType=multipart . Для быстрой передачи небольших файлов и метаданных; передает файл вместе с метаданными, которые его описывают, в одном запросе.
  • Возобновляемая загрузка : uploadType=resumable . Для надежной передачи, особенно важно для больших файлов. В этом методе вы используете запрос, инициирующий сеанс, который при желании может включать метаданные. Это хорошая стратегия для большинства приложений, поскольку она также работает для файлов меньшего размера за счет одного дополнительного HTTP-запроса на загрузку.

Когда вы загружаете медиа, вы используете специальный URI. На самом деле методы, поддерживающие загрузку мультимедиа, имеют две конечные точки URI:

  • URI /upload для мультимедиа. Формат конечной точки загрузки — стандартный URI ресурса с префиксом «/upload». Используйте этот URI при передаче самих мультимедийных данных.

    Пример: POST /upload/mirror/v1/timeline

  • Стандартный URI ресурса для метаданных. Если ресурс содержит какие-либо поля данных, эти поля используются для хранения метаданных, описывающих загруженный файл. Вы можете использовать этот URI при создании или обновлении значений метаданных.

    Пример: POST /mirror/v1/timeline

Простая загрузка

Самый простой способ загрузить файл — сделать простой запрос на загрузку. Этот вариант является хорошим выбором, когда:

  • Файл достаточно мал, чтобы загрузить его снова целиком в случае сбоя соединения.
  • Нет метаданных для отправки. Это может быть верно, если вы планируете отправлять метаданные для этого ресурса в отдельном запросе или если метаданные не поддерживаются или не доступны.

Чтобы использовать простую загрузку, сделайте запрос POST или PUT к URI /upload метода и добавьте параметр запроса uploadType=media . Например:

POST https://www.googleapis.com/upload/mirror/v1/timeline?uploadType=media

Заголовки HTTP, используемые при отправке простого запроса на загрузку, включают:

  • Content-Type . Установите один из допустимых типов данных мультимедиа для загрузки метода, указанных в справочнике по API .
  • Content-Length . Установите количество байтов, которые вы загружаете. Не требуется, если вы используете кодирование передачи по частям .

Пример: простая загрузка

В следующем примере показано использование простого запроса на загрузку для Google Mirror API.

POST /upload/mirror/v1/timeline?uploadType=media HTTP/1.1
Host: www.googleapis.com
Content-Type: image/jpeg
Content-Length: number_of_bytes_in_file
Authorization: Bearer your_auth_token

JPEG data

Если запрос выполнен успешно, сервер возвращает код состояния HTTP 200 OK вместе со всеми метаданными:

HTTP/1.1 200
Content-Type: application/json

{
  "text": "Hello world!"
}

Многокомпонентная загрузка

Если у вас есть метаданные, которые вы хотите отправить вместе с данными для загрузки, вы можете сделать один multipart/related запрос. Это хороший выбор, если данные, которые вы отправляете, достаточно малы для повторной загрузки в полном объеме в случае сбоя подключения.

Чтобы использовать многокомпонентную загрузку, сделайте запрос POST или PUT к URI /upload метода и добавьте параметр запроса uploadType=multipart , например:

POST https://www.googleapis.com/upload/mirror/v1/timeline?uploadType=multipart

Заголовки HTTP верхнего уровня, которые следует использовать при выполнении многокомпонентного запроса на загрузку, включают:

  • Content-Type . Установите значение multipart/related и включите граничную строку, которую вы используете для идентификации частей запроса.
  • Content-Length . Установите общее количество байтов в теле запроса. Размер мультимедийной части запроса должен быть меньше максимального размера файла, указанного для этого метода.

Тело запроса отформатировано как multipart/related тип контента [ RFC2387 ] и содержит ровно две части. Части идентифицируются граничной строкой, а за последней граничной строкой следуют два дефиса.

Каждая часть составного запроса нуждается в дополнительном заголовке Content-Type :

  1. Часть метаданных: должна быть первой, а Content-Type должен соответствовать одному из принятых форматов метаданных.
  2. Медиа-часть: должна быть второй, а Content-Type должен соответствовать одному из принятых медиа-типов MIME метода.

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

Примечание. Чтобы создать или обновить только часть метаданных без загрузки связанных данных, просто отправьте запрос POST или PUT на стандартную конечную точку ресурса: https://www.googleapis.com/mirror/v1/timeline .

Пример: многокомпонентная загрузка

В приведенном ниже примере показан составной запрос на загрузку для Google Mirror API.

POST /upload/mirror/v1/timeline?uploadType=multipart HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer your_auth_token
Content-Type: multipart/related; boundary=foo_bar_baz
Content-Length: number_of_bytes_in_entire_request_body

--foo_bar_baz
Content-Type: application/json; charset=UTF-8

{
  "text": "Hello world!"
}

--foo_bar_baz
Content-Type: image/jpeg

JPEG data
--foo_bar_baz--

Если запрос выполнен успешно, сервер возвращает код состояния HTTP 200 OK вместе со всеми метаданными:

HTTP/1.1 200
Content-Type: application/json

{
  "text": "Hello world!"
}

Возобновляемая загрузка

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

Шаги для использования возобновляемой загрузки включают в себя:

  1. Начать возобновляемый сеанс . Сделайте первоначальный запрос к URI загрузки, который включает метаданные, если таковые имеются.
  2. Сохраните URI возобновляемого сеанса . Сохраните URI сеанса, возвращенный в ответе на первоначальный запрос; вы будете использовать его для оставшихся запросов в этом сеансе.
  3. Загрузите файл . Отправьте файл мультимедиа на URI возобновляемого сеанса.

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

Примечание. Срок действия URI загрузки истекает через неделю.

Шаг 1. Начните возобновляемый сеанс

Чтобы инициировать возобновляемую загрузку, сделайте запрос POST или PUT к URI /upload метода и добавьте параметр запроса uploadType=resumable , например:

POST https://www.googleapis.com/upload/mirror/v1/timeline?uploadType=resumable

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

Используйте следующие заголовки HTTP с первоначальным запросом:

  • X-Upload-Content-Type . Установите тип media MIME для данных загрузки, которые будут передаваться в последующих запросах.
  • X-Upload-Content-Length . Установите количество байтов загружаемых данных, которые будут переданы в последующих запросах. Если длина неизвестна во время этого запроса, вы можете опустить этот заголовок.
  • При предоставлении метаданных: Content-Type . Установите в соответствии с типом данных метаданных.
  • Content-Length . Установите количество байтов, предоставленное в теле этого первоначального запроса. Не требуется, если вы используете кодирование передачи по частям .

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

Пример: возобновляемый запрос на инициацию сеанса

В следующем примере показано, как инициировать возобновляемый сеанс для Google Mirror API.

POST /upload/mirror/v1/timeline?uploadType=resumable HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer your_auth_token
Content-Length: 38
Content-Type: application/json; charset=UTF-8
X-Upload-Content-Type: image/jpeg
X-Upload-Content-Length: 2000000

{
  "text": "Hello world!"
}

Примечание. Для исходного возобновляемого запроса на обновление без метаданных оставьте тело запроса пустым и установите для заголовка Content-Length значение 0 .

В следующем разделе описывается, как обрабатывать ответ.

Шаг 2. Сохраните URI возобновляемого сеанса.

Если запрос на инициацию сеанса выполнен успешно, сервер API отвечает кодом состояния HTTP 200 OK . Кроме того, он предоставляет заголовок Location , который указывает URI вашего возобновляемого сеанса. Заголовок Location , показанный в приведенном ниже примере, включает часть параметра запроса upload_id , которая дает уникальный идентификатор загрузки для использования в этом сеансе.

Пример: возобновляемый ответ на инициацию сеанса

Вот ответ на запрос на шаге 1:

HTTP/1.1 200 OK
Location: https://www.googleapis.com/upload/mirror/v1/timeline?uploadType=resumable&upload_id=xa298sd_sdlkj2
Content-Length: 0

Значение заголовка Location , как показано в приведенном выше примере ответа, — это URI сеанса, который вы будете использовать в качестве конечной точки HTTP для выполнения фактической загрузки файла или запроса статуса загрузки.

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

Шаг 3: Загрузите файл

Чтобы загрузить файл, отправьте запрос PUT на URI загрузки, который вы получили на предыдущем шаге. Формат запроса на загрузку:

PUT session_uri

Заголовки HTTP, используемые при выполнении запросов на возобновляемую загрузку файлов, включают Content-Length . Установите это значение на количество байтов, которые вы загружаете в этом запросе, что обычно соответствует размеру загружаемого файла.

Пример: запрос на возобновляемую загрузку файла

Вот возобновляемый запрос на загрузку всего 2 000 000-байтового файла JPEG для текущего примера.

PUT https://www.googleapis.com/upload/mirror/v1/timeline?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1
Content-Length: 2000000
Content-Type: image/jpeg

bytes 0-1999999

Если запрос выполнен успешно, сервер отвечает HTTP 201 Created вместе со всеми метаданными, связанными с этим ресурсом. Если бы первоначальный запрос возобновляемого сеанса был PUT для обновления существующего ресурса, успешный ответ был бы 200 OK вместе со всеми метаданными, связанными с этим ресурсом.

Если запрос на загрузку прерывается или вы получаете сообщение HTTP 503 Service Unavailable или любой другой ответ 5xx от сервера, следуйте процедуре, описанной в возобновлении прерванной загрузки .


Загрузка файла кусками

С помощью возобновляемых загрузок вы можете разбить файл на фрагменты и отправить серию запросов на последовательную загрузку каждого фрагмента. Этот подход не является предпочтительным, так как дополнительные запросы связаны с затратами на производительность, и, как правило, в этом нет необходимости. Однако вам может понадобиться использовать фрагментацию, чтобы уменьшить объем данных, передаваемых в любом отдельном запросе. Это полезно, когда существует фиксированное ограничение по времени для отдельных запросов, как это верно для определенных классов запросов Google App Engine. Он также позволяет вам делать такие вещи, как индикация хода загрузки для устаревших браузеров, которые по умолчанию не поддерживают ход загрузки.


Возобновить прерванную загрузку

Если запрос на загрузку завершается до получения ответа или если вы получаете ответ HTTP 503 Service Unavailable от сервера, вам необходимо возобновить прерванную загрузку. Сделать это:

  1. Статус запроса. Запросите текущий статус загрузки, отправив пустой запрос PUT на URI загрузки. Для этого запроса заголовки HTTP должны включать заголовок Content-Range , указывающий, что текущая позиция в файле неизвестна. Например, установите для параметра Content-Range значение */2000000 , если общая длина файла составляет 2 000 000. Если вы не знаете полный размер файла, установите для параметра Content-Range значение */* .

    Примечание. Вы можете запрашивать статус между фрагментами, а не только в том случае, если загрузка прервана. Это полезно, например, если вы хотите показать индикаторы выполнения загрузки для устаревших браузеров.

  2. Получить количество загруженных байтов. Обработайте ответ на запрос состояния. Сервер использует заголовок Range в своем ответе, чтобы указать, какие байты он уже получил. Например, заголовок Range 0-299999 указывает, что первые 300 000 байт файла были получены.
  3. Загрузите оставшиеся данные. Наконец, теперь, когда вы знаете, где возобновить запрос, отправьте оставшиеся данные или текущий фрагмент. Обратите внимание, что вам нужно обрабатывать оставшиеся данные как отдельный блок в любом случае, поэтому вам нужно отправить заголовок Content-Range при возобновлении загрузки.
Пример: возобновление прерванной загрузки

1) Запросите статус загрузки.

Следующий запрос использует заголовок Content-Range , чтобы указать, что текущая позиция в файле размером 2 000 000 байт неизвестна.

PUT {session_uri} HTTP/1.1
Content-Length: 0
Content-Range: bytes */2000000

2) Извлеките количество загруженных байтов из ответа.

Ответ сервера использует заголовок Range , чтобы указать, что он уже получил первые 43 байта файла. Используйте верхнее значение заголовка Range , чтобы определить, с чего начать возобновленную загрузку.

HTTP/1.1 308 Resume Incomplete
Content-Length: 0
Range: 0-42

Примечание. Возможно, ответ статуса может быть 201 Created или 200 OK , если загрузка завершена. Это могло произойти, если соединение прервалось после загрузки всех байтов, но до того, как клиент получил ответ от сервера.

3) Возобновить загрузку с того места, где она была прервана.

Следующий запрос возобновляет загрузку, отправляя оставшиеся байты файла, начиная с байта 43.

PUT {session_uri} HTTP/1.1
Content-Length: 1999957
Content-Range: bytes 43-1999999/2000000

bytes 43-1999999

Лучшие практики

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

  • Возобновите или повторите загрузку, которая не удалась из-за прерывания соединения или любых ошибок 5xx , в том числе:
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • Используйте экспоненциальную стратегию отсрочки , если какая-либо ошибка сервера 5xx возвращается при возобновлении или повторной попытке загрузки. Эти ошибки могут возникать, если сервер перегружен. Экспоненциальная отсрочка может помочь облегчить подобные проблемы в периоды большого объема запросов или интенсивного сетевого трафика.
  • Другие типы запросов не должны обрабатываться с экспоненциальной задержкой, но вы все равно можете повторить некоторые из них. При повторных попытках этих запросов ограничьте количество повторных попыток. Например, ваш код может ограничиться десятью или менее повторными попытками, прежде чем будет сообщено об ошибке.
  • Обработайте ошибки 404 Not Found и 410 Gone при возобновляемой загрузке, начав всю загрузку с самого начала.

Экспоненциальная отсрочка

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

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

Алгоритм реализации простой экспоненциальной отсрочки выглядит следующим образом:

  1. Сделайте запрос к API.
  2. Получите ответ HTTP 503 , который указывает, что вы должны повторить запрос.
  3. Подождите 1 секунду + random_number_milliseconds и повторите запрос.
  4. Получите ответ HTTP 503 , который указывает, что вы должны повторить запрос.
  5. Подождите 2 секунды + random_number_milliseconds и повторите запрос.
  6. Получите ответ HTTP 503 , который указывает, что вы должны повторить запрос.
  7. Подождите 4 секунды + random_number_milliseconds и повторите запрос.
  8. Получите ответ HTTP 503 , который указывает, что вы должны повторить запрос.
  9. Подождите 8 секунд + random_number_milliseconds и повторите запрос.
  10. Получите ответ HTTP 503 , который указывает, что вы должны повторить запрос.
  11. Подождите 16 секунд + random_number_milliseconds и повторите запрос.
  12. Останавливаться. Сообщите или зарегистрируйте ошибку.

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

Примечание. Время ожидания всегда равно (2 ^ n) + random_number_milliseconds, где n — монотонно возрастающее целое число, первоначально определенное как 0. Целое число n увеличивается на 1 для каждой итерации (каждого запроса).

Алгоритм настроен на завершение, когда n равно 5. Этот предел предотвращает бесконечные повторные попытки клиентов и приводит к общей задержке около 32 секунд, прежде чем запрос будет признан «неисправимой ошибкой». Большее максимальное количество попыток допустимо, особенно если выполняется длительная загрузка; просто не забудьте ограничить задержку повтора чем-то разумным, скажем, менее одной минуты.

Руководства по клиентской библиотеке API