Executar uploads retomáveis

Visão geral

Nesta página, descrevemos como fazer uma solicitação de upload retomável nas APIs JSON e XML do Cloud Storage. Esse protocolo permite retomar uma operação de upload quando uma falha de comunicação interrompe o fluxo de dados.

Para informações sobre o uso de uploads retomáveis na CLI do Google Cloud e nas bibliotecas de cliente, consulte Como ferramentas e APIs usam uploads retomáveis.

Funções exigidas

Para ter as permissões necessárias para executar um upload retomável, peça ao administrador para conceder a você um dos seguintes papéis:

  • Para uploads que incluem um bloqueio de retenção de objetos, peça ao administrador para conceder a você o papel de IAM de Administrador de objetos do Storage (roles/storage.objectAdmin) para o bucket.

  • Para todos os outros casos, peça ao administrador para conceder a você o papel do IAM de Usuário do objeto do Storage (roles/storage.objectUser) para o bucket.

Esses papéis predefinidos contêm as permissões necessárias para fazer upload de um objeto em um bucket para os respectivos casos. Para conferir as permissões exatas necessárias, expanda a seção Permissões necessárias:

Permissões necessárias

  • storage.objects.create
  • storage.objects.delete
    • Essa permissão é necessária apenas para uploads que substituem um objeto já existente.
  • storage.objects.setRetention
    • Essa permissão é necessária apenas para uploads que incluem um bloqueio de retenção de objetos.

Também é possível conseguir essas permissões com outros papéis predefinidos ou personalizados.

Para informações sobre como conceder papéis nos buckets, consulte Usar o IAM com buckets.

Iniciar uma sessão de upload retomável

Para iniciar uma sessão de upload retomável, siga estas etapas, siga estas etapas:

API JSON

  1. Ter a CLI gcloud instalada e inicializada, o que permite gerar um token de acesso para o cabeçalho Authorization.

  2. Opcionalmente, crie um arquivo JSON com os metadados que você quer definir no objeto que está enviando. Por exemplo, o arquivo JSON a seguir define os metadados contentType do objeto que você quer enviar para image/png:

    {
        "contentType": "image/png"
    }
  3. Use cURL para chamar a API JSON com uma solicitação de POST Objeto:

    curl -i -X POST --data-binary @METADATA_LOCATION \
        -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Type: application/json" \
        -H "Content-Length: INITIAL_REQUEST_LENGTH" \
        "https://storage.googleapis.com/upload/storage/v1/b/BUCKET_NAME/o?uploadType=resumable&name=OBJECT_NAME"

    Em que:

    • METADATA_LOCATION é o caminho local do arquivo JSON que contém os metadados opcionais especificados na etapa anterior. Se você não estiver incluindo um arquivo de metadados, exclua esse caminho, junto com --data-binary @ e o cabeçalho Content-Type.
    • INITIAL_REQUEST_LENGTH é o número de bytes no corpo dessa solicitação inicial, por exemplo, 79.
    • BUCKET_NAME é o nome do bucket de upload do objeto. Por exemplo, my-bucket.
    • OBJECT_NAME é o nome codificado por URL que você quer dar ao objeto. Por exemplo, pets/dog.png, codificado em URL como pets%2Fdog.png. Isso não será necessário se você tiver incluído um name no arquivo de metadados do objeto na Etapa 2.

    Se você tiver ativado o Compartilhamento de recursos entre origens, também deverá incluir um cabeçalho Origin nessa solicitação de upload e nas próximas.

    Entre os cabeçalhos opcionais que podem ser adicionados à solicitação estão X-Upload-Content-Type e X-Upload-Content-Length.

    Se a operação for bem-sucedida, a resposta incluirá um código de status 200.

  4. Salve o URI da sessão retomável fornecido no cabeçalho Location da resposta à sua solicitação de objeto POST.

    Esse URI é usado em solicitações subsequentes para fazer upload dos dados do objeto.

API XML

  1. Ter a CLI gcloud instalada e inicializada, o que permite gerar um token de acesso para o cabeçalho Authorization.

  2. Use cURL para chamar a API XML com uma solicitação de objeto POST com um corpo vazio:

    curl -i -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Length: 0" \
        -H "Content-Type: OBJECT_CONTENT_TYPE" \
        -H "x-goog-resumable: start" \
        "https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME"

    Em que:

    • OBJECT_CONTENT_TYPE é o tipo de conteúdo do objeto. Por exemplo, image/png. Se você não especificar um tipo de conteúdo, o sistema do Cloud Storage definirá os metadados Content-Type do objeto como application/octet-stream.
    • BUCKET_NAME é o nome do bucket em que você fará o upload do objeto. Por exemplo, my-bucket.
    • OBJECT_NAME é o nome codificado por URL que você quer dar ao objeto. Por exemplo, pets/dog.png, codificado em URL como pets%2Fdog.png.

    Se você tiver ativado o Compartilhamento de recursos entre origens, também deverá incluir um cabeçalho Origin nessa solicitação de upload e nas próximas.

    Se a operação for bem-sucedida, a resposta incluirá uma mensagem de status 201.

  3. Salve o URI da sessão retomável fornecido no cabeçalho Location da resposta à sua solicitação de objeto POST.

    Esse URI é usado em solicitações subsequentes para fazer upload dos dados do objeto.

