400 Bad Request – DeדחיסתionFailureAtRequest

אתם צופים במסמכי התיעוד של Apigee Edge.
כדאי לעיין במסמכי התיעוד של Apigee X.
מידע

תיאור הבעיה

אפליקציית הלקוח מקבלת קוד סטטוס של HTTP‏ 400 Bad Request עם קוד השגיאה messaging.adaptors.http.flow.DecompressionFailureAtRequest כתגובה לקריאות ל-API.

הודעת שגיאה

אפליקציית הלקוח מקבלת את קוד התגובה הבא:

HTTP/1.1 400 Bad Request

בנוסף, יכול להיות שתופיע הודעת שגיאה דומה לזו שמוצגת למטה:

{
   "fault":{
      "faultstring":"Decompression failure at request",
      "detail":{
         "errorcode":"messaging.adaptors.http.flow.DecompressionFailureAtRequest"
      }
   }
}

גורמים אפשריים

השגיאה הזו מתרחשת רק אם:

  • הקידוד שצוין בכותרת בקשת ה-HTTPContent-Encoding תקף ו נתמך על ידי Apigee Edge,
  • BUT

  • פורמט המטען הייעודי (payload) שנשלח על ידי הלקוח כחלק מבקשת ה-HTTP לא תואם לפורמט הקידוד שצוין בכותרת Content-Encoding

הסיבה לכך היא ש-Apigee Edge לא מצליח לפענח את המטען הייעודי (payload) באמצעות הקידוד שצוין, כי הפורמט של המטען הייעודי לא זהה לפורמט של הקידוד שצוין בכותרת Content-Encoding.

ריכזנו כאן כמה דוגמאות לערכים נתמכים Content-Encoding ולאופן שבו Apigee Edge מצפה לפורמט של מטען הייעודי (payload) במקרים האלה:

תרחיש קידוד התוכן פורמט המטען הייעודי הצפוי
קידוד יחיד gzip

הפורמט של gzip ב-Unix.

RFC1952 GZIP Format

קידוד יחיד deflate

הפורמט הזה משתמש במבנה zlib עם אלגוריתם דחיסה מסוג deflate.

מידע נוסף זמין ב- RFC1950 וב- RFC1951.

קידודים מרובים

קידודים מרובים

לדוגמה, במקרים שבהם הקידוד נעשה פעמיים, יכול להיות ש:

  • gzip, deflate
  • ‫gzip, ‏ gzip
  • deflate, ‏ gzip
  • deflate, deflate
הוחלו כמה קידודים על מטען הייעודי (payload) בסדר שבו הם מופיעים בכותרת.

אלה הסיבות האפשריות לשגיאה הזו:

סיבה תיאור הוראות לפתרון בעיות שרלוונטיות ל
פורמט המטען הייעודי (payload) של הבקשה לא תואם לקידוד שצוין בכותרת Content-Encoding הפורמט של מטען הייעודי (payload) של הבקשה שנשלח על ידי הלקוח לא מקודד או לא תואם לקידוד שצוין בכותרת Content-Encoding. משתמשים ב-Edge Public Cloud וב-Edge Private Cloud

שלבים נפוצים לאבחון

כדי לאבחן את השגיאה הזו, אפשר להשתמש באחד מהכלים או מהטכניקות הבאים:

API Monitoring

כדי לאבחן את השגיאה באמצעות הכלי 'מעקב אחר API':

  1. נכנסים לממשק המשתמש של Apigee Edge כמשתמש עם תפקיד מתאים.
  2. עוברים לארגון שבו רוצים לבדוק את הבעיה.

  3. עוברים לדף Analyze > API Monitoring > Investigate.
  4. בוחרים את מסגרת הזמן הספציפית שבה נתקלת בשגיאות.
  5. מוודאים שהמסנן Proxy מוגדר לAll.
  6. משרטטים את קוד התקלה מול הזמן.
  7. בוחרים תא עם קוד השגיאה messaging.adaptors.http.flow.DecompressionFailureAtRequest כמו בדוגמה הבאה:

    ( הגדלת התמונה)

  8. מוצג מידע על קוד התקלה messaging.adaptors.http.flow.DecompressionFailureAtRequest, כמו בדוגמה הבאה:

    ( הגדלת התמונה)

  9. לוחצים על הצגת יומנים ומרחיבים את השורה שנכשלה עם השגיאה 400.

    ( הגדלת התמונה)

  10. בחלון יומנים, רושמים את הפרטים הבאים:
    • קוד סטטוס: 400
    • מקור התקלה: proxy
    • קוד שגיאה: messaging.adaptors.http.flow.DecompressionFailureAtRequest.
  11. אם הערך של Fault Source הוא proxy, המשמעות היא שפורמט מטען הייעודי (payload) של הבקשה לא תאם ל קידוד הנתמך שצוין בכותרת Content-Encoding.

