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

Estás viendo la documentación de Apigee Edge.
Ir a la documentación de Apigee X.
info

Síntoma

La aplicación cliente recibe una HTTP 400 Bad Request respuesta 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 habilitado para TLS 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 se produce cuando un cliente intenta conectarse a una API en Apigee y el host virtual mencionado está configurado para usar SSL y, en su lugar, recibe una solicitud HTTP.

Diagnóstico

Como este problema ocurre en el extremo de salida 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 API Monitoring y la herramienta Trace.

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

    Ejemplo de solicitud a la API incorrecta:

    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 de host myorg-test.apigee.net en el puerto seguro 443. Esta es la causa del 400 Bad Request error.

Solució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 habilitado para TLS 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. Realiza solicitudes al proxy de API.
  3. Selecciona una de las solicitudes a la API que falló con el código de respuesta 400.
  4. Navega por las distintas fases y determina dónde se produjo 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 Response received from target server como se muestra a continuación:

  6. Para determinar el extremo de destino para el que se realizó la solicitud, haz clic en el ícono AX (Analytics Data Recorded) en el seguimiento.

  7. Ten en cuenta el target.url, que contiene el protocolo, el alias de 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 escuche en un puerto seguro, como 443. Si usas el protocolo como http en el elemento <URL>, entonces esa es la causa de este problema.

    Ejemplo de configuración del extremo de destino:

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

Solución

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

    Ejemplo de configuración del extremo de destino:

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

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

    Ejemplo de configuración del extremo de destino:

    <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, esto hace que el Message Processor 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. Realiza solicitudes al proxy de API.
  3. Selecciona una de las solicitudes a la API que falló con el código de respuesta 400.
  4. Navega por las distintas fases y determina dónde se produjo 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 Response received from target server como se muestra a continuación:

  6. Para determinar el extremo de destino para el que se realizó la solicitud, haz clic en el ícono AX (Analytics Data Recorded) en el seguimiento.

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

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

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

    Ejemplo de configuración del extremo de destino:

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

    La configuración del extremo de destino de ejemplo anterior 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 > Admin > Environments > Target Servers.
  2. Elige el servidor de destino específico identificado en el proxy de API y haz clic en Edit.
  3. Verifica el puerto especificado para el servidor de destino y la información de 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 de este 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, obtienes 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 sobre 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 de 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 de este problema.

    Ejemplo de configuración del servidor de destino:

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

    En el resultado de ejemplo 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 Message Processor de Apigee Edge envíe solicitudes HTTP al puerto seguro 443. Por lo tanto, obtienes el error 400 Bad Request con el mensaje The plain HTTP request was sent to HTTPS port.

Solución

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

Para ello, usa una de las siguientes opciones:

  • IU de Edge
  • API de Management

IU de Edge

  1. Navega al servidor de destino en IU de Edge > Admin > Environments > Target Servers.
  2. Elige el servidor de destino específico y haz clic en Edit.
  3. Si tu servidor de destino es seguro y usa un puerto como 443, habilita SSL seleccionando la casilla de verificación junto a la opción SSL.
  4. Configura Truststore, Ciphers y Protocols. (Solo si es necesario)

API de Management

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

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 Asistencia de Apigee Edge.

  1. Si eres usuario de la nube pública, proporciona la siguiente información:
    • Nombre de la organización
    • Nombre del entorno
    • Nombre del proxy de API
    • Comando curl completo para reproducir el error
    • Resultado de la herramienta Trace (si pudiste capturar la solicitud con errores)
  2. Si eres usuario de la nube privada, proporciona la siguiente información:
    • Mensaje de error completo observado
    • Nombre del entorno
    • Paquete de proxy de API
    • Definición del servidor de destino (si usas el servidor de destino en tu extremo)
    • Resultado de la herramienta Trace (si pudiste capturar la solicitud con errores)