upload dos dados

Depois de iniciar um upload retomável, há duas maneiras de fazer upload dos dados do objeto:

  • Em um único bloco: essa abordagem costuma ser melhor, já que requer menos solicitações e, portanto, tem melhor desempenho.
  • Em vários blocos: use essa abordagem se você precisar reduzir a quantidade de dados transferidos em qualquer solicitação única, como quando há um limite de tempo fixo para solicitações individuais ou quando você não sabe o tamanho total do upload no momento do envio.

Upload de bloco único

Para fazer upload do arquivo em um único bloco, faça o seguinte:

API JSON

  1. Use cURL para chamar a API JSON com uma solicitação de objeto PUT.

    curl -i -X PUT --data-binary @OBJECT_LOCATION \
        -H "Content-Length: OBJECT_SIZE" \
        "SESSION_URI"

    Em que:

    • OBJECT_LOCATION é o caminho local do objeto. Por exemplo, Desktop/dog.png.
    • OBJECT_SIZE é o número de bytes no objeto. Por exemplo, 20000000.
    • SESSION_URI é o valor retornado no cabeçalho Location quando você iniciou o upload retomável.

    Se quiser, inclua cabeçalhos com o prefixo X-Goog-Meta- para adicionar metadados personalizados ao objeto como parte dessa solicitação.

API XML

  1. Use cURL para chamar a API XML com uma solicitação de objeto PUT.

    curl -i -X PUT --data-binary @OBJECT_LOCATION \
        -H "Content-Length: OBJECT_SIZE" \
        "SESSION_URI"

    Em que:

    • OBJECT_LOCATION é o caminho local do objeto. Por exemplo, Desktop/dog.png.
    • OBJECT_SIZE é o número de bytes no objeto. Por exemplo, 20000000.
    • SESSION_URI é o valor retornado no cabeçalho Location quando você iniciou o upload retomável.

Se o upload for concluído na íntegra, você receberá uma resposta 200 OK ou 201 Created, com todos os metadados associados ao recurso.

Se a solicitação de upload for interrompida ou você receber uma resposta 5xx, siga o procedimento em Como retomar um upload interrompido.

Upload de várias partes

Para fazer upload dos dados em vários blocos:

API JSON

  1. Crie um bloco de dados com base nos dados gerais que você quer enviar.

    O tamanho do bloco será um múltiplo de 256 KiB (256 x 1.024 bytes), a menos que seja o último bloco que conclui o upload. Tamanhos de bloco maiores geralmente tornam os uploads mais rápidos, mas existe uma compensação entre velocidade e uso de memória. É recomendável usar pelo menos 8 MiB para o tamanho do bloco.

  2. Use cURL para chamar a API JSON com uma solicitação de objeto PUT.

    curl -i -X PUT --data-binary @CHUNK_LOCATION \
        -H "Content-Length: CHUNK_SIZE" \
        -H "Content-Range: bytes CHUNK_FIRST_BYTE-CHUNK_LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    Em que:

    • CHUNK_LOCATION é o caminho local para o bloco que você está enviando no momento.
    • CHUNK_SIZE é o número de bytes que você está enviando na solicitação atual. Por exemplo, 8388608.
    • CHUNK_FIRST_BYTE é o byte inicial no objeto geral contido no bloco que você está enviando.
    • CHUNK_LAST_BYTE é o byte final no objeto geral contido no bloco que você está enviando.
    • TOTAL_OBJECT_SIZE é o tamanho total do objeto que você está enviando.
    • SESSION_URI é o valor retornado no cabeçalho Location quando você iniciou o upload retomável.

    Um Content-Range de exemplo é Content-Range: bytes 0-8388607/20000000. Consulte Content-Range para mais informações sobre esse cabeçalho.

    Se a solicitação for bem-sucedida, o servidor responderá com 308 Resume Incomplete. A resposta contém um cabeçalho Range.

  3. Repita as etapas acima para cada bloco restante de dados que você quer enviar, usando o valor superior contido no cabeçalho Range de cada resposta para determinar onde iniciar cada bloco sucessivo; não suponha que o servidor tenha recebido todos os bytes enviados em qualquer solicitação.

    Se quiser, na solicitação final do upload retomável, inclua cabeçalhos com o prefixo X-Goog-Meta- para adicionar metadados personalizados ao objeto.