כלי המעקב

כדי לאבחן את השגיאה באמצעות הכלי Trace:

  1. מפעילים את trace session (מעקב אחר סשן) ואחת מהאפשרויות הבאות:
    1. ממתינים להתרחשות השגיאה 400 Bad Request, או
    2. אם אפשר לשחזר את הבעיה, מבצעים את קריאת ה-API ומשחזרים את 400 Bad Request.
  2. מוודאים שהאפשרות הצגת כל פרטי הזרימה מופעלת:

  3. בוחרים אחת מהבקשות שנכשלו ובודקים את המעקב.
  4. אפשר לנווט בין השלבים השונים של ה-trace ולמצוא את המקום שבו התרחשה השגיאה.
  5. בדרך כלל השגיאה מופיעה בתהליך מיד אחרי השלב הבקשה התקבלה מהלקוח, כמו שמוצג כאן:

    ( הגדלת התמונה)

  6. שימו לב לערכים של המאפיינים מהמעקב:

    • שגיאה: Decompression failure at request
    • error.class: com.apigee.rest.framework.BadRequestException
    • error.cause: Not in GZIP format

    ב-error.cause מצוין שמטען הייעודי (payload) של הבקשה הוא לא בפורמט GZIP. כלומר, מערכת Apigee Edge ציפתה שמטען הנתונים של הבקשה יהיה בפורמט GZIP, כפי שצוין בכותרת Content-Encoding.

  7. קובעים את הערך של כותרת הבקשה Content-Encoding. לשם כך, עוברים לשלב Request Received from Client (הבקשה התקבלה מהלקוח) כמו שמוצג בהמשך:

    ( הגדלת התמונה)

    שימו לב: הערך של כותרת הבקשה Content-Encoding הוא אכן gzip.

    במעקב לדוגמה שלמעלה אפשר לראות שהקידוד שצוין בכותרת הבקשה Content-Encoding הוא gzip, אבל מטען הייעודי (payload) של הבקשה לא בפורמט GZIP. לכן, Apigee לא יכול לבצע דקומפרסיה של מטען הייעודי באמצעות gzip ומחזיר את השגיאה Decompression failure at request.

  8. כדי לראות את קוד הסטטוס ואת הודעת השגיאה שמוחזרים על ידי Apigee Edge, עוברים אל

    לשלב Response Sent to Client בנתוני המעקב, כמו שמוצג בהמשך:

    ( הגדלת התמונה)

    שימו לב לפרטים הבאים מהמעקב:

    • קוד הסטטוס: 400 Bad Request.
    • תוכן השגיאה: {"fault":{"faultstring":"Decompression failure at request","detail":{"errorcode":"messaging.adaptors.http.flow.DecompressionFailureAtRequest"}}}
  9. עוברים לשלב AX (נתוני Analytics שתועדו) במעקב ולוחצים עליו.

  10. גוללים למטה לקטע Phase Details (פרטי השלב) או Error Headers (כותרות שגיאה) וקובעים את הערכים של X-Apigee-fault-code ו-X-Apigee-fault-source, כמו שמוצג בהמשך:

    ( הגדלת התמונה)

  11. הערכים של X-Apigee-fault-code ו-X-Apigee-fault-source יהיו messaging.adaptors.http.flow.DecompressionFailureAtRequest ו- policy, מה שמציין שהפורמט של מטען הייעודי (payload) של הבקשה לא תאם לקידוד שצוין בכותרת Content-Encoding.
    כותרות תגובה ערך
    X-Apigee-fault-code messaging.adaptors.http.flow.DecompressionFailureAtRequest
    X-Apigee-fault-source policy

NGINX

