Solicitud incorrecta 400: Solicitud HTTP sin formato enviada al puerto HTTPS

Estás consultando la documentación de Apigee Edge.
Consulta la documentación de Apigee X.
Información

Síntoma

La aplicación cliente recibe una respuesta HTTP 400 Bad Request con el mensaje The plain HTTP request was sent to HTTPS port.

Mensaje de error

La aplicación cliente obtiene el siguiente código de respuesta:

HTTP/1.1 400 Bad Request

Seguido de la siguiente página de error 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>

Causas posibles

Causa Descripción Instrucciones de solución de problemas aplicables para
Solicitud HTTP a un host virtual configurado con TLS El cliente envía una solicitud HTTP a un host virtual configurado con TLS. Usuarios de la nube pública y privada de Edge
Solicitud HTTP a un extremo de destino configurado con TLS Solicitud HTTP realizada a un servidor de backend con TLS habilitado en el extremo de destino. Usuarios de la nube pública y privada de Edge
Configuración incorrecta del servidor de destino El servidor de destino está configurado con el puerto seguro 443, pero SSL no está habilitado. Usuarios de la nube pública y privada de Edge

Causa: solicitud HTTP a un host virtual configurado con TLS

Este error ocurre cuando un cliente intenta conectarse a una API en Apigee y el host virtual mencionado se configura para usar SSL y, en su lugar, recibe una solicitud HTTP.

Diagnóstico

Dado que este problema ocurre en el extremo Northbound y las solicitudes a la API fallan en la interacción del punto de entrada entre la aplicación cliente y el router, estos mensajes de error no se registran en los registros de acceso del router NGINX. Por lo tanto, estas solicitudes no se capturarán en herramientas como la supervisión de API y la herramienta de seguimiento.

  1. Verifica tu solicitud a la API y comprueba si realizas una solicitud HTTP a un alias de host configurado para aceptar solicitudes solo en el puerto seguro 443. Si es así, esa es la causa del problema.

    Ejemplo de solicitud a la API incorrecto:

    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. En la solicitud de ejemplo anterior, ten en cuenta que se realiza una solicitud HTTP al alias del host myorg-test.apigee.net en el puerto seguro 443. Esa es la causa del error 400 Bad Request.

Resolución

Debes verificar si el cliente usa HTTP en lugar de HTTPS y realizar la solicitud correcta como se muestra a continuación:

Ejemplo de solicitud a la API:

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

o

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

Causa: solicitud HTTP a un extremo de destino configurado con TLS

Este error se produce si configuraste de forma incorrecta las solicitudes HTTP a un servidor de backend con TLS habilitado en el extremo de destino de un proxy de API.

Diagnóstico

Sigue estos pasos para diagnosticar el error con la herramienta Trace:

  1. Habilita Trace en la IU de Apigee para el proxy de API afectado.
  2. Realizar solicitudes al proxy de API
  3. Selecciona una de las solicitudes a la API que fallaron con el código de respuesta 400.
  4. Navega por las distintas fases y determina dónde ocurrió la falla.
  5. Por lo general, verás la respuesta de error 400 que proviene del servidor de backend. Es decir, verás la respuesta de error 400 en la fase Respuesta recibida del servidor de destino, como se muestra a continuación:

  6. Haz clic en el ícono AX (datos registrados de Analytics) del seguimiento para determinar el extremo de destino para el que se realizó la solicitud.

  7. Ten en cuenta el target.url, que contiene el protocolo, el alias del host del servidor de backend y, a veces, el número de puerto. El puerto que se usa para la URL de destino es 443, pero el protocolo es HTTP.
  8. Revisa la definición del extremo de destino para comprender la configuración.
  9. Verifica que el host del servidor de backend sea seguro y que escuche en un puerto seguro, como 443. Si usas el protocolo como http en el elemento <URL>, entonces esa es la causa del problema.

    Configuración del extremo de destino de muestra:

    <?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>
    

    En el ejemplo anterior, se muestra que usas el protocolo HTTP, pero el puerto que se usa es el puerto seguro 443. Esto hace que el servidor de backend responda con 400 Bad Request y el mensaje de error The plain HTTP request was sent to HTTPS port.

Resolución

  1. Si tu servidor de backend es seguro o está habilitado para TLS, asegúrate de usar el protocolo como https en el elemento <URL> del extremo de destino, como se muestra en el siguiente ejemplo:

    Configuración del extremo de destino de muestra:

    <HTTPTargetConnection>
        <Properties/>
        <URL>https://somehost.org:443/get</URL>
    </HTTPTargetConnection>
    
  2. Si tu servidor de backend no es seguro, sucede lo siguiente:

    • No menciones el número de puerto seguro, como 443.
    • Si tu servidor de backend escucha en un puerto estándar no seguro, no necesitas mencionar el número de puerto en absoluto.
    • Menciona el número de puerto si usas otro puerto que no sea seguro, por ejemplo: 9080

    Configuración del extremo de destino de muestra:

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

Causa: configuración incorrecta del servidor de destino

