400 Неверный запрос — DecompressionFailureAtRequest

Вы просматриваете документацию Apigee Edge .
Перейдите в документацию Apigee
X.info

Симптом

В ответ на вызовы API клиентское приложение получает HTTP-статус 400 Bad Request с кодом ошибки messaging.adaptors.http.flow.DecompressionFailureAtRequest .

Сообщение об ошибке

Клиентское приложение получает следующий код ответа:

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 не может декодировать полезную нагрузку, используя указанную кодировку, поскольку формат полезной нагрузки не совпадает с форматом кодировки, указанной в заголовке Content-Encoding .

Вот несколько примеров поддерживаемых значений Content-Encoding и того, какой формат полезной нагрузки ожидает Apigee Edge в этих случаях:

Сценарий Кодирование контента Ожидаемый формат полезной нагрузки
Единое кодирование gzip

Формат Unix gzip .

См. RFC1952 Формат GZIP .

Единое кодирование сдуть

В этом формате используется структура zlib с алгоритмом сжатия deflate.

См. RFC1950 и RFC1951 .

Множественное кодирование

Множественное кодирование

Например, в случаях, когда кодирование выполняется дважды, это может выглядеть так:

  • gzip, deflate
  • gzip, gzip
  • сдуть, gzip
  • сдуть, сдуть
К полезной нагрузке применяется множественное кодирование в указанном порядке, как оно представлено в заголовке.

Возможные причины этой ошибки следующие:

Причина Описание Инструкции по устранению неполадок, применимые для
Формат полезной нагрузки запроса не соответствует кодировке, указанной в заголовке Content-Encoding. Формат полезной нагрузки запроса, отправляемого клиентом, либо не закодирован, либо не соответствует кодировке, указанной в заголовке Content-Encoding . Пользователи публичных и частных облачных сервисов на периферии сети

Общие этапы диагностики

Для диагностики этой ошибки воспользуйтесь одним из следующих инструментов/методов:

Мониторинг API

Для диагностики ошибки с помощью мониторинга API:

  1. Войдите в пользовательский интерфейс Apigee Edge под учетной записью пользователя с соответствующей ролью .
  2. Переключитесь на организацию, в которой вы хотите расследовать проблему.

  3. Перейдите на страницу Анализ > Мониторинг API > Исследование .
  4. Выберите конкретный временной промежуток, в течение которого вы наблюдали ошибки.
  5. Убедитесь, что для фильтра прокси установлено значение «Все» .
  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 , это означает, что формат полезной нагрузки запроса не соответствует поддерживаемой кодировке, указанной в заголовке Content-Encoding .

инструмент трассировки

Для диагностики ошибки с помощью инструмента трассировки:

  1. Включите сеанс трассировки и выполните одно из следующих действий:
    1. Дождитесь появления ошибки 400 Bad Request , или
    2. Если вы можете воспроизвести проблему, выполните вызов API и воспроизведите ошибку 400 Bad Request .
  2. Убедитесь, что параметр «Показывать все FlowInfos» включен:

  3. Выберите один из запросов, завершившихся неудачей, и изучите трассировку.
  4. Проследите за различными этапами трассировки и определите место возникновения сбоя.
  5. Как правило, ошибка обнаруживается в процессе обработки запроса сразу после этапа «Запрос получен от клиента» , как показано ниже:

    ( Посмотреть увеличенное изображение )

  6. Обратите внимание на значения свойств из трассировки:

    • Ошибка: Decompression failure at request
    • error.class : com.apigee.rest.framework.BadRequestException
    • error.cause: Not in GZIP format

    В сообщении об ошибке указано, что полезная нагрузка запроса НЕ находится в формате GZIP. Это означает, что Apigee Edge ожидал, что полезная нагрузка запроса будет в формате GZIP, поскольку это должно было быть указано в заголовке Content-Encoding .

  7. Определите значение заголовка запроса Content-Encoding . Для этого перейдите к этапу «Запрос получен от клиента», как показано ниже:

    ( Посмотреть увеличенное изображение )

    Обратите внимание, что значение заголовка запроса Content-Encoding действительно равно gzip .

    Приведенный выше пример трассировки показывает, что в заголовке запроса Content-Encoding указана кодировка gzip ; однако полезная нагрузка запроса не в формате GZIP. Поэтому Apigee не может распаковать полезную нагрузку с использованием 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 Data Recorded) в трассировке и щелкните по нему.

  10. Прокрутите вниз до раздела «Подробности этапа» , «Заголовки ошибок» и определите значения 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 .
    Заголовки ответа Ценить
    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-source:

    Заголовки ответа Ценить
    X-Apigee-fault-code messaging.adaptors.http.flow.DecompressionFailureAtRequest
    X-Apigee-fault-source policy