כדי לאבחן את השגיאה באמצעות יומני הגישה של NGINX:

  1. אם אתם משתמשים ב-Private Cloud, אתם יכולים להשתמש ביומני הגישה של NGINX כדי לקבוע את פרטי המפתח לגבי שגיאות HTTP 400.
  2. בודקים את יומני הגישה של NGINX:

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    איפה: הערכים ORG,‏ ENV ו-PORT# מוחלפים בערכים בפועל.

  3. מחפשים כדי לראות אם יש 400 שגיאות במהלך פרק זמן מסוים (אם הבעיה התרחשה בעבר) או אם יש בקשות שעדיין נכשלות עם 400.
  4. אם אתם מוצאים שגיאות 400 עם הערך של X-Apigee-fault-code שזהה לערך של messaging.adaptors.http.flow.DecompressionFailureAtRequest, אתם צריכים לקבוע את הערך של X-Apigee-fault-source.

    דוגמה לשגיאה 400 מיומן הגישה של NGINX:

    בדוגמה של רשומה מיומן הגישה של NGINX שמופיעה למעלה, הערכים של X-Apigee-fault-code ושל X-Apigee-fault-source הם:

    כותרות תגובה ערך
    X-Apigee-fault-code messaging.adaptors.http.flow.DecompressionFailureAtRequest
    X-Apigee-fault-source policy

הסיבה: פורמט המטען הייעודי (payload) של הבקשה לא תואם לקידוד שצוין בכותרת Content-Encoding

כברירת מחדל, Apigee Edge תמיד מבצע דקומפרסיה של מטען ייעודי (payload) אם request header Content-Encoding מכיל קידוד תקין ו נתמך. לכן, הפורמט של מטען הייעודי (payload) של הבקשה צריך להיות זהה לקידוד שצוין ב-request header Content-Encoding. אם יש אי התאמה, השגיאה הזו תופיע.