API XML

  1. Crie um bloco de dados com base nos dados gerais que você quer enviar.

    O tamanho do bloco será um múltiplo de 256 KiB (256 x 1.024 bytes), a menos que seja o último bloco que conclui o upload. Tamanhos de bloco maiores geralmente tornam os uploads mais rápidos, mas existe uma compensação entre velocidade e uso de memória. É recomendável usar pelo menos 8 MiB para o tamanho do bloco.

  2. Use cURL para chamar a API XML com uma solicitação de objeto PUT.

    curl -i -X PUT --data-binary @CHUNK_LOCATION \
        -H "Content-Length: CHUNK_SIZE" \
        -H "Content-Range: bytes CHUNK_FIRST_BYTE-CHUNK_LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    Em que:

    • CHUNK_LOCATION é o caminho local para o bloco que você está enviando no momento.
    • CHUNK_SIZE é o número de bytes que você está enviando na solicitação atual. Por exemplo, 8388608.
    • CHUNK_FIRST_BYTE é o byte inicial no objeto geral contido no bloco que você está enviando.
    • CHUNK_LAST_BYTE é o byte final no objeto geral contido no bloco que você está enviando.
    • TOTAL_OBJECT_SIZE é o tamanho total do objeto que você está enviando.
    • SESSION_URI é o valor retornado no cabeçalho Location quando você iniciou o upload retomável.

    Um Content-Range de exemplo é Content-Range: bytes 0-8388607/20000000. Consulte Content-Range para mais informações sobre esse cabeçalho.

    Se a solicitação for bem-sucedida, o servidor responderá com 308 Resume Incomplete. A resposta contém um cabeçalho Range.

  3. Repita as etapas acima para cada bloco restante de dados que você quer enviar, usando o valor superior contido no cabeçalho Range de cada resposta para determinar onde iniciar cada bloco sucessivo; não suponha que o servidor tenha recebido todos os bytes enviados em qualquer solicitação.

Depois que o upload for concluído, você receberá uma resposta 200 OK ou 201 Created, com todos os metadados associados ao recurso.

Se algum dos uploads das partes for interrompido, ou se você receber uma resposta 5xx, reenvie a parte interrompida na íntegra ou retome o upload interrompido de onde parou.

Verificar o status de um upload retomável

Se o upload retomável for interrompido ou você não tiver certeza se ele foi mesmo concluído, verifique o status do upload:

API JSON

  1. Use cURL para chamar a API JSON com uma solicitação de objeto PUT.

    curl -i -X PUT \
        -H "Content-Length: 0" \
        -H "Content-Range: bytes */OBJECT_SIZE" \
        "SESSION_URI"

    Em que:

    • OBJECT_SIZE é o número total de bytes no objeto. Se você não souber o tamanho total do objeto, use * para esse valor.
    • SESSION_URI é o valor retornado no cabeçalho Location quando você iniciou o upload retomável.

API XML

  1. Use cURL para chamar a API XML com uma solicitação de objeto PUT.

    curl -i -X PUT \
        -H "Content-Length: 0" \
        -H "Content-Range: bytes */OBJECT_SIZE" \
        "SESSION_URI"

    Em que:

    • OBJECT_SIZE é o número total de bytes no objeto. Se você não souber o tamanho total do objeto, use * para esse valor.
    • SESSION_URI é o valor retornado no cabeçalho Location quando você iniciou o upload retomável.

Uma resposta 200 OK ou 201 Created indica que o upload foi concluído e não é necessário realizar qualquer outra ação.

Uma resposta 308 Resume Incomplete indica que você precisa continuar fazendo o upload dos dados.

  • Se o Cloud Storage ainda não manteve bytes, a resposta 308 não terá um cabeçalho Range. Nesse caso, inicie o upload desde o início.
  • Caso contrário, a resposta 308 terá um cabeçalho Range, que especifica quais bytes o Cloud Storage manteve até o momento. Use esse valor ao retomar um upload interrompido.

Retomar um upload interrompido

Se uma solicitação de upload for encerrada antes de receber uma resposta ou se você receber uma resposta 503 ou 500, será necessário retomar o upload interrompido do ponto em que parou. Para retomar um upload interrompido:

