O download do backup não pode ser retomado após a interrupção porque o token de e-mail já foi consumido

Lembro-me de um problema semelhante que parece ter sido corrigido na versão 2026.01.0-latest, portanto, acredito que esta seja uma questão atual e separada, envolvendo a recuperação de um download de backup interrompido, em vez da falha antiga no download inicial.

É plausível pensar que o link de backup de uso único possa impedir o navegador de retomar um download interrompido, mas não é possível baixar um backup duas vezes com um único link. Portanto, quando ele falha uma vez, a retomada do download provavelmente é cancelada pelo próprio Discourse.

Agora consegui reproduzir exatamente esse comportamento no Discourse atual.

Reprodução

Eu estava baixando um backup local do Discourse de:

4.231.639.143 bytes

usando o Safari no iOS.

O download estava progredindo normalmente. Tenho uma gravação de tela mostrando o aumento de aproximadamente:

https://youtube.com/shorts/_Pjc-kxJ1OE?feature=shared

313,3 MB para 317,8 MB

Em seguida, saí do Safari por apenas cerca de 15 segundos.

Quando voltei ao Safari, o download havia parado em aproximadamente:

319,8 MB

e o Safari exibiu seu controle de nova tentativa.


O log de acesso do Caddy para a solicitação original mostra:

GET /admin/backups/...

HTTP/3

Range: none

status: 200

Content-Length: 4231639143

size: 319864024

Em seguida, usei o próprio controle de nova tentativa do Safari.

O Safari fez uma verdadeira solicitação de intervalo de bytes HTTP:

GET /admin/backups/...

HTTP/3

Range: bytes=319799904-

status: 422

Portanto, o Safari não estava simplesmente tentando outro download completo. Ele estava tentando corretamente retomar o arquivo existente aproximadamente no ponto em que a transferência anterior parou.

O Discourse rejeitou essa solicitação de Range com 422.

Código atual do Discourse

Olhando para o Admin::BackupsController#show atual, a sequência é efetivamente:

EmailBackupToken.compare(current_user.id, token)

        ↓

find backup

        ↓

EmailBackupToken.del(current_user.id)

        ↓

send_file

Portanto, a solicitação autenticada inicial consome o token do e-mail antes que a transferência de vários gigabytes tenha sido realmente concluída.

Se essa transferência for interrompida em seguida, o Safari faz outra solicitação, como:

Range: bytes=319799904-

mas essa solicitação passa novamente por /admin/backups/… e o token do e-mail já foi excluído.

Isso parece explicar o 422 que capturei.

A sessão autenticada ainda é necessária, bem como o token de backup, portanto, não estou sugerindo simplesmente tornar o token existente reutilizável indefinidamente.

Em vez disso, estou me perguntando se deveria haver alguma maneira limitada para o mesmo administrador autenticado retomar o mesmo download de backup já autorizado.

Por exemplo, isso poderia ser uma autorização de download de vida curta associada ao mesmo usuário e backup, embora os mantenedores possam ter uma maneira melhor de lidar com isso.

Por que isso está se tornando mais fácil de reproduzir no iOS

A interrupção que expôs isso também parece semelhante a relatórios de usuários de versões recentes do iOS.

Há pelo menos três relatórios hospedados na Apple Community:

relatórios mais antigos

“Falhas em downloads em segundo plano do Safari após atualização para IOS 26” — outubro de 2025

Safari Background Downloads Failing After… - Apple Community

O usuário relata que downloads maiores do Safari falham quando executados em segundo plano após a atualização para o iOS 26. Eles também atualizaram um iPhone 15 Pro para o iOS 26 e relataram o mesmo comportamento.

“Problema de download em segundo plano do Safari iOS - Cancela ao minimizar” — dezembro de 2025

Safari iOS Background Download Issue - Ca… - Apple Community

Relatado em um iPhone 15 executando o iOS 26.1. Os downloads começam normalmente, mas são cancelados após alternar para outro aplicativo ou minimizar o Safari.

“Safari não consegue concluir um download grande” — abril de 2026

Relatado em um iPhone 17 Pro Max executando o iOS 26.4. Relata-se que downloads grandes pausam pouco tempo depois de bloquear o dispositivo, deixar o Safari ou alternar entre celular e Wi-Fi. O autor relata especificamente bom sinal e diz que os mesmos downloads são concluídos em PC, Mac e Android.

Não acho que esses relatórios da comunidade sejam suficientes para afirmar que a Apple confirmou uma regressão no iOS.

No entanto, eles são consistentes com minha gravação de tela: o backup estava sendo baixado normalmente, saí do Safari brevemente e, quando voltei, a transferência havia sido interrompida.

O ponto importante do lado do Discourse é independente do motivo da interrupção:

transferência de backup grande é interrompida

        ↓

navegador tenta retomar com Range baseado em padrões

        ↓

token de backup já foi consumido

        ↓

retomada recebe 422

Observações do lado do servidor

Isso não parece ser um problema geral com o caminho atual nginx/sendfile.

O mesmo caminho de backup de vários GB foi concluído com sucesso:

  • do Firefox/Linux via HTTP/3; e
  • do mesmo iPhone via Wi-Fi usando HTTP/3.

O nginx atual também anuncia suporte a intervalos de bytes.

Portanto, não estou sugerindo que HTTP/3, Caddy ou nginx seja intrinsecamente incapaz de entregar o backup.

Nesta reprodução específica, a transferência original foi interrompida após cerca de 320 MB, o Safari fez posteriormente uma solicitação de Range aparentemente válida e essa segunda solicitação foi rejeitada pelo Discourse.

Faria sentido que um download de backup já autorizado tivesse algum mecanismo de vida curta que permita ao mesmo administrador autenticado retomar aquele mesmo arquivo após uma transferência interrompida?