Il y a eu une problème précédent avec le téléchargement des sauvegardes qui semble avoir été corrigé dans la version 2026.01.0-latest. Je pense qu’il s’agit ici d’un problème actuel distinct, lié à la récupération après un téléchargement de sauvegarde interrompu, et non de l’échec initial de téléchargement décrit précédemment.
L’une des hypothèses soulevées dans cette discussion antérieure était que le lien de sauvegarde à usage unique pourrait empêcher un navigateur de reprendre un téléchargement interrompu : une fois que la première requête a consommé le lien, une requête de reprise ultérieure pourrait ne plus être autorisée.
J’ai désormais pu reproduire exactement ce comportement sur la version actuelle de Discourse.
Reproduction
Je téléchargeais une sauvegarde locale de Discourse de :
4 231 639 143 octets
en utilisant Safari sur iOS.
Le téléchargement progressait normalement. J'ai une capture d'écran montrant qu'il passait d'environ :
313,3 Mo à 317,8 Mo
J’ai ensuite quitté Safari pendant seulement environ 15 secondes.
Lorsque je suis revenu à Safari, le téléchargement s’était arrêté à environ :
319,8 Mo
et Safari affichait son contrôle de réessai.
Le journal d’accès Caddy pour la requête d’origine montre :
GET /admin/backups/...
HTTP/3
Range: none
status: 200
Content-Length: 4231639143
size: 319864024
J’ai ensuite utilisé le contrôle de réessai de Safari lui-même.
Safari a effectué une véritable requête HTTP de plage d’octets :
GET /admin/backups/...
HTTP/3
Range: bytes=319799904-
status: 422
Safari ne tentait donc pas simplement un autre téléchargement complet. Il essayait correctement de reprendre le fichier existant à peu près au point où le transfert précédent s’était arrêté.
Discourse a rejeté cette requête Range avec un code 422.
Code actuel de Discourse
En examinant le code actuel de Admin::BackupsController#show, la séquence est effectivement la suivante :
EmailBackupToken.compare(current_user.id, token)
↓
find backup
↓
EmailBackupToken.del(current_user.id)
↓
send_file
Ainsi, la requête initiale authentifiée consomme le jeton d’e-mail avant que le transfert de plusieurs gigaoctets ne soit réellement terminé.
Si ce transfert est ensuite interrompu, Safari effectue une autre requête telle que :
Range: bytes=319799904-
mais cette requête passe à nouveau par /admin/backups/… et le jeton d’e-mail a déjà été supprimé.
Cela semble expliquer le code 422 que j’ai capturé.
La session authentifiée est toujours requise en plus du jeton de sauvegarde, je ne propose donc pas simplement de rendre le jeton existant réutilisable indéfiniment.
Plutôt, je me demande s’il devrait y avoir un moyen borné pour le même administrateur authentifié de reprendre le même téléchargement de sauvegarde déjà autorisé.
Par exemple, cela pourrait être une autorisation de téléchargement à durée de vie courte associée au même utilisateur et à la même sauvegarde, bien que les mainteneurs aient peut-être une meilleure façon de gérer cela.
Pourquoi cela devient plus facile à reproduire sur iOS
L’interruption qui a révélé ce problème semble également similaire aux rapports des utilisateurs des versions récentes d’iOS.
Il y a au moins trois rapports hébergés sur la communauté Apple :
rapports plus anciens
« Les téléchargements en arrière-plan de Safari échouent après la mise à jour d’IOS 26 » — octobre 2025
Safari Background Downloads Failing After… - Apple Community
L’utilisateur rapporte que les grands téléchargements de Safari échouent lorsqu’ils s’exécutent en arrière-plan après la mise à niveau vers iOS 26. Ils ont également mis à niveau un iPhone 15 Pro vers iOS 26 et ont rapporté le même comportement.
« Problème de téléchargement en arrière-plan de Safari iOS - Annulation lors de la minimisation » — décembre 2025
Safari iOS Background Download Issue - Ca… - Apple Community
Signalé sur un iPhone 15 exécutant iOS 26.1. Les téléchargements démarrent normalement mais sont annulés après le passage à une autre application ou la minimisation de Safari.
« Safari ne peut pas terminer un grand téléchargement » — avril 2026
Signalé sur un iPhone 17 Pro Max exécutant iOS 26.4. Les grands téléchargements sont supposés se mettre en pause peu après le verrouillage de l’appareil, le passage entre Safari, ou le changement entre données cellulaires et Wi-Fi. L’auteur signale spécifiquement une bonne réception et affirme que les mêmes téléchargements sont terminés sur PC, Mac et Android.
Je ne pense pas que ces rapports communautaires suffisent à affirmer qu’Apple a confirmé une régression d’iOS.
Cependant, ils sont cohérents avec ma capture d’écran : la sauvegarde était en cours de téléchargement normalement, je suis brièvement passé d’une autre application à Safari, et lorsque je suis revenu, le transfert avait été interrompu.
Le point important côté Discourse est indépendant de la raison de l’interruption :
le transfert de sauvegarde volumineux est interrompu
↓
le navigateur tente une reprise Range basée sur les normes
↓
le jeton de sauvegarde a déjà été consommé
↓
la reprise reçoit un code 422
Observations côté serveur
Cela ne semble pas être un problème général avec le chemin nginx/sendfile actuel.
Le même chemin de sauvegarde multi-Go a été complété avec succès :
- depuis Firefox/Linux via HTTP/3 ; et
- depuis le même iPhone via Wi-Fi en utilisant HTTP/3.
Le nginx actuel publie également le support des plages d’octets.
Je ne suggère donc pas que HTTP/3, Caddy ou nginx est intrinsèquement incapable de livrer la sauvegarde.
Dans cette reproduction particulière, le transfert d’origine a été interrompu après environ 320 Mo, Safari a ensuite effectué une requête Range apparemment valide, et cette deuxième requête a été rejetée par Discourse.
Aurait-il du sens qu’un téléchargement de sauvegarde déjà autorisé dispose d’un mécanisme à durée de vie courte permettant au même administrateur authentifié de reprendre ce même fichier après un transfert interrompu ?