Причина: Формат полезной нагрузки запроса не соответствует кодировке, указанной в заголовке Content-Encoding.

По умолчанию Apigee Edge всегда распаковывает полезную нагрузку, если заголовок запроса Content-Encoding содержит допустимую и поддерживаемую кодировку . Поэтому ожидается, что формат полезной нагрузки запроса будет соответствовать кодировке, указанной в заголовке запроса Content-Encoding . В случае несоответствия вы получите эту ошибку.

Диагноз

  1. Определите код ошибки и источник ошибки, используя мониторинг API, инструмент трассировки или журналы доступа NGINX, как описано в разделе «Общие шаги диагностики» .
  2. Если код ошибки равен messaging.adaptors.http.flow.DecompressionFailureAtRequest , а источник ошибки имеет значение policy или proxy , это указывает на то, что запрос, отправленный клиентским приложением, содержит полезную нагрузку, которая не соответствует поддерживаемой кодировке, указанной в заголовке запроса 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 с помощью трассировки , как описано в разделе «Общие шаги диагностики» .
    2. Значения, полученные из образца трассировки, следующие:

      • Content-Encoding: 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 присутствует в списке поддерживаемых кодировок, но формат полезной нагрузки запроса не соответствует кодировке, указанной в заголовке Content-Encoding , то это и является причиной проблемы.

      Пример запроса:

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

      Приведенный выше пример запроса отправляет значение gzip в заголовок Content-Encoding , который является поддерживаемой кодировкой в ​​Apigee Edge. Однако полезная нагрузка запроса request_payload.zip имеет формат ZIP. Поэтому этот запрос завершается с ошибкой 400 Bad Request и кодом ошибки: messaging.adaptors.http.flow.DecompressionFailureAtRequest .

    Журналы обработчика сообщений

    Для проверки с использованием журналов обработчика сообщений:

    Если вы используете частное облако , то можете использовать журналы обработчика сообщений для получения ключевой информации об ошибках HTTP 400 .

    1. Определите идентификатор сообщения неудачного запроса, используя мониторинг API, инструмент трассировки или журналы доступа 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 в приведенном выше сообщении об ошибке указывают на то, что полезная нагрузка запроса отправлена ​​не в формате deflate и не соответствует кодировке, указанной в заголовке Content-Encoding пакета deflate. Поэтому Apigee Edge генерирует исключение и возвращает клиентским приложениям код состояния 400 с кодом ошибки messaging.adaptors.http.flow.DecompressionFailureAtRequest .

Разрешение

  1. Если в потоке API-прокси в Apigee Edge и на бэкэнд-сервере нет необходимости в сжатом содержимом запроса, то не передавайте заголовок Content-Encoding . Если же сжатие содержимого запроса необходимо, перейдите к шагу 2.
  2. Убедитесь, что клиентское приложение всегда отправляет следующее:
    • В качестве значения заголовка Content-Encoding в запросе можно указать любую из поддерживаемых кодировок.
    • Запрос к 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, раздел 6.5.1
RFC 7231, раздел 3.1.2.2

Если вам по-прежнему нужна помощь службы поддержки Apigee, перейдите по ссылке «Необходимо собрать диагностическую информацию» .

Необходимо собрать диагностическую информацию.

Соберите следующую диагностическую информацию, а затем свяжитесь со службой поддержки Apigee Edge :

Если вы являетесь пользователем публичного облака , предоставьте следующую информацию:

  • Название организации
  • Название среды
  • Имя API-прокси
  • Полная команда curl , использованная для воспроизведения ошибки 400
  • Файл трассировки для запросов API

Если вы являетесь пользователем частного облака , предоставьте следующую информацию:

  • Полное сообщение об ошибке, полученное для неудачных запросов.
  • Название среды
  • Пакет 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