400 Bad request — обычный HTTP-запрос отправлен на HTTPS-порт

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

Симптом

Клиентское приложение получает ответ HTTP 400 Bad Request с сообщением " The plain HTTP request was sent to HTTPS port .

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

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

HTTP/1.1 400 Bad Request

Далее следует HTML-страница с ошибкой:

<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
</body>
</html>

Возможные причины

Причина Описание Инструкции по устранению неполадок, применимые для
HTTP-запрос к виртуальному хосту с настроенным TLS. Клиент отправляет HTTP-запрос на виртуальный хост, настроенный с использованием TLS. Пользователи публичных и частных облачных сервисов на периферии сети
HTTP-запрос к целевой конечной точке, настроенной с использованием TLS. HTTP-запрос, отправленный на сервер бэкэнда с поддержкой TLS в целевой конечной точке. Пользователи публичных и частных облачных сервисов на периферии сети
Неправильная конфигурация целевого сервера. Целевой сервер настроен на использование защищенного порта 443 , но SSL не включен. Пользователи публичных и частных облачных сервисов на периферии сети

Причина: HTTP-запрос к виртуальному хосту с настроенным TLS.

Эта ошибка возникает, когда клиент пытается подключиться к API в Apigee, а указанный виртуальный хост настроен на использование SSL и вместо этого получает HTTP-запрос.

Диагноз

Поскольку эта проблема возникает на северном конце сети, и запросы API завершаются с ошибкой на этапе взаимодействия между клиентским приложением и маршрутизатором, эти сообщения об ошибках не регистрируются в журналах доступа маршрутизатора NGINX. Следовательно, эти запросы не будут фиксироваться такими инструментами, как мониторинг API и инструмент трассировки.

  1. Проверьте свой API-запрос и убедитесь, что вы отправляете HTTP-запрос к псевдониму хоста, который настроен на прием запросов только через защищенный порт 443 Если это так, то это и есть причина проблемы.

    Пример некорректного запроса к API:

    curl http://org-test.apigee.net:443/400-demo
    
    <html>
    <head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
    <body>
    <center><h1>400 Bad Request</h1></center>
    <center>The plain HTTP request was sent to HTTPS port</center>
    <hr><center>server</center>
    </body>
    </html>
  2. В приведенном выше примере запроса обратите внимание, что HTTP-запрос отправляется на хост с псевдонимом myorg-test.apigee.net через защищенный порт 443 Это и является причиной ошибки 400 Bad Request .

Разрешение

Необходимо проверить, использует ли клиент протокол HTTP вместо HTTPS, и отправить корректный запрос, как показано ниже:

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

curl https://org-test.apigee.net:443/400-demo

или

curl https://org-test.apigee.net/400-demo
< HTTP/1.1 200 OK
< Date: Thu, 25 Feb 2021 13:01:43 GMT
< Content-Type: text/xml;charset=UTF-8
< Content-Length: 403
< Connection: keep-alive
< Server: gunicorn/19.9.0
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true

Причина: HTTP-запрос к целевой конечной точке, для которой настроен TLS.

Эта ошибка возникает, если вы неправильно настроили HTTP-запросы к серверу бэкэнда с поддержкой TLS в целевой конечной точке API-прокси.

