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"
      }
   }
}

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

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

  • הקידוד שצוין בכותרת בקשת ה-HTTP Content-Encoding תקין ו נתמך על ידי Apigee Edge.
  • אבל

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

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

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

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

פורמט Unix gzip.

פרטים נוספים זמינים במאמר פורמט RFC1952 GZIP.

קידוד יחיד deflate

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

פרטים נוספים זמינים ב- RFC1950 וב- RFC1951.

קידוד מרובה

קידוד מרובה

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

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

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

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

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

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

מעקב באמצעות API

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

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

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

    ( הצגת תמונה גדולה יותר)

  8. מידע על קוד התקלה messaging.adaptors.http.flow.DecompressionFailureAtRequest מוצג באופן שמוצג למטה:

    ( הצגת תמונה גדולה יותר)

  9. לוחצים על View Logs (הצגת היומנים) ומרחיבים את השורה שבה הופיעה השגיאה 400.

    ( הצגת תמונה גדולה יותר)

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

כלי המעקב

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

  1. מפעילים את הפעלת המעקב וגם:
    1. להמתין עד שהשגיאה 400 Bad Request תתרחש, או
    2. אם הצלחת לשחזר את הבעיה, יש לבצע את הקריאה ל-API ולשחזר את 400 Bad Request.
  2. יש לוודא שהאפשרות Show allflowInfos מופעלת:

  3. בוחרים אחת מהבקשות שנכשלו ובודקים את המעקב.
  4. אפשר לנווט בין השלבים השונים של המעקב ולאתר את המיקום שבו אירעה הכשל.
  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 ציפה שהמטען הייעודי (payload) של הבקשה יהיה בפורמט GZIP כפי שצוין בכותרת Content-Encoding.

  7. קביעת הערך של כותרת הבקשה Content-Encoding. כדי לעשות זאת, צריך לעבור לשלב הבקשה התקבלה מהלקוח, כפי שמוצג כאן:

    ( הצגת תמונה גדולה יותר)

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

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

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

    לשלב תגובה שנשלחה ללקוח במעקב באופן הבא:

    ( הצגת תמונה גדולה יותר)

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

    • קוד סטטוס: 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. הערכים האלה מציינים שפורמט המטען הייעודי של הבקשה לא תואם לקידוד שצוין בכותרת Content-Encoding.
    כותרות תגובה Value
    X-Apigee-fault-code messaging.adaptors.http.flow.DecompressionFailureAtRequest
    X-Apigee-fault-source policy

NGINX

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

  1. אם אתם משתמשים בענן פרטי, אתם יכולים להשתמש ביומני הגישה של 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-code

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

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

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

אבחון

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

    הודעת השגיאה

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

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

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

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

    נתוני מעקב

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

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

      • קידוד תוכן: gzip
      • error.cause: Not in GZIP format

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

    בקשה בפועל

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

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

    1. יש לקבוע את הערך שהועבר לכותרת הבקשה Content-Encoding.
    2. יש לקבוע את הפורמט של המטען הייעודי שנשלח כחלק מהבקשה.
    3. אם הערך של הכותרת Content-Encoding מופיע ברשימת הקידודים הנתמכים אבל הפורמט של המטען הייעודי (payload) של הבקשה לא תואם לקידוד שצוין בכותרת 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.

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

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

    משתמשים בענן פרטי יכולים להיעזר ביומנים של מעבד ההודעות כדי לגלות את המידע החשוב לגבי שגיאות HTTP מסוג 400.

    1. אפשר לאתר את מזהה ההודעה של הבקשה שנכשלה באמצעות API Monitoring, הכלי למעקב או יומני גישה של 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 בהודעת השגיאה שלמעלה מציינת שמטען הייעודי (payload) של הבקשה לא נשלח בפורמט 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) של הבקשה הדחוסה בתהליך ה-API של שרת ה-proxy ב-Apigee Edge ובשרת הקצה העורפי, אין להעביר את הכותרת Content-Encoding. אם יש צורך לדחוס את המטען הייעודי (payload) של הבקשה, עוברים לשלב 2.
  2. מוודאים שאפליקציית הלקוח תמיד שולחת את הפרטים הבאים:
    • כל אחד מ הקידודים הנתמכים בתור הערך של הכותרת Content-Encoding בבקשה
    • המטען הייעודי (payload) של הבקשה בפורמט הנתמך ל-Apigee Edge תואם לפורמט הקידוד שצוין בכותרת Content-Encoding
  3. בדוגמה שלמעלה, המטען הייעודי (payload) של הבקשה הוא בפורמט ZIP אבל בכותרת הבקשה צוין Content-Encoding: gzip. כדי לפתור את הבעיה, אפשר לשלוח את כותרת הבקשה בתור Content-Encoding: gzip והמטען הייעודי (payload) של הבקשה גם בפורמט 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, סעיף 6.5.1
RFC 7231, סעיף 3.1.2.2

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

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

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

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

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

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

  • זוהתה הודעת שגיאה מלאה בבקשות שנכשלו
  • שם הסביבה
  • חבילת שרת 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