Cargar archivos de gran tamaño con una sesión de carga

Espacio de nombres: microsoft.graph

Cree una sesión de carga para permitir que la aplicación cargue archivos de hasta el tamaño de archivo máximo. Una sesión de carga permite que la aplicación cargue intervalos del archivo en solicitudes API secuenciales, lo que permite que la transferencia se reanude si se interrumpe una conexión mientras la carga está en curso.

Para cargar un archivo mediante una sesión de carga hay que realizar dos pasos:

  1. Crear una sesión de carga
  2. Cargar bytes a la sesión de carga

Permisos

Se requiere uno de los siguientes permisos para llamar a esta API. Para obtener más información, incluido cómo elegir permisos, vea Permisos.

Tipo de permiso Permisos (de menos a más privilegiados)
Delegado (cuenta profesional o educativa) Files.ReadWrite, Files.ReadWrite.All, Sites.ReadWrite.All
Delegado (cuenta personal de Microsoft) Files.ReadWrite, Files.ReadWrite.All
Aplicación Sites.ReadWrite.All

Crear una sesión de carga

Para comenzar la carga de archivos de gran tamaño, su aplicación debe solicitar primero una nueva sesión de carga. Esto crea una ubicación de almacenamiento temporal donde se guardarán los bytes del archivo hasta que se cargue el archivo completo. Una vez que se haya cargado el último byte del archivo, termina la sesión de carga y el archivo final se muestra en la carpeta de destino. Como alternativa, puede aplazar la creación final del archivo en el destino, hasta que se realice explícitamente una solicitud para completar la carga al establecer la propiedad deferCommit en los argumentos de solicitud.

Solicitud HTTP

POST /drives/{driveId}/items/{itemId}/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

Cuerpo de la solicitud

No se requiere ningún cuerpo de solicitud. Sin embargo, puede especificar propiedades en el cuerpo de la solicitud proporcionando datos adicionales sobre el archivo que se está cargando y personalizando la semántica de la operación de carga.

Por ejemplo, la propiedad item permite establecer los siguientes parámetros:

{
  "@microsoft.graph.conflictBehavior": "fail (default) | replace | rename",
  "description": "description",
  "fileSize": 1234,
  "name": "filename.txt"
}

En el ejemplo siguiente se controla el comportamiento si el nombre de archivo ya está tomado y también especifica que el archivo final no se debe crear hasta que no se realice una solicitud de finalización explícita:

{
  "item": {
    "@microsoft.graph.conflictBehavior": "rename"
  },
  "deferCommit": true
}

Encabezados de solicitud opcionales

Nombre Valor Descripción
if-match etag Si se incluye este encabezado de solicitud y la eTag (o cTag) proporcionada no coincide con la eTag actual en el elemento, se devuelve una respuesta de error 412 Precondition Failed.

Parámetros

Parámetro Tipo Descripción
item driveItemUploadableProperties Datos sobre el archivo que se está cargando
deferCommit Booleano Si se establece en verdadero, la creación final del archivo en el destino requerirá una solicitud explícita. Solo en OneDrive para la Empresa.

Solicitud

La respuesta a esta solicitud ofrecerá los detalles de la uploadSession recién creada, que incluye la dirección URL utilizada para cargar las partes del archivo.

Nota: {item-path} debe contener el nombre del elemento especificado en el cuerpo de la solicitud.

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

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

Respuesta

La respuesta a esta solicitud, si se realiza correctamente, proporcionará los detalles sobre dónde deben enviarse el resto de las solicitudes como un recurso UploadSession.

Este recurso proporciona detalles sobre dónde debe cargarse el intervalo de bytes del archivo y cuándo expira la sesión de carga.

Si se especifica el parámetro fileSize y se supera la cuota disponible, se devolverá una respuesta 507 Insufficent Storage y no se creará la sesión de carga.

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

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

Cargar bytes en la sesión de carga

Para cargar el archivo, o una parte del archivo, su aplicación realiza una solicitud PUT al valor uploadUrl recibido en la respuesta createUploadSession. Puede cargar todo el archivo o dividirlo en varios intervalos de bytes, siempre y cuando el número máximo de bytes de una solicitud determinada sea inferior a 60 MiB.