Диагноз

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

  1. Включите трассировку в пользовательском интерфейсе Apigee для затронутого API-прокси.
  2. Отправляйте запросы к API-прокси.
  3. Выберите один из запросов API, завершившихся ошибкой с кодом ответа 400 .
  4. Пройдите через различные этапы и определите, где произошла ошибка.
  5. Как правило, от бэкэнд-сервера приходит сообщение об ошибке 400 То есть, сообщение об ошибке 400 появляется на этапе "Получен ответ от целевого сервера", как показано ниже:

  6. Определите целевую конечную точку, для которой был сделан запрос, щелкнув значок AX (Analytics Data Recorded) в трассировке.

  7. Обратите внимание на target.url , который содержит протокол, псевдоним хоста бэкэнд-сервера и иногда номер порта. Порт, используемый для целевого URL, — 443 , но протокол — HTTP.
  8. Ознакомьтесь с определением целевой конечной точки, чтобы понять конфигурацию.
  9. Убедитесь, что серверная часть защищена и использует безопасный порт, например, 443 Если в элементе <URL> используется протокол http , то это и является причиной проблемы.

    Пример конфигурации целевой конечной точки:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <TargetEndpoint name="default">
        <Description/>
        <FaultRules/>
        <PreFlow name="PreFlow">
            <Request/>
            <Response/>
        </PreFlow>
        <PostFlow name="PostFlow">
            <Request/>
            <Response/>
        </PostFlow>
        <Flows/>
        <HTTPTargetConnection>
            <Properties/>
            <URL>http://somehost.org:443/get</URL>
        </HTTPTargetConnection>
    </TargetEndpoint>

    В приведенном выше примере показано, что вы используете протокол HTTP, но используется защищенный порт 443 Это приводит к тому, что серверная часть отвечает ошибкой 400 Bad Request и сообщением об ошибке The plain HTTP request was sent to HTTPS port .

Разрешение

  1. Если ваш сервер защищен/поддерживает TLS, убедитесь, что в элементе <URL> целевой конечной точки используется протокол https , как показано в следующем примере:

    Пример конфигурации целевой конечной точки:

    <HTTPTargetConnection>
        <Properties/>
        <URL>https://somehost.org:443/get</URL>
    </HTTPTargetConnection>
  2. Если ваш сервер небезопасен , то:

    • Не указывайте номер защищенного порта, например, 443 .
    • Если ваш бэкэнд-сервер использует стандартный незащищенный порт, указывать номер порта вообще необязательно.
    • Укажите номер порта, если вы используете какой-либо другой незащищенный порт, например: 9080

    Пример конфигурации целевой конечной точки:

    <HTTPTargetConnection>
        <Properties/>
        <URL>http://somehost.org/get</URL>
    </HTTPTargetConnection>
    
    or
    
    <HTTPTargetConnection>
        <Properties/>
        <URL>http://somehost.org:9080/get</URL>
    </HTTPTargetConnection>

Причина: Неправильная конфигурация целевого сервера.

Если целевой сервер настроен с использованием защищенного порта, например 443 без включения SSL, это приводит к тому, что обработчик сообщений Apigee Edge отправляет HTTP-запросы на защищенный или настроенный с использованием TLS целевой сервер, что и вызывает эту проблему.

Диагноз

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

  1. Включите трассировку в пользовательском интерфейсе Apigee для затронутого API-прокси.
  2. Отправляйте запросы к API-прокси.
  3. Выберите один из запросов API, завершившихся ошибкой с кодом ответа 400 .
  4. Пройдите через различные этапы и определите, где произошла ошибка.
  5. Как правило, от бэкэнд-сервера приходит сообщение об ошибке 400 То есть, сообщение об ошибке 400 появляется на этапе "Получен ответ от целевого сервера", как показано ниже:

  6. Определите целевую конечную точку, для которой был сделан запрос, щелкнув значок AX (Analytics Data Recorded) в трассировке.

  7. Обратите внимание на target.name , которое представляет собой имя целевой конечной точки.

    В приведенном выше примере файла трассировки target.name имеет значение default . Это указывает на то, что целевой конечной точкой, используемой для этого запроса, является default.

  8. Ознакомьтесь с определением целевой конечной точки, чтобы понять конфигурацию.

    Пример конфигурации целевой конечной точки:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <TargetEndpoint name="default">
        <Description/>
        <FaultRules/>
        <PreFlow name="PreFlow">
            <Request/>
            <Response/>
        </PreFlow>
        <PostFlow name="PostFlow">
            <Request/>
            <Response/>
        </PostFlow>
        <Flows/>
        <HTTPTargetConnection>
            <Properties/>
            <LoadBalancer>
            <Server name="faulty-target"/>
            </LoadBalancer>
        </HTTPTargetConnection>
    </TargetEndpoint>

    Приведенный выше пример конфигурации целевой конечной точки показывает, что вы используете целевой сервер с именем faulty-target .

  9. Получив имя целевого сервера, вы можете использовать один из следующих методов для проверки конфигурации целевого сервера:

    • Edge UI
    • API управления

