تذكرت مشكلة مشابهة يبدو أنها تم إصلاحها في إصدار 2026.01.0-latest، لذا أعتقد أن هذه مشكلة حالية منفصلة تتعلق بالاسترداد من تنزيل نسخة احتياطية انقطع، وليس فشل التنزيل الأولي القديم.
من المعقول التفكير في أن رابط النسخة الاحتياطية الذي يُستخدم مرة واحدة قد يمنع المتصفح من استئناف التنزيل المنقطع، لكنك لا تستطيع تنزيل نسخة احتياطية مرتين باستخدام رابط واحد. لذا، عندما يفشل التنزيل مرة واحدة، على الأرجح يتم إلغاء استئناف التنزيل بواسطة Discourse نفسه.
لقد تمكنت الآن من إعادة إنتاج هذا السلوك بالضبط على إصدار Discourse الحالي.
إعادة الإنتاج
كنت أقوم بتنزيل نسخة احتياطية محلية لـ Discourse بحجم:
4,231,639,143 بايت
باستخدام Safari على iOS.
كان التنزيل يتم بشكل طبيعي. لدي تسجيل شاشة يُظهر زيادته من حوالي:
313.3 ميغابايت إلى 317.8 ميغابايت
ثم انتقلت من Safari لمدة حوالي 15 ثانية فقط.
عندما عدت إلى Safari، كان التنزيل قد توقف عند حوالي:
319.8 ميغابايت
وعرض Safari زر المحاولة مرة أخرى.
يُظهر سجل وصول Caddy للطلب الأصلي:
GET /admin/backups/...
HTTP/3
Range: none
status: 200
Content-Length: 4231639143
size: 319864024
ثم استخدمت زر المحاولة الخاص بـ Safari نفسه.
أصدر Safari طلب نطاق بايت HTTP حقيقي:
GET /admin/backups/...
HTTP/3
Range: bytes=319799904-
status: 422
لذا، لم يكن Safari يحاول ببساطة تنزيل الملف كاملاً مرة أخرى. كان يحاول بشكل صحيح استئناف الملف الموجود عند النقطة التي توقف عندها النقل السابق تقريباً.
رفض Discourse طلب النطاق (Range) ذلك برمز 422.
كود Discourse الحالي
بالنظر إلى Admin::BackupsController#show الحالي، تكون التسلسل الفعلي:
EmailBackupToken.compare(current_user.id, token)
↓
find backup
↓
EmailBackupToken.del(current_user.id)
↓
send_file
لذا، فإن الطلب المصادق عليه الأولي يستهلك رمز البريد الإلكتروني قبل أن يكتمل نقل البيانات الضخم (عدة جيجابايت) فعلياً.
إذا انقطع ذلك النقل لاحقاً، يقوم Safari بإصدار طلب آخر مثل:
Range: bytes=319799904-
لكن هذا الطلب يمر عبر /admin/backups/… مرة أخرى، وقد تم حذف رمز البريد الإلكتروني بالفعل.
يبدو أن هذا يفسر رمز الخطأ 422 الذي تم التقاطه.
لا يزال مطلوباً وجود جلسة مصادقة بالإضافة إلى رمز النسخة الاحتياطية، لذا لا أقترح ببساطة جعل الرمز الحالي قابلاً لإعادة الاستخدام بشكل غير محدود.
بدلاً من ذلك، أتساءل عما إذا كان ينبغي وجود طريقة محددة النطاق تسمح لنفس المسؤول المصادق عليه باستئناف تنزيل نفس النسخة الاحتياطية المصرح بها مسبقاً.
على سبيل المثال، قد يكون ذلك تفويض تنزيل قصير العمر مرتبطاً بنفس المستخدم والنسخة الاحتياطية، على الرغم من أن المطورين قد يكون لديهم طريقة أفضل للتعامل مع هذا.
لماذا أصبح من الأسهل إعادة إنتاج هذا على iOS
يبدو أن الانقطاع الذي كشف عن هذه المشكلة مشابه أيضاً لتقارير المستخدمين من إصدارات iOS الحديثة.
هناك على الأقل ثلاثة تقارير مستضافة على مجتمع Apple:
تقارير أقدم
«فشل التنزيلات في الخلفية في Safari بعد تحديث IOS 26» — أكتوبر 2025
Safari Background Downloads Failing After… - Apple Community
يُبلغ المستخدم عن فشل تنزيلات Safari الكبيرة عند تشغيلها في الخلفية بعد الترقية إلى iOS 26. كما قام بترقية iPhone 15 Pro إلى iOS 26 وأبلغ عن نفس السلوك.
«مشكلة تنزيل الخلفية في Safari iOS - الإلغاء عند التصغير» — ديسمبر 2025
Safari iOS Background Download Issue - Ca… - Apple Community
تم الإبلاغ عنها على iPhone 15 يعمل بنظام iOS 26.1. تبدأ التنزيلات بشكل طبيعي لكنها تُلغى بعد التحويل إلى تطبيق آخر أو تصغير Safari.
«لا يمكن لـ Safari إكمال تنزيل كبير» — أبريل 2026
تم الإبلاغ عنها على iPhone 17 Pro Max يعمل بنظام iOS 26.4. يُزعم أن التنزيلات الكبيرة تتوقف مؤقتاً بعد قفل الجهاز بفترة وجيزة، أو عند التبديل بين الشبكة الخلوية و Wi-Fi. يذكر المؤلف تحديداً وجود إشارة جيدة ويقول إن نفس التنزيلات تكتمل على أجهزة الكمبيوتر، Mac، وأندرويد.
لا أعتقد أن تلك التقارير المجتمعية كافية للقول إن Apple أكدت وجود تراجع (Regression) في iOS.
ومع ذلك، فهي متسقة مع تسجيل الشاشة الخاص بي: كانت النسخة الاحتياطية قيد التنزيل بشكل طبيعي، انتقلت بعيداً عن Safari لفترة وجيزة، وعندما عدت أصبح النقل منقطعاً.
النقطة المهمة من جانب Discourse مستقلة عن سبب حدوث الانقطاع:
انقطاع نقل النسخة الاحتياطية الكبيرة
↓
يحاول المتصفح استئناف النطاق (Range) المعتمد على المعايير
↓
تم استهلاك رمز النسخة الاحتياطية بالفعل
↓
يتلقى الاستئناف رمز 422
ملاحظات من جانب الخادم
لا يبدو أن هذا مشكلة عامة في مسار nginx/sendfile الحالي.
تم إكمال نفس مسار النسخة الاحتياطية الضخم (عدة جيجابايت) بنجاح:
- من Firefox/Linux عبر HTTP/3؛ و
- من نفس iPhone عبر Wi-Fi باستخدام HTTP/3.
يعلن nginx الحالي أيضاً عن دعم نطاقات البايت (byte-range).
لذا، لا أقترح أن HTTP/3 أو Caddy أو nginx غير قادرة جوهرياً على تسليم النسخة الاحتياطية.
في إعادة الإنتاج هذه على وجه الخصوص، انقطع النقل الأصلي بعد حوالي 320 ميغابايت، ثم أصدر Safari طلب نطاق (Range) يبدو صالحاً، وتم رفض ذلك الطلب الثاني بواسطة Discourse.
هل من المعقول أن يكون لتنزيل نسخة احتياطية مصرح بها مسبقاً آلية قصيرة العمر تسمح لنفس المسؤول المصادق عليه باستئناف نفس ذلك الملف بعد انقطاع النقل؟