Los fragmentos del archivo se deben cargar secuencialmente en orden. La carga de fragmentos sin un orden producirá un error.

Nota: Si su aplicación divide un archivo en varios intervalos de bytes, el tamaño de cada intervalo de bytes DEBE ser un múltiplo de 320 KiB (327 680 bytes). Si se usa un tamaño de fragmento que no se divide uniformemente entre 320 KiB, se producirán errores al confirmar algunos archivos.

Ejemplo

En este ejemplo, la aplicación carga los primeros 26 bytes de un archivo de 128 bytes.

  • El encabezado Content-Length especifica el tamaño de la solicitud actual.
  • El encabezado Content-Range indica el intervalo de bytes en el archivo global que representa esta solicitud.
  • La longitud total del archivo se conoce antes de cargar el primer fragmento del archivo.
PUT https://sn3302.up.1drv.com/up/fe6987415ace7X4e1eF866337
Content-Length: 26
Content-Range: bytes 0-25/128

<bytes 0-25 of the file>

Importante: Su aplicación debe asegurarse de que el tamaño total de archivo especificado en el encabezado Content-Range sea el mismo para todas las solicitudes. Si un intervalo de bytes declara un tamaño de archivo diferente, se producirá un error en la solicitud.

Respuesta

Cuando se complete la solicitud, el servidor responderá con 202 Accepted si existen más intervalos de bytes que necesitan cargarse.

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

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

Su aplicación puede usar el valor de nextExpectedRanges para determinar dónde iniciar el siguiente intervalo de bytes. Es posible que vea varios intervalos especificados, lo que indica partes del archivo que el servidor aún no ha recibido. Esto es útil si necesita reanudar una transferencia que se interrumpió y el cliente no está seguro del estado del servicio.

Siempre debe determinar el tamaño de los intervalos de bytes según los procedimientos recomendados que se indican a continuación. No suponga que nextExpectedRanges devolverá intervalos de tamaño adecuado para que se cargue un intervalo de bytes. La propiedad nextExpectedRanges indica intervalos del archivo que no se han recibido y no un patrón de cómo su aplicación debe cargar el archivo.

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

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

Comentarios

  • La propiedad nextExpectedRanges no siempre enumera todos los intervalos que faltan.
  • Cuando las escrituras de fragmento se ejecuten correctamente, devolverá el siguiente intervalo desde el que empezar (ej. "523-").
  • Cuando se produzcan errores en los que el cliente envíe un fragmento que el servidor ya ha recibido, el servidor responderá HTTP 416 Requested Range Not Satisfiable. Puede solicitar el estado de la carga para obtener una lista más detallada de los intervalos que faltan.
  • Incluir el encabezado de autorización al emitir la llamada PUT puede resultar en la respuesta HTTP 401 Unauthorized. El encabezado de autorización y el token de portador deberían enviarse únicamente al emitir el POST durante el primer paso. No debería incluirse al emitir el PUT.

Finalización de un archivo

Si deferCommit es falso o no está establecido, la carga se completará automáticamente cuando el rango de bytes final del archivo sea PUT para la dirección URL de carga.

Si deferCommit es verdadero, puede completar la carga explícitamente de dos maneras:

  • Después de que el rango de bytes final del archivo sea PUT para la dirección URL de carga, envíe una solicitud POST a la dirección URL con una carga con contenido de longitud cero (actualmente solo es compatible con OneDrive para la Empresa y SharePoint).
  • Después de que el rango de bytes final del archivo sea PUT para la dirección URL de carga, envíe una solicitud PUT de la misma forma en que administraría los errores de carga (actualmente solo es compatible con OneDrive Personal).

Una vez completada la carga, el servidor responderá a la solicitud final con HTTP 201 Created o HTTP 200 OK. El cuerpo de la respuesta también incluirá la propiedad predeterminada establecida para el driveItem que representa el archivo completado.

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": { }
}
POST https://sn3302.up.1drv.com/up/fe6987415ace7X4e1eF866337
Content-Length: 0
HTTP/1.1 201 Created
Content-Type: application/json

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

Controlar conflictos de carga

Si se produce un conflicto después de que se cargue el archivo (por ejemplo, se ha creado un elemento con el mismo nombre durante la sesión de carga), se devuelve un error cuando se carga el último intervalo de bytes.

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.",
  }
}