API JSON

  1. Verifique o status do upload retomável.

  2. Salve o valor superior do cabeçalho Range contido na resposta à verificação de status. Se a resposta não tiver um cabeçalho Range, o Cloud Storage não manteve bytes e você precisará fazer o upload desde o início.

  3. Verifique se os dados do objeto que você está prestes a enviar começam no byte após o valor superior do cabeçalho Range.

  4. Se a solicitação interrompida contiver cabeçalhos com o prefixo X-Goog-Meta-, inclua esses cabeçalhos na solicitação para retomar o upload.

  5. Use cURL para chamar a API JSON com uma solicitação de objeto PUT que faz a coleta no byte após o valor superior do cabeçalho Range:

    curl -i -X PUT --data-binary @PARTIAL_OBJECT_LOCATION \
        -H "Content-Length: UPLOAD_SIZE_REMAINING" \
        -H "Content-Range: bytes NEXT_BYTE-LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    Em que:

    • PARTIAL_OBJECT_LOCATION é o caminho local para a parte restante dos dados que você quer enviar.
    • UPLOAD_SIZE_REMAINING é o número de bytes que você está enviando na solicitação atual. Por exemplo, fazer o upload do restante de um objeto com tamanho total de 20000000 que foi interrompido após o envio de 0-42 bytes terá um UPLOAD_SIZE_REMAINING de 19999957.
    • NEXT_BYTE é o próximo número inteiro após o valor salvo na Etapa 2. Por exemplo, se 42 for o valor superior na Etapa 2, o valor de NEXT_BYTE será 43.
    • LAST_BYTE é o byte final contido nesta solicitação de PUT. Por exemplo, para concluir o upload de um objeto com tamanho total de 20000000, o valor de LAST_BYTE será 19999999.
    • TOTAL_OBJECT_SIZE é o tamanho total do objeto que você está enviando. Por exemplo, 20000000.
    • SESSION_URI é o valor retornado no cabeçalho Location quando você iniciou o upload retomável.

API XML

  1. Verifique o status do upload retomável.

  2. Salve o valor superior do cabeçalho Range contido na resposta à verificação de status. Se a resposta não tiver um cabeçalho Range, o Cloud Storage não manteve bytes e você precisará fazer o upload desde o início.

  3. Verifique se os dados do objeto que você está prestes a enviar começam no byte após o valor superior do cabeçalho Range.

  4. Use cURL para chamar a API XML com uma solicitação de objeto PUT que faz a coleta no byte após o valor no cabeçalho Range:

    curl -i -X PUT --data-binary @PARTIAL_OBJECT_LOCATION \
        -H "Content-Length: UPLOAD_SIZE_REMAINING" \
        -H "Content-Range: bytes NEXT_BYTE-LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    Em que:

    • PARTIAL_OBJECT_LOCATION é o caminho local para a parte restante dos dados que você quer enviar.
    • UPLOAD_SIZE_REMAINING é o número de bytes que você está enviando na solicitação atual. Por exemplo, fazer o upload do restante de um objeto com tamanho total de 20000000 que foi interrompido após o envio de 0-42 bytes terá um UPLOAD_SIZE_REMAINING de 19999957.
    • NEXT_BYTE é o próximo número inteiro após o valor salvo na Etapa 2. Por exemplo, se 42 for o valor superior na Etapa 2, o valor de NEXT_BYTE será 43.
    • LAST_BYTE é o byte final contido nesta solicitação de PUT. Por exemplo, para concluir o upload de um objeto com tamanho total de 20000000, o valor de LAST_BYTE será 19999999.
    • TOTAL_OBJECT_SIZE é o tamanho total do objeto que você está enviando. Por exemplo, 20000000.
    • SESSION_URI é o valor retornado no cabeçalho Location quando você iniciou o upload retomável.

É possível retomar os uploads quantas vezes forem necessárias enquanto o URI da sessão estiver ativo. O URI da sessão expira após uma semana. Quando os dados forem carregados, o Cloud Storage responderá com um código de status 200 OK ou 201 created.

Cancelar um upload

Para cancelar um upload retomável incompleto e impedir outras ações nele:

API JSON

  1. Use cURL para chamar a API JSON com uma solicitação DELETE:

    curl -i -X DELETE -H "Content-Length: 0" \
      "SESSION_URI"

    Em que:

Se funcionar, a resposta conterá o código de status 499. As tentativas futuras de consultar ou retomar o resultado do upload em uma resposta 4xx

API XML

  1. Use cURL para chamar a API XML com uma solicitação DELETE:

    curl -i -X DELETE -H "Content-Length: 0" \
      "SESSION_URI"

    Em que:

Se a resposta for bem-sucedida, ela conterá um código de status 204, e tentativas posteriores de consultar ou retomar o upload também resultarão em uma resposta 204.

Como lidar com falhas

Em circunstâncias raras, uma solicitação para retomar um upload interrompido pode falhar com um erro 4xx não recuperável porque as permissões no bucket mudaram ou porque a verificação de integridade no objeto enviado final detectou uma incompatibilidade. Se isso acontecer, tente realizar novamente o upload iniciando uma nova sessão de upload retomável.

A seguir