استكشاف أخطاء Gotenberg وإصلاحها في NextPDF
لمحة سريعة
قسم بعنوان «لمحة سريعة»يفشل الجسر بوضوح ومنذ مرحلة مبكرة. يطلق كل فشل استثناءً محدد النوع برسالة تذكر السبب. استخدم هذه الصفحة كدليل مرجعي. لكل فشل، ستجد نوع الاستثناء، وجزء الرسالة الذي ستراه، والمطلق الدقيق في مسار التنفيذ، وطريقة الإصلاح.
فئات الاستثناءات هي:
GotenbergConvertException— فشل في طبقة التحويل (الإعداد أو النقل أو الاستجابة).RuntimeException— فشل في طبقة التحقق تطلقه سياسة الأمان قبل أي حركة شبكية.ValueError— امتداد ملف غير معروف.InvalidSpkiPinException— سلسلة تثبيت Transport Layer Security (TLS) SubjectPublicKeyInfo (SPKI) غير سليمة التنسيق.
حالات فشل الإعداد
قسم بعنوان «حالات فشل الإعداد»”Invalid Gotenberg configuration: apiUrl is empty”
قسم بعنوان «”Invalid Gotenberg configuration: apiUrl is empty”»- النوع:
GotenbergConvertException - المُطلِق: تم استدعاء
convertFile()أوconvertString()بينماGotenbergConfig::isValid()تُرجع false. يحدث ذلك عندما تكونapiUrlسلسلة فارغة. - الإصلاح: زود عنوان HTTPS URL غير فارغ. إذا أنشأت الإعداد باستخدام
fromArray()، فلاحظ أنها تستبدل''ضمنيًا عندما تكون قيمةapi_urlمفقودة أو غير نصية. تحقق من مصدر إعدادك أثناء الإقلاع.
حالات فشل عنوان URL والعنوان (SSRF)
قسم بعنوان «حالات فشل عنوان URL والعنوان (SSRF)»تأتي حالات الفشل هذه من سياسة الأمان التي تحمي من تزوير الطلب من جانب الخادم (SSRF). يطلقها الجسر قبل إرسال أي طلب. كل واحدة منها هي RuntimeException عادية.
”Gotenberg API URL must use HTTPS (got: http)”
قسم بعنوان «”Gotenberg API URL must use HTTPS (got: http)”»- المُطلِق: مخطط عنوان URL المهيأ ليس
https. التحقق غير حساس لحالة الأحرف، لذلك يُقبلHTTPS://. - الإصلاح: ضع Gotenberg خلف TLS واضبط نقطة نهاية HTTPS. يُرفض HTTP العادي حتى في التطوير المحلي.
”Invalid Gotenberg API URL: unable to parse”
قسم بعنوان «”Invalid Gotenberg API URL: unable to parse”»- المُطلِق: تعذر تحليل عنوان URL إلى مخطط ومضيف.
- الإصلاح: زود عنوان URL مطلقًا صحيحًا نحويًا، مثل
https://gotenberg.example.com:3000.
”Gotenberg API URL must not resolve to a private or reserved IP address”
قسم بعنوان «”Gotenberg API URL must not resolve to a private or reserved IP address”»- المُطلِق: المضيف هو عنوان بروتوكول إنترنت (IP) خاص أو محجوز حرفيًا، أو اسم مضيف يُحل (عبر كل سجلات A/AAAA) إلى أي عنوان خاص أو محجوز. يحجب هذا النطاقات الخاصة من طلب التعليقات (RFC) 1918، وعناوين الاسترجاع (loopback)، والعناوين المحلية للرابط (link-local).
- الإصلاح: وجه الجسر إلى عنوان عام قابل للتوجيه أو إلى عنوان خدمة معزول بشكل سليم. إذا كان Gotenberg لديك على شبكة خاصة عمدًا، فإن حارس SSRF في الجسر يرفضه حسب التصميم. اكشفه عبر عنوان يقبله الحارس، ثم احم ذلك المسار بضوابط شبكية ومصادقة. راجع /integrations/gotenberg/security-and-operations/.
“Gotenberg API URL DNS answer changed since validation — possible DNS rebinding attack”
قسم بعنوان «“Gotenberg API URL DNS answer changed since validation — possible DNS rebinding attack”»- المُطلِق: بين التحقق الأولي والطلب، أعاد تحليل جديد لنظام أسماء النطاقات (DNS) عنوانًا لم يكن ضمن المجموعة التي تم التحقق منها أصلًا.
- الإصلاح: هذا يعني أن حارس time-of-check/time-of-use قد فُعّل. افحص DNS للمضيف. قد يكون السبب المشروع موازن تحميل يدوّر العناوين، وقد يكون السبب الخبيث هجوم إعادة ربط. استخدم عنوانًا ثابتًا أو اسمًا بمجموعة سجلات ثابتة لنقطة نهاية Gotenberg.
حالات فشل التحقق من المدخلات
قسم بعنوان «حالات فشل التحقق من المدخلات»تطلق سياسة الأمان حالات الفشل هذه قبل الطلب. كل واحدة منها هي RuntimeException عادية ما لم يُذكر خلاف ذلك.
”File not found or not readable: ”
قسم بعنوان «”File not found or not readable: ”»- النوع:
GotenbergConvertException - المُطلِق: تعذر على
convertFile()تقييس المسار، أو أن المسار المحلول ليس ملفًا عاديًا قابلًا للقراءة. يُطلق هذا أيضًا عند تمرير دليل. - الإصلاح: مرر مسارًا إلى ملف موجود قابل للقراءة. يُقيَّس المسار باستخدام
realpath()أولًا، وهذا يبطل أيضًا اجتياز المسارات.
”File size ( bytes) exceeds maximum allowed size ( bytes)”
قسم بعنوان «”File size ( bytes) exceeds maximum allowed size ( bytes)”»- المُطلِق: المُدخل أكبر من
maxFileSize(الافتراضي 52,428,800 بايت = 50 MiB). - الإصلاح: ارفع
maxFileSizeإذا كان المستند يحتاج إلى ذلك فعلًا، أو ارفض الرفع في مرحلة أبكر. أبق الحد الأقصى منخفضًا بقدر ما تسمح به مستنداتك الفعلية. إنه حد الموارد المدمج الوحيد في الجسر.
حالات رفض اسم الملف
قسم بعنوان «حالات رفض اسم الملف»يتحقق الجسر من اسم الملف. في تحويلات الملفات، يكون اسم الملف هو الاسم الأساسي للمسار المحلول؛ أما في convertString() فهو الاسم الذي تمرره. كل واحدة من هذه الحالات هي RuntimeException:
| جزء الرسالة | المُطلِق |
|---|---|
must not be empty | اسم ملف فارغ |
path traversal sequences (..) | يحتوي الاسم على .. |
forward slashes | يحتوي الاسم على / |
backslashes | يحتوي الاسم على \ |
null bytes | يحتوي الاسم على بايت NUL |
control characters | يحتوي الاسم على محرف تحكُّم ASCII (0–31) |
- الإصلاح: مرِّر اسمًا أساسيًا نظيفًا. بالنسبة لـ
convertString()، زوِّد اسمًا عاديًا مثلreport.docx. يُستخدم لاكتشاف التنسيق وبوصفه اسم ملف الرفع متعدد الأجزاء، وليس بوصفه مسارًا. - الإصلاح: مرر اسمًا أساسيًا نظيفًا. بالنسبة إلى
convertString()، زود اسمًا عاديًا مثلreport.docx. يُستخدم لاكتشاف التنسيق وبوصفه اسم ملف الرفع متعدد الأجزاء، لا بوصفه مسارًا.
”Unknown office format extension: ”
قسم بعنوان «”Unknown office format extension: ”»- النوع:
ValueError - المُطلِق: امتداد الملف ليس واحدًا من
docx،xlsx،pptx،odt،ods،odp(غير حساس لحالة الأحرف، ويتسامح مع النقطة البادئة). - الإصلاح: حول فقط التنسيقات الستة المعترف بها. لا يتعرف الجسر على التنسيقات الثنائية القديمة (
.doc،.xls،.ppt)، أو.rtf، أو.csv، أو النص العادي، أو الصور. حول هذه المدخلات إلى تنسيق معترف به قبل استدعاء الجسر، أو وجهها عبر مسار مختلف.
حالات فشل النقل والاستجابة
قسم بعنوان «حالات فشل النقل والاستجابة»كل هذه هي GotenbergConvertException.
”Gotenberg HTTP request failed: ”
قسم بعنوان «”Gotenberg HTTP request failed: ”»- المُطلِق: أطلق عميل توصية PHP المعيارية 18 (PSR-18) (أو نقل cURL المدمج) استثناءً أثناء إرسال الطلب. يكون السبب رفض الاتصال، أو انتهاء مهلة، أو فشل مصافحة TLS، أو عدم تطابق تثبيت.
- رمز الاستثناء: رمز استثناء العميل الأساسي.
- السبب: يُرفق استثناء عميل PSR-18 الأصلي بوصفه الاستثناء السابق.
- الإصلاح: تحقق من أربعة أشياء. تحقق من إمكانية الوصول إلى الخدمة باستخدام
isAvailable(). تحقق من مسار الشبكة. تحقق من سلسلة TLS. إذا كان التثبيت مهيأً، فتحقق من أن SubjectPublicKeyInfo (SPKI) الحالي للخادم يطابق تثبيتًا مهيأً. عدم تطابق التثبيت بعد تدوير الشهادة هو السبب المعتاد. راجع إجراء التدوير في /integrations/gotenberg/security-and-operations/.
“cURL transport error (): ”
قسم بعنوان «“cURL transport error (): ”»- المُطلِق: فشل
curl_execالخاص بنقل cURL المدمج برقم خطأ cURL غير صفري، أو أعاد جسمًا غير نصي. - الإصلاح: يحدد رقم خطأ cURL السبب (TLS، أو التحليل، أو انتهاء المهلة، أو التثبيت). يظهر فشل التثبيت هنا عندما يرفض
CURLOPT_PINNEDPUBLICKEYالشهادة. تأكد من أن التثبيتات المهيأة والعنوان المحلول محدثة.
”Gotenberg conversion failed with HTTP : ”
قسم بعنوان «”Gotenberg conversion failed with HTTP : ”»- المُطلِق: لم تكن حالة الاستجابة
200. يُدرج الجسم مقتطعًا إلى أول 500 محرف، مع إلحاق علامة حذف عندما يكون أطول. - الإصلاح: اقرأ الجسم المدرج. تشرح رسالة خطأ Gotenberg سبب رفض التحويل: محتوى مستند غير مدعوم، أو فشل داخلي في LibreOffice، أو رفض مصادقة على
401أو403.401/403يعني أنapiKeyمفقود أو خاطئ.5xxفشل من جانب الخدمة، وهو المرشح لإعادة محاولة محدودة.
”Unexpected Content-Type from Gotenberg: (expected application/pdf)”
قسم بعنوان «”Unexpected Content-Type from Gotenberg: (expected application/pdf)”»- المُطلِق: كانت الحالة
200، لكنContent-Typeفي الاستجابة لم يحتوِ علىapplication/pdf. - الإصلاح: يعني هذا عادةً أن وكيلًا أو بوابة أعاد صفحة خطأ HTML أو صفحة إعادة توجيه بحالة
200. يعطل الجسر تتبع إعادة التوجيه على النقل المدمج عمدًا، لذلك لا يُتبع رد3xxبصمت إلى مضيف غير متحقق منه. وصول جسم بـContent-Typeخاطئ يشير إلى أن شيئًا ما بينك وبين Gotenberg يتدخل. افحص مسار الشبكة.
”Response body does not start with %PDF header — invalid PDF data”
قسم بعنوان «”Response body does not start with %PDF header — invalid PDF data”»- المُطلِق: الحالة
200، وContent-Typeمقبول، لكن الجسم لا يبدأ بتوقيع%PDF. - الإصلاح: أعاد المنبع شيئًا ليس ملف تنسيق المستند المحمول (PDF) رغم الترويسات. عامل الاستجابة بوصفها غير موثوقة وافحص الخدمة. لا تكتب الجسم إلى القرص. يرفض الجسر إعادته بوصفه نتيجة.
حالات فشل إعداد التثبيت
قسم بعنوان «حالات فشل إعداد التثبيت»”Invalid SPKI pin format: (expected sha256/)”
قسم بعنوان «”Invalid SPKI pin format: (expected sha256/)”»- النوع:
InvalidSpkiPinException - المُطلِق: سلسلة تثبيت مهيأة لا تبدأ بـ
sha256/أوsha256//. - الإصلاح: نسق كل تثبيت بالشكل
sha256/<base64-encoded-spki-hash>. يقبل النقل أيضًا الشكل الأصلي لـ cURLsha256//<base64>. ولد القيمة من SubjectPublicKeyInfo لشهادة الخادم، لا من الشهادة بأكملها.
”It says unavailable but the service is up”
قسم بعنوان «”It says unavailable but the service is up”»isAvailable() تُرجع false دون أي استدعاء شبكي عندما يكون عنوان URL فارغًا، أو ليس HTTPS، أو يُحل إلى عنوان private/reserved. كما تُرجع false عند أي خطأ شبكي، أو عندما يُرجع /health الحالة 500 أو أعلى؛ في تلك الحالات، تلتقط الخطأ بدلًا من إطلاقه. تحقق، بالترتيب:
- عنوان URL المهيأ غير فارغ وهو HTTPS.
- المضيف لا يُحل إلى عنوان private/reserved (حارس SSRF يرفضه حتى لأغراض الفحص).
<apiUrl>/healthقابل للوصول من مضيف التطبيق ويُرجع حالة أقل من500.
انظر أيضًا
قسم بعنوان «انظر أيضًا»- /integrations/gotenberg/configuration/ — كل الخيارات وقواعد اختيار النقل.
- /integrations/gotenberg/production-usage/ — سياسة إعادة المحاولة وعقد معالجة الفشل.
- /integrations/gotenberg/security-and-operations/ — نموذج SSRF وتدوير التثبيت.
- /integrations/gotenberg/quickstart/ — ترتيب الالتقاط الشامل ضمن سياقه.