Cancelar la sesión de carga

Para cancelar una sesión de carga, envíe una solicitud DELETE a la dirección URL de carga. Esto limpia el archivo temporal que contiene los datos previamente cargados. Debe utilizarse en los casos en los que se anula la carga, por ejemplo, si el usuario cancela la transferencia.

Los archivos temporales y la sesión de carga que los acompaña se limpian automáticamente cuando pasa la expirationDateTime. Puede que los archivos temporales no se eliminen inmediatamente después de que haya transcurrido el tiempo de expiración.

Solicitud

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

Respuesta

En el ejemplo siguiente se muestra la respuesta.

HTTP/1.1 204 No Content

Reanudar una carga en curso

Si una solicitud de carga se desconecta o si falla antes de que se complete la solicitud, se pasan por alto todos los bytes de dicha solicitud. Esto puede ocurrir si se interrumpe la conexión entre la aplicación y el servicio. Si esto ocurre, la aplicación todavía puede reanudar la transferencia de archivos desde el fragmento completado anteriormente.

Para averiguar qué intervalos de bytes se han recibido anteriormente, su aplicación puede solicitar el estado de una sesión de carga.

Ejemplo

Consulte el estado de la carga mediante el envío de una solicitud GET a uploadUrl.

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

El servidor responderá con una lista de los intervalos de bytes que faltan por cargar y la fecha de expiración de la sesión de carga.

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

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

Cargar los datos restantes

Ahora que la aplicación sabe desde dónde iniciar la carga, reanude la carga siguiendo los pasos descritos en cargar bytes a la sesión de carga.

Controlar errores de carga

Cuando se carga el último intervalo de bytes de un archivo, es posible que se produzca un error. Esto puede deberse a que se ha superado un conflicto de nombres o una limitación de cuota. La sesión de carga se conservará hasta la hora de expiración, lo que permite a la aplicación recuperar la carga confirmando explícitamente la sesión de carga.

Para confirmar explícitamente la sesión de carga, la aplicación debe realizar una solicitud PUT con un nuevo recurso driveItem que se usará al confirmar la sesión de carga. Esta nueva solicitud debería corregir el origen del error que ha generado el error de carga original.

Para indicar que su aplicación está confirmando una sesión de carga existente, la solicitud PUT debe incluir la propiedad @microsoft.graph.sourceUrl con el valor de la URL de la sesión de carga.

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}"
}

Nota: Puede usar los encabezados @microsoft.graph.conflictBehavior y if-match como se esperaba en esta llamada.

Respuesta

Si el archivo puede confirmarse con los nuevos metadatos, se devolverá una respuesta HTTP 201 Created o HTTP 200 OK con los metadatos Item para el archivo cargado.

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

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

Procedimientos recomendados

  • Reanude o vuelva a ejecutar las cargas que fallaron debido a las interrupciones de la conexión o a los errores 5xx, como:
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • Utilice una estrategia de interrupción exponencial si se devuelve cualquier error 5xx del servidor al reanudar o volver a ejecutar solicitudes de carga.
  • Si hay otros errores, no debe utilizar una estrategia de interrupción exponencial sino limitar el número de reintentos realizados.
  • Controle los errores 404 Not Found al realizar cargas reanudables volviendo a iniciar la carga completa. Esto indica que ya no existe la sesión de carga.
  • Use transferencias de archivo reanudables para los archivos de más de 10 MiB (10.485.760 bytes).
  • Un tamaño de rango de bytes de 10 MiB para conexiones estables de alta velocidad es óptimo. Para conexiones más lentas o menos confiables, puede obtener mejores resultados con un tamaño de fragmento más pequeño. El tamaño de fragmento recomendado es de 5 a 10 MiB.
  • Use un tamaño de intervalo de bytes que sea múltiplo de 320 KiB (327 680 bytes). Si no usa un tamaño de fragmento que sea múltiplo de 320 KiB, se puede producir un error en las transferencias de archivos de gran tamaño después de que se cargue el último intervalo de bytes.

Respuestas de error

Vea el tema Respuestas de error para obtener más información sobre la manera en que se devuelven los errores.