אבחון

  1. כדי לקבוע את קוד השגיאה ואת מקור השגיאה של השגיאה שנצפתה, אפשר להשתמש בכלי 'מעקב אחר קריאות ל-API', בכלי 'מעקב' או ביומני הגישה של NGINX, כמו שמוסבר בשלבים הנפוצים לאבחון.
  2. אם קוד השגיאה הוא messaging.adaptors.http.flow.DecompressionFailureAtRequest ומקור השגיאה הוא policy או proxy, המשמעות היא שהבקשה שנשלחה מאפליקציית הלקוח מכילה מטען ייעודי (payload) שלא תואם לContent-Encoding
  3. אפשר לקבוע את אי ההתאמה כחלק מבקשת ה-HTTP באמצעות אחת מהשיטות הבאות:

    הודעת שגיאה

    כדי לאמת באמצעות הודעת השגיאה:

    1. אם יש לכם גישה להודעת השגיאה המלאה שהתקבלה מ-Apigee Edge, תוכלו לעיין בfaultstring.

      הודעת שגיאה לדוגמה:

      "faultstring":"Decompression failure at request"
    2. בהודעת השגיאה שלמעלה מוצג "Decompression failure at request", מה שאומר שלא הייתה אפשרות לבטל את הדחיסה של הבקשה באמצעות הקידוד שצוין בכותרת Content-Encoding.

    מעקב

    כדי לבצע אימות באמצעות הכלי Trace:

    1. כדי לקבוע את הערך של כותרת הבקשה Content-Encoding ואת המאפיין error.cause, משתמשים ב-Trace כמו שמוסבר בשלבים נפוצים לאבחון.
    2. הערכים מהדוגמה של נתוני המעקב הם:

      • Content-Encoding: gzip
      • error.cause: Not in GZIP format

      הערך ב-request header Content-Encoding הוא gzip; אבל מטען הייעודי (payload) של הבקשה לא בפורמט GZIP (כפי שמצוין ב-error.cause). לכן, Apigee Edge מגיב עם קוד השגיאה 400 Bad Request וקוד השגיאה messaging.adaptors.http.flow.DecompressionFailureAtRequest.

    הבקשה בפועל

    כדי לאמת באמצעות הבקשה בפועל:

    אם יש לכם גישה לבקשה בפועל שבוצעה על ידי אפליקציית הלקוח, צריך לבצע את השלבים הבאים:

    1. קובעים את הערך שמועבר לכותרת הבקשה Content-Encoding.
    2. קובעים את הפורמט של המטען הייעודי (Payload) שנשלח כחלק מהבקשה.
    3. אם הערך של הכותרת Content-Encoding מופיע ברשימה של קידוד נתמך אבל הפורמט של מטען הבקשה לא תואם לקידוד שצוין בכותרת Content-Encoding, אז זו הסיבה לבעיה.

      בקשה לדוגמה:

      curl -v "http://HOSTALIAS/v1/testgzip" -H "Content-Encoding: gzip" -X POST -d @request_payload.zip
      

      בדוגמה של הבקשה שלמעלה, הערך gzip נשלח לכותרת Content-Encoding, שהיא קידוד נתמך ב-Apigee Edge. עם זאת, מטען הייעודי (payload) של הבקשה request_payload.zip הוא בפורמט ZIP. לכן, הבקשה הזו נכשלת עם קוד סטטוס 400 Bad Request וקוד השגיאה: messaging.adaptors.http.flow.DecompressionFailureAtRequest.

    יומנים של מעבד הודעות

    כדי לבצע אימות באמצעות יומני מעבד בקשות:

    אם אתם משתמשים ב-Private Cloud, אתם יכולים להשתמש ביומני מעבד בקשות כדי לקבוע את פרטי המפתח לגבי שגיאות HTTP 400.

    1. כדי לקבוע את מזהה ההודעה של הבקשה שנכשלה, משתמשים בכלי המעקב, בכלי לניתוח נתונים או ביומני הגישה של NGINX, כמו שמוסבר בשלבים נפוצים לאבחון.
    2. מחפשים את מזהה ההודעה ביומן של מעבד ההודעות:

      /opt/apigee/var/log/edge-message-processor/logs/system.log

    3. יוצג אחד מהחריגים הבאים:

      תרחיש #1

      תרחיש מספר 1: כשבקשת API כוללת את הכותרת Content-Encoding: gzip

      2021-07-28 10:21:16,861  NIOThread@0 ERROR HTTP.SERVER -
      HTTPServer$Context.onInputException() : Message id:rt-57-1
      SSLClientChannel[Accepted: Remote:192.168.199.8:8443
      Local:192.168.80.234:44284]@28469 useCount=1 bytesRead=0
      bytesWritten=28764 age=2739893ms  lastIO=0ms
      isOpen=true.onExceptionRead exception: {}
      java.util.zip.ZipException: Not in GZIP format
      
      2021-07-28 10:21:16,862  NIOThread@0 ERROR ADAPTORS.HTTP.FLOW -
      AbstractRequestListener.onException() : Request:POST, uri:/test,
      message Id:rt-57-1, exception:java.util.zip.ZipException: Not in GZIP format,
      context:Context@71ea5ac input=ClientInputChannel(SSLClientChannel[Accepted:
      Remote:192.168.199.8:8443 Local:192.168.80.234:44284]@28469 useCount=1
      bytesRead=0 bytesWritten=28764 age=2739894ms  lastIO=0ms  isOpen=true)
      2021-07-28 10:21:16,862  NIOThread@0 INFO  HTTP.SERVICE -
      ExceptionHandler.handleException() :
      Exception java.util.zip.ZipException: Not in GZIP format occurred while writing
      to channel null
      2021-07-28 10:21:16,863  NIOThread@0 INFO  HTTP.SERVICE -
      ExceptionHandler.handleException() : Exception trace:
      java.util.zip.ZipException: Not in GZIP format
      

      השורה java.util.zip.ZipException: Not in GZIP format בהודעת השגיאה שלמעלה מציינת שמטען הבקשה לא נשלח בפורמט GZIP, למרות ש-Content-Encoding מצוין כ-gzip. לכן, Apigee Edge מעלה את החריגה ומחזיר קוד סטטוס 400 עם קוד שגיאה messaging.adaptors.http.flow.DecompressionFailureAtRequest לאפליקציות לקוח.

      תרחיש מספר 2

      תרחיש מספר 2: כשבקשת API כוללת את הכותרת Content-Encoding: deflate

      2021-07-28 15:26:31,893  NIOThread@1 ERROR HTTP.SERVER -
      HTTPServer$Context.onInputException() : Message id:rt-47875-1
      SSLClientChannel[Accepted: Remote:192.168.199.8:8443
      Local:192.168.81.72:45954]@29276 useCount=1 bytesRead=0
      bytesWritten=37230 age=3498856ms  lastIO=1ms
      isOpen=true.onExceptionRead exception: {}
      java.util.zip.ZipException: incorrect header check
                        ….
      Caused by: java.util.zip.DataFormatException: incorrect header check
             ..
      2021-07-28 15:26:31,894  NIOThread@1 ERROR ADAPTORS.HTTP.FLOW -
      AbstractRequestListener.onException() : Request:POST, uri:/test,
      message Id:rrt-47875-1, exception:java.util.zip.ZipException:
      incorrect header check, context:Context@69b3ac45
      input=ClientInputChannel(SSLClientChannel[Accepted:
      Remote:192.168.199.8:8443 Local:192.168.81.72:45954]@29276
      useCount=1 byt	esRead=0 bytesWritten=37230 age=3498856ms
      lastIO=1ms  isOpen=true)
      

      השורות java.util.zip.ZipException: incorrect header check ו- Caused by: java.util.zip.DataFormatException: incorrect header check בהודעת השגיאה שלמעלה מציינות שמטען הייעודי (payload) של הבקשה לא נשלח בפורמט deflate ולא תואם לקידוד שצוין בכותרת Content-Encoding של deflate. לכן, Apigee Edge מפעיל את החריגה ומחזיר קוד סטטוס 400 עם קוד שגיאה messaging.adaptors.http.flow.DecompressionFailureAtRequest לאפליקציות לקוח.

