Отправка больших файлов с помощью сеанса отправки

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

Процесс отправки файла с помощью сеанса отправки состоит из двух этапов:

  1. Создание сеанса отправки.
  2. Отправка байтов в сеанс отправки.

Разрешения

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

Тип разрешения Разрешения (в порядке повышения привилегий)
Делегированные (рабочая или учебная учетная запись) Files.ReadWrite, Files.ReadWrite.All, Sites.ReadWrite.All
Делегированные (личная учетная запись Майкрософт) Files.ReadWrite, Files.ReadWrite.All
Для приложений Sites.ReadWrite.All

Создание сеанса отправки

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

HTTP-запрос

POST /drives/{driveId}/items/{itemId}/createUploadSession
POST /drives/{driveId}/items/{itemId}:/{fileName}:/createUploadSession
POST /groups/{groupId}/drive/items/{itemId}/createUploadSession
POST /me/drive/items/{itemId}/createUploadSession
POST /sites/{siteId}/drive/items/{itemId}/createUploadSession
POST /users/{userId}/drive/items/{itemId}/createUploadSession

Тело запроса

Тело запроса не требуется. Но вы можете указать свойство item в теле запроса, чтобы предоставить дополнительные данные об отправляемом файле.

{
  "@microsoft.graph.conflictBehavior": "rename | fail | replace",
  "description": "description",
  "fileSystemInfo": { "@odata.type": "microsoft.graph.fileSystemInfo" },
  "name": "filename.txt"
}

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

{
  "item": {
    "@microsoft.graph.conflictBehavior": "rename"
  }
}

Необязательные заголовки запросов

Имя Значение Описание
if-match etag Если указан заголовок запроса, а предоставленное значение eTag (или cTag) не совпадает с текущим значением eTag элемента, то возвращается ошибка 412 Precondition Failed.

Свойства

Свойство Тип Описание
description String Предоставляет видимое пользователю описание элемента. Чтение и запись. Только в OneDrive Personal
fileSystemInfo fileSystemInfo Сведения о файловой системе на клиенте. Чтение и запись.
name String Имя элемента (имя и расширение файла). Чтение и запись.

Запрос

В отклике на этот запрос будут представлены подробные сведения о новом экземпляре uploadSession (в том числе URL-адрес для отправки фрагментов файла).

POST /drive/root:/{item-path}:/createUploadSession
Content-Type: application/json

{
  "item": {
    "@odata.type": "microsoft.graph.driveItemUploadableProperties",
    "@microsoft.graph.conflictBehavior": "rename",
    "name": "largefile.dat"
  }
}

Ответ

В случае успешного выполнения запроса ответ будет содержать сведения о том, куда отправлять остальные запросы (в виде ресурса UploadSession).

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

HTTP/1.1 200 OK
Content-Type: application/json

{
  "uploadUrl": "https://sn3302.up.1drv.com/up/fe6987415ace7X4e1eF866337",
  "expirationDateTime": "2015-01-29T09:21:55.523Z"
}

Отправка байтов в сеанс отправки

Чтобы отправить файл или его часть, приложение отправляет запрос PUT на адрес uploadUrl, указанный в ответе для createUploadSession. Вы можете отправить файл целиком или разделить его на несколько диапазонов байтов. При этом каждый запрос должен содержать фрагмент размером не более 60 МБ.

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

Примечание. Если приложение делит файл на несколько диапазонов байтов, размер каждого из них ДОЛЖЕН быть кратным 320 КиБ (327 680 байтов). Если размер фрагментов не делится на 320 КБ без остатка, при отправке некоторых файлов возникнут ошибки.

Пример

В этом примере приложение отправляет первые 26 из 128 байтов файла.

  • Заголовок Content-Length задает размер текущего запроса.
  • Заголовок Content-Range указывает диапазон байтов для всего файла, представленного в запросе.
  • Прежде чем отправлять первый фрагмент файла, необходимо знать общий размер этого файла.
PUT https://sn3302.up.1drv.com/up/fe6987415ace7X4e1eF866337
Content-Length: 26
Content-Range: bytes 0-25/128

<bytes 0-25 of the file>

Важно! Приложение должно указывать в заголовках Content-Range всех запросов один и тот же общий размер файла. Если объявить для диапазона байтов другой размер файла, запрос не будет выполнен.

Ответ

После выполнения запроса сервер отправит в ответ код 202 Accepted, если требуется отправить дополнительные диапазоны байтов.

HTTP/1.1 202 Accepted
Content-Type: application/json

{
  "expirationDateTime": "2015-01-29T09:21:55.523Z",
  "nextExpectedRanges": ["26-"]
}

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

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

HTTP/1.1 202 Accepted
Content-Type: application/json

{
  "expirationDateTime": "2015-01-29T09:21:55.523Z",
  "nextExpectedRanges": [
  "12345-55232",
  "77829-99375"
  ]
}