Edge UI

  1. Перейдите в Apigee Edge > Администрирование > Среды > Целевые серверы .
  2. Выберите конкретный целевой сервер, определенный через API-прокси, и нажмите » .
  3. Проверьте порт, указанный для целевого сервера, и информацию SSL.
  4. Если целевой сервер настроен на использование защищенного порта (например, 443 ), но SSL не включен, то это и является причиной проблемы.

    Как видно на скриншоте выше, используется порт 443 , но SSL для этого порта не включен в конфигурации целевого сервера. Это приводит к тому, что обработчик сообщений Apigee Edge отправляет HTTP-запросы на защищенный порт 443 В результате вы получаете ошибку 400 Bad Request с сообщением The plain HTTP request was sent to HTTPS port .

API управления

  1. Для получения подробной информации о конфигурации конкретного целевого сервера выполните вызов API Get target server , как показано ниже:

    Пользователь публичного облака:

    curl -v 'https://api.enterprise.apigee.com/v1/organizations/ORG_NAME/environments/ENV_NAME>/targetservers/TARGET_SERVER_NAME' \
    -H "Content-Type:application/xml" \
    -H "Authorization:Bearer $TOKEN"
    

    Пользователь частного облака:

    curl -v 'http://MANAGEMENT_IP:8080/v1/organizations/ORG_NAME/environments/ENV_NAME/targetservers/TARGET_SERVER_NAME' \
    -H "Content-Type:application/xml" \
    -H "Authorization:Bearer $TOKEN"
    
  2. Проверьте порт, указанный для целевого сервера, и информацию SSL.
  3. Если целевой сервер настроен с использованием защищенного порта (например, 443 ), но раздел SSLInfo не определен или не включен, то это и является причиной проблемы.

    Пример конфигурации целевого сервера:

    {
      "host" : "somehost.org",
      "isEnabled" : true,
      "name" : "faulty-target",
      "port" : 443
    }

    В приведенном выше примере выходных данных видно, что для целевого соединения используется порт 443 , но блок конфигурации SSLInfo отсутствует.

    Это приводит к тому, что обработчик сообщений Apigee Edge отправляет HTTP-запросы на защищенный порт 443 В результате вы получаете ошибку 400 Bad Request с сообщением " The plain HTTP request was sent to HTTPS port .

Разрешение

Если целевой сервер защищен или использует протокол TLS, то необходимо включить SSL для этого конкретного целевого сервера.

Это можно сделать, используя один из следующих вариантов:

  • Edge UI
  • API управления

Edge UI

  1. Перейдите к целевому серверу в пользовательском интерфейсе Edge > Администрирование > Среды > Целевые серверы .
  2. Выберите конкретный целевой сервер и нажмите » .
  3. Если целевой сервер защищен и использует порт, например, 443 , включите SSL, установив флажок рядом с параметром SSL.
  4. Настройте хранилище доверенных сертификатов , шифры и протоколы . (Только при необходимости)

API управления

Используйте API управления для настройки целевого сервера, как описано в документации по обновлению конфигурации целевого сервера .

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

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

  1. Если вы являетесь пользователем публичного облака , предоставьте следующую информацию:
    • Название организации
    • Название среды
    • Имя API-прокси
    • Выполните команду curl для воспроизведения ошибки.
    • Вывод инструмента трассировки (если вам удалось получить данные для запроса, завершившегося с ошибкой).
  2. Если вы являетесь пользователем частного облака , предоставьте следующую информацию:
    • Полное сообщение об ошибке
    • Название среды
    • пакет API-прокси
    • Определение целевого сервера (если вы используете целевой сервер в своей конечной точке)
    • Вывод инструмента трассировки (если вам удалось получить данные для запроса, завершившегося с ошибкой).