רזולוציה

  1. אם אין צורך במטען הייעודי (payload) של הבקשה הדחוסה בתהליך של שרת proxy ל-API ב-Apigee Edge ובשרת הקצה העורפי, אל תעבירו את הכותרת Content-Encoding. אם יש צורך לדחוס את מטען הייעודי (payload) של הבקשה, עוברים לשלב 2.
  2. מוודאים שאפליקציית הלקוח תמיד שולחת את הפרטים הבאים:
    • אחד מ הקידודים הנתמכים בתור הערך של הכותרת Content-Encoding בבקשה
    • מטען הייעודי (payload) של הבקשה בפורמט הנתמך ל-Apigee Edge תואם לפורמט הקידוד שצוין בכותרת Content-Encoding
  3. בדוגמה שצוינה למעלה, מטען הייעוד של הבקשה הוא בפורמט ZIP, אבל בכותרת הבקשה מצוין Content-Encoding: gzip. כדי לפתור את הבעיה, צריך לשלוח את כותרת הבקשה כ-Content-Encoding: gzip ואת מטען הבקשה גם בפורמט gzip:
    curl -v "https://HOSTALIAS/v1/testgzip" -H "Content-Encoding: gzip" -X POST -d @request_payload.gz
    

מפרט

‫Apigee Edge מגיב עם קוד הסטטוס 400 Bad Request וקוד השגיאה messaging.adaptors.http.flow.DecompressionFailureAtRequest, בהתאם למפרטים הבאים של RFC:

מפרט
RFC 7231, section 6.5.1
RFC 7231, section 3.1.2.2

אם עדיין דרושה לך עזרה מצוות התמיכה של Apigee, אפשר לעבור אל איסוף מידע לצורך אבחון.

צריך לאסוף פרטי אבחון

אוספים את נתוני האבחון הבאים ופונים אל התמיכה של Apigee Edge:

אם אתם משתמשי ענן ציבורי, עליכם לספק את הפרטים הבאים:

  • שם הארגון
  • שם הסביבה
  • שם ה-proxy ל-API
  • הפקודה curl שבה השתמשת כדי לשחזר את השגיאה 400
  • קובץ מעקב לבקשות ה-API

אם אתם משתמשים ב-Private Cloud, עליכם לספק את הפרטים הבאים:

  • הודעת השגיאה המלאה שזוהתה בבקשות שנכשלו
  • שם הסביבה
  • חבילת proxy ל-API
  • קובץ מעקב לבקשות ה-API
  • יומני גישה של NGINX /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    הסבר: מחליפים את ORG, ‏ ENV ו-PORT# בערכים בפועל.

  • יומני מערכת של מעבד ההודעות /opt/apigee/var/log/edge-message-processor/logs/system.log