Примечания

  • Свойство nextExpectedRanges не всегда указывает все отсутствующие диапазоны.
  • При успешной записи фрагментов оно возвращает следующий диапазон (например, "523-").
  • При сбоях в тех случаях, когда клиент отправляет файл, уже полученный сервером, сервер возвращает отклик HTTP 416 Requested Range Not Satisfiable. Вы можете запросить состояние отправки, чтобы получить более подробный список недостающих диапазонов.
  • В ответ на добавление заголовка авторизации при совершении вызова PUT может появиться сообщение об ошибке HTTP 401 Unauthorized. Заголовок Authorization и маркер носителя должны отправляться только при выдаче POST на первом шаге. Не следует включать их, когда совершается вызов PUT.

Завершение отправки файла

После получения последнего диапазона байтов файла сервер отправляет ответ HTTP 201 Created или HTTP 200 OK. Текст ответа также включает набор свойств по умолчанию для ресурса driveItem, представляющего полностью отправленный файл.

PUT https://sn3302.up.1drv.com/up/fe6987415ace7X4e1eF866337
Content-Length: 21
Content-Range: bytes 101-127/128

<final bytes of the file>
HTTP/1.1 201 Created
Content-Type: application/json

{
  "id": "912310013A123",
  "name": "largefile.vhd",
  "size": 128,
  "file": { }
}

Обработка конфликтов при отправке

В случае возникновения конфликта после отправки файла (например, если в ходе сеанса отправки был создан элемент с таким же именем) при отправке последнего диапазона байтов возвращается ошибка.

HTTP/1.1 409 Conflict
Content-Type: application/json

{
  "error":
  {
    "code": "upload_name_conflict",
    "message": "Another file exists with the same name as the uploaded session. You can redirect the upload session to use a new filename by calling PUT with the new metadata and @microsoft.graph.sourceUrl attribute.",
  }
}

Отмена сеанса отправки

Чтобы отменить сеанс отправки, отправьте запрос DELETE на URL-адрес отправки. При этом очищается временный файл, содержащий ранее отправленные данные. Это следует делать в тех случаях, когда отправка прерывается (например, если пользователь отменил передачу).

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

Запрос

DELETE https://sn3302.up.1drv.com/up/fe6987415ace7X4e1eF866337

Отклик

Ниже приводится пример отклика.

HTTP/1.1 204 No Content

Возобновление выполняемой отправки

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

Чтобы узнать, какие диапазоны байтов были получены ранее, приложение может запросить состояние сеанса отправки.

Пример

Получить состояние отправки можно, отправив запрос GET на адрес uploadUrl.

GET https://sn3302.up.1drv.com/up/fe6987415ace7X4e1eF86633784148bb98a1zjcUhf7b0mpUadahs

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

HTTP/1.1 200 OK
Content-Type: application/json

{
  "expirationDateTime": "2015-01-29T09:21:55.523Z",
  "nextExpectedRanges": ["12345-"]
}

Отправка оставшихся данных

Теперь, когда приложению известно, с какого момента начинать отправку, возобновите операцию, выполнив действия из раздела Отправка байтов в сеанс отправки.

Обработка ошибок отправки

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

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

Чтобы указать, что приложение применяет существующий сеанс отправки, запрос PUT должен включать свойство @microsoft.graph.sourceUrl со значением URL-адреса сеанса отправки.

PUT /me/drive/root:/{path_to_parent}
Content-Type: application/json
If-Match: {etag or ctag}

{
  "name": "largefile.vhd",
  "@microsoft.graph.conflictBehavior": "rename",
  "@microsoft.graph.sourceUrl": "{upload session URL}"
}

Примечание. В этом вызове можно использовать заголовки @microsoft.graph.conflictBehavior и if-match надлежащим образом.

HTTP-ответ

Если файл можно зафиксировать с помощью новых метаданных, возвращается ответ HTTP 201 Created или HTTP 200 OK с метаданными ресурса Item для отправленного файла.

HTTP/1.1 201 Created
Content-Type: application/json

{
  "id": "912310013A123",
  "name": "largefile.vhd",
  "size": 128,
  "file": { }
}

Рекомендации

  • Возобновляйте или повторно запускайте операции отправки, не выполненные из-за разрывов соединения или каких-либо ошибок с кодом 5xx, в том числе:
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • Используйте стратегию экспоненциального откладывания, если при возобновлении или повторной отправке возвращаются ошибки сервера с кодом 5xx.
  • При возникновении других ошибок не следует использовать эту стратегию. Вместо этого ограничьте количество повторных попыток.
  • Для устранения ошибок 404 Not Found при возобновляемой отправке начинайте всю отправку заново. Это означает, что сеанс отправки больше не существует.
  • Используйте возобновляемую отправку для файлов размером более 10 МБ (10 485 760 байтов).
  • Размер 10 МБ для диапазона байтов оптимален при использовании стабильных высокоскоростных подключений. Если используется более медленное или менее надежное подключение, то вы можете достичь оптимальных результатов, используя фрагменты меньших размеров. Рекомендуем использовать фрагменты размером 5–10 МиБ.
  • Используйте размер фрагментов, кратный 320 КиБ (327 680 байтов). В противном случае после отправки последнего диапазона байтов большого файла может произойти сбой.

Ответы с ошибками

Дополнительные сведения о возвращении ошибок см. в статье Ответы с ошибками.