Si el servidor de destino está configurado con un puerto seguro, como 443, sin habilitar SSL, hace que el procesador de mensajes de Apigee Edge envíe solicitudes HTTP a un servidor de destino seguro o configurado con TLS, lo que genera este problema.

Diagnóstico

Sigue estos pasos para diagnosticar el error con la herramienta Trace:

  1. Habilita Trace en la IU de Apigee para el proxy de API afectado.
  2. Realizar solicitudes al proxy de API
  3. Selecciona una de las solicitudes a la API que fallaron con el código de respuesta 400.
  4. Navega por las distintas fases y determina dónde ocurrió la falla.
  5. Por lo general, verás la respuesta de error 400 que proviene del servidor de backend. Es decir, verás la respuesta de error 400 en la fase Respuesta recibida del servidor de destino, como se muestra a continuación:

  6. Haz clic en el ícono AX (datos registrados de Analytics) del seguimiento para determinar el extremo de destino para el que se realizó la solicitud.

  7. Ten en cuenta el target.name, que representa el nombre del extremo de destino.

    En el archivo de registro de ejemplo anterior, el target.name es default. Esto indica que el extremo de destino que se usa para esta solicitud es el predeterminado.

  8. Revisa la definición del extremo de destino para comprender la configuración.

    Configuración del extremo de destino de muestra:

    <?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>
    

    En la configuración del extremo de destino de muestra anterior, se muestra que usas un servidor de destino llamado faulty-target.

  9. Una vez que tengas el nombre del servidor de destino, puedes usar uno de los siguientes métodos para verificar la configuración del servidor de destino:

    • IU de Edge
    • API de Management

IU de Edge

  1. Navega a Apigee Edge > Administrador > Entornos > Servidores de destino.
  2. Elige el servidor de destino específico identificado del proxy de la API y haz clic en Editar.
  3. Verifica el puerto especificado para el servidor de destino y la información SSL.
  4. Si el servidor de destino está configurado con un puerto seguro (por ejemplo: 443), pero SSL no está habilitado, esa es la causa del problema.

    Como puedes ver en la captura de pantalla anterior, el puerto que se usa es 443, pero SSL no está habilitado para ese puerto en la configuración del servidor de destino. Esto hace que el procesador de mensajes de Apigee Edge envíe solicitudes HTTP al puerto seguro 443. Por lo tanto, verás el error 400 Bad Request con el mensaje The plain HTTP request was sent to HTTPS port.

API de Management

  1. Ejecuta la API de Get target server para obtener los detalles de la configuración específica del servidor de destino, como se muestra a continuación:

    Usuario de la nube pública:

    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"
    

    Usuario de la nube privada:

    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. Verifica el puerto especificado para el servidor de destino y la información SSL.
  3. Si el servidor de destino está configurado con un puerto seguro (por ejemplo: 443), pero la sección SSLInfo no está definida o no está habilitada, esa es la causa del problema.

    Configuración del servidor de destino de muestra:

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

    En el resultado de muestra anterior, podemos ver que el puerto que se usa para la conexión de destino es 443, pero no hay un bloque de configuración SSLInfo.

    Esto hace que el procesador de mensajes de Apigee Edge envíe solicitudes HTTP al puerto seguro 443. Por lo tanto, recibirás el error 400 Bad Request con el mensaje The plain HTTP request was sent to HTTPS port.

Resolución

Si tu servidor de destino es seguro o está configurado con TLS, debes habilitar SSL para el servidor de destino específico.

Puedes hacerlo mediante una de las siguientes opciones:

  • IU de Edge
  • API de Management

IU de Edge

  1. Navega al servidor de destino en Edge UI > Admin > Environments > Target Servers.
  2. Elige el servidor de destino específico y haz clic en Editar.
  3. Si el servidor de destino es seguro y usa un puerto como 443, marca la casilla de verificación junto a la opción de SSL para habilitar SSL.
  4. Configura el Almacén de confianza, los Cifrados y los Protocolos. (Solo si es necesario)

API de Management

Usa la API de Management para configurar el servidor de destino como se describe en la documentación de Actualiza la configuración del servidor de destino.

Se debe recopilar información de diagnóstico

Si el problema persiste, incluso después de seguir las instrucciones anteriores, recopila la siguiente información de diagnóstico y, luego, comunícate con el equipo de asistencia de Apigee Edge.

  1. Si eres usuario de una nube pública, proporciona la siguiente información:
    • Nombre de la organización
    • Nombre del entorno
    • Nombre del proxy de API
    • Completa el comando curl para reproducir el error
    • Resultado de la herramienta de seguimiento (si pudiste capturar la solicitud que falla)
  2. Si eres usuario de una nube privada, proporciona la siguiente información:
    • Se observó un mensaje de error completo
    • Nombre del entorno
    • Paquete de proxy de API
    • Definición del servidor de destino (si usas un servidor de destino en tu extremo)
    • Resultado de la herramienta de seguimiento (si pudiste capturar la solicitud que falla)