Error interno del servidor: Error de datos del formulario

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

Síntoma

La aplicación cliente obtiene un código de estado HTTP 500 Internal Server Error con el código de error protocol.http.BadFormData como respuesta a las llamadas a la API.

Mensaje de error

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

HTTP/1.1 500 Internal Server Error

Además, es posible que observes el siguiente mensaje de error:

{
   "fault":{
      "faultstring":"Bad Form Data",
      "detail":{
         "errorcode":"protocol.http.BadFormData"
      }
   }
}

Datos de formulario

Antes de entrar en los detalles para solucionar este problema, veamos qué son los datos de formulario.

Los datos del formulario son la información que proporciona el usuario, generalmente a través de un formulario HTML que tiene elementos como un cuadro de entrada de texto, un botón o una casilla de verificación. Por lo general, los datos del formulario se envían como una serie de pares clave-valor como parte de las solicitudes o respuestas HTTP.

Transmisión de datos de formulario

  1. Content-Type: application/x-www-form-urlencoded
    • Si el tamaño de los datos del formulario es pequeño, los datos se envían como pares clave-valor con lo siguiente:
      • Los caracteres de ambas claves codificados según las reglas explicadas en Formularios - Sección 17.13.4.1
      • El encabezado Content-Type: application/x-www-form-urlencoded

      Solicitud de muestra con datos de formulario:

      curl https://HOSTALIAS/somepath -H "Content-Type: application/x-www-form-urlencoded" -d "username=abc@google.com&pasword=secret123"
      
    • Todos los caracteres no alfanuméricos en las claves y los valores están codificados como porcentaje, es decir, se representan como un triplete de caracteres %HH, que consta de un signo de porcentaje seguido de dos dígitos hexadecimales que representan el código ASCII del carácter específico.
    • Por lo tanto, aunque el signo de porcentaje (%) se permite en los datos del formulario, se interpreta como el inicio de una secuencia de escape especial. Por lo tanto, si los datos del formulario deben contener el signo de porcentaje (%) en la clave o el valor, se deben transmitir como %25, , que representa el código ASCII del carácter de signo de porcentaje (%).
  2. Content-Type: multipart/form-data

    Si deseas transmitir grandes cantidades de datos binarios o texto que contenga caracteres que no sean ASCII, puedes enviar los datos con Content-Type: multipart/form-data, como se explica en Formularios: Sección 17.13.4.2

Causas posibles

Este error se produce si y solo si se cumplen todas las siguientes condiciones:

  1. La solicitud HTTP que envió el cliente a Apigee Edge contiene lo siguiente:
    1. Content-Type: application/x-www-form-urlencoded y
    2. Datos del formulario con el signo de porcentaje (%) o el signo de porcentaje (%) seguido de caracteres hexadecimales no válidos que no están permitidos según Formularios: Sección 17.13.4.1.
  2. El proxy de API en Apigee Edge lee los parámetros de formulario específicos que contienen cualquier carácter que no se permita usar en el flujo de solicitud con la política ExtractVariables o AssignMessage.

    Por ejemplo, si los datos del formulario contienen el signo de porcentaje (%) tal como está (sin codificar) o el signo de porcentaje (%) seguido de caracteres hexadecimales no válidos en la clave o el valor, recibirás este error.

    Estas son las posibles causas de este error:

    Causa Descripción Instrucciones de solución de problemas aplicables para
    Los parámetros del formulario en la solicitud tienen caracteres no permitidos Los parámetros de formulario que el cliente pasa como parte de la solicitud HTTP contienen caracteres que no se permiten. Usuarios de la nube pública y privada de Edge

Pasos comunes de diagnóstico

Usa una de las siguientes herramientas o técnicas para diagnosticar este error:

Supervisión de API

Para diagnosticar el error con API Monitoring, haz lo siguiente:

  1. Accede a la IU de Apigee Edge como usuario con un rol adecuado.
  2. Cambia a la organización en la que deseas investigar el problema.

  3. Navega a la página Analizar > Supervisión de API > Investigar.
  4. Selecciona el período específico en el que observaste los errores.
  5. Representa gráficamente el código de falla en función del tiempo.

  6. Selecciona una celda que tenga el código de falla protocol.http.BadFormData, como se muestra a continuación:

    (aumentar el tamaño de la imagen)

  7. La información sobre el código de falla protocol.http.BadFormData se muestra como se indica a continuación:

    (aumentar el tamaño de la imagen)

  8. Haz clic en Ver registros y expande la fila de la solicitud con errores.

  9. En la ventana Registros, ten en cuenta los siguientes detalles:
    • Código de estado: 500
    • Fuente del error: proxy
    • Código de falla: protocol.http.BadFormData
    • Política de fallas: extractvariables/EV-ExtractFormParams
  10. Si la Fuente de error es proxy, el Código de error es protocol.http.BadFormData y la Política de error no está vacía, esto indica que el error se produjo mientras la política específica indicada en Política de error leía o extraía los datos del formulario (parámetros del formulario) que tienen caracteres que no se permiten usar.
  11. En este ejemplo, X-Apigee-fault-policy es extractvariables/EV- ExtractFormParams, , lo que significa que la política ExtractVariables llamada EV-ExtractFormParams falló durante la lectura o la extracción de los parámetros del formulario.

Herramienta de Trace

Para diagnosticar el error con la herramienta Trace, haz lo siguiente:

  1. Habilita la sesión de registro y realiza una de las siguientes acciones:
    • Espera a que se produzca el error 500 Internal Server Error.
    • Si puedes reproducir el problema, realiza la llamada a la API para reproducirlo. 500 Internal Server Error
  2. Asegúrate de que la opción Mostrar todos los FlowInfos esté habilitada:

  3. Selecciona una de las solicitudes con errores y examina el registro.
  4. Navega por las diferentes fases del registro y ubica dónde se produjo la falla.
  5. Por lo general, encontrarás el error en una de las políticas, como se muestra a continuación:

    En el registro de muestra anterior, ten en cuenta que la falla se produjo en la política de ExtractVariables llamada EV-ExtractFormParams.

  6. Navega al flujo llamado Error después de la política específica que falló:

  7. Ten en cuenta los valores de los siguientes elementos del registro:

    error: Bad Form Data

    state: PROXY_REQ_FLOW

    error.class: com.apigee.rest.framework.BadRequestException

    • El valor del error Bad Form Data indica que los parámetros del formulario tenían algunos caracteres que no se permiten usar.
    • El valor del estado PROXY_REQ_FLOW, indica que el error se produjo en el flujo de solicitud del proxy de API.
  8. Navega a la fase AX (datos de Analytics registrados) en el registro y haz clic en ella.
  9. Desplázate hacia abajo hasta la sección Phase Details - Error Headers y determina los valores de X-Apigee-fault-code, X-Apigee-fault-source y X-Apigee-fault-policy, como se muestra a continuación:

  10. Ten en cuenta que los valores de X-Apigee-fault-code y X-Apigee-fault-source son protocol.http.BadFormData y policy, respectivamente, y X-Apigee-fault-policy no está vacío. Esto indica que el error se produjo mientras la política específica indicada en X-Apigee-fault-policy leía o extraía los datos del formulario (parámetros del formulario), que contenían caracteres que no se permiten usar.

    Encabezados de respuesta Valor
    X-Apigee-fault-code protocol.http.BadFormData
    X-Apigee-fault-source policy
    X-Apigee-fault-policy extractvariables/EV-ExtractFormParams
  11. En este ejemplo, X-Apigee-fault-policy es extractvariables/EV- ExtractFormParams, , lo que significa que la política ExtractVariables llamada EV-ExtractFormParams falló al leer o extraer los parámetros del formulario.

NGINX

Para diagnosticar el error con los registros de acceso de NGINX, haz lo siguiente:

  1. Si eres usuario de Private Cloud, puedes usar los registros de acceso de NGINX para determinar la información clave sobre 500 Internal Server Error de HTTP.
  2. Verifica los registros de acceso de NGINX:

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

  3. Busca si hay errores de 500 con el código de error protocol.http.BadFormData durante un período específico (si el problema ocurrió en el pasado) o si aún hay solicitudes que fallan con 500.
  4. Si encuentras errores de 500 con el X-Apigee-fault-code que coincida con el valor de protocol.http.BadFormData, determina el valor de X-Apigee-fault-source y X-Apigee-fault-policy.

    Ejemplo de error 500 del registro de acceso de NGINX:

    La entrada de ejemplo anterior del registro de acceso de NGINX tiene los siguientes valores para X-Apigee-fault-code y X-Apigee-fault-source:

    Encabezados Valor
    X-Apigee-fault-code protocol.http.BadFormData
    X-Apigee-fault-source policy
    X-Apigee-fault-policy extractvariables/EV-ExtractFormParams
  5. Ten en cuenta que los valores de X-Apigee-fault-code y X-Apigee-fault-source son protocol.http.BadFormData y policy , respectivamente, y que X-Apigee-fault-policy no está vacío. Esto indica que el error se produjo mientras la política específica indicada en X-Apigee-fault-policy leía o extraía los datos del formulario (parámetros del formulario), que contenían caracteres que no se permiten usar.
  6. En este ejemplo, X-Apigee-fault-policy es extractvariables/EV- ExtractFormParams, , lo que significa que la política ExtractVariables llamada EV-ExtractFormParams falló mientras leía los parámetros del formulario.

Causa: Los parámetros del formulario en la solicitud tienen caracteres no permitidos

Diagnóstico

  1. Determina el código de error, la fuente del error y la política de errores para 500 Internal Server Error con la Supervisión de API, la herramienta Trace o los registros de acceso de NGINX, como se explica en los pasos de diagnóstico comunes.
  2. Si el código de error es protocol.http.BadFormData, la fuente del error tiene el valor proxy o policy, y la política de error no está vacía, esto indica que la política especificada en política de error falló durante la lectura o extracción de los datos del formulario (parámetros del formulario).
  3. Examina la política indicada en Política de errores y determina la siguiente información:
    1. Fuente: Determina si la política lee o extrae los datos de la solicitud o la respuesta.
    2. Parámetros del formulario: Determinan los parámetros específicos del formulario que se leen en la política.

      Ejemplo 1

      Ejemplo 1: Política ExtractVariables que extrae parámetros de un formulario:

            <ExtractVariables name="EV-ExtractFormParms">
               <DisplayName>EV-ExtractFormParams</DisplayName>
               <Source>request</Source>
               <FormParam name="username">
                  <Pattern ignoreCase="false">{username}</Pattern>
               </FormParam>
               <FormParam name="password">
                 <Pattern ignoreCase="false">{password}</Pattern>
               </FormParam>
               <VariablePrefix>forminfo</VariablePrefix>
             <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
            </ExtractVariables>
            

      En la política ExtractVariables anterior, sucede lo siguiente:

      • Fuente: request

        Esto se indica con el elemento <Source>.

      • Parámetros del formulario: username y password

        Esto se indica con el elemento <Pattern> dentro del elemento <FormParam>.

      Esto indica que los parámetros de formulario username o password que el cliente pasó como parte de la solicitud HTTP a Apigee Edge contienen caracteres que no se permiten.

      Muestra 2

      Ejemplo 2: Política de AssignMessage que copia parámetros de formulario:

            <AssignMessage continueOnError="false" enabled="true" name="AM-CopyFormParams">
              <Copy source="request">
                <FormParams>
                  <FormParam name="username"/>
                  <FormParam name="password"/>
                </FormParams>
              </Copy>
              <AssignTo createNew="true" transport="http" type="request"/>
            </AssignMessage>
            

      En la política ExtractVariables anterior, sucede lo siguiente:

      • Origen: request

        Esto se indica con el atributo source en el elemento <Copy>.

      • Parámetros del formulario: username y password

        Esto se indica con el atributo name en el elemento <FormParam>.

      Esto indica que los parámetros de formulario username o password, o ambos, que el cliente pasó como parte de la solicitud HTTP a Apigee Edge contienen caracteres que no se permiten.

  4. Verifica si hay caracteres que no se permiten en los parámetros del formulario identificados en el paso 3 con uno de los siguientes métodos:

    Herramienta de Trace

    Para realizar la validación con la herramienta de seguimiento, sigue estos pasos:

    1. Si capturaste el registro de la solicitud con errores como se explica en Pasos comunes de diagnóstico, selecciona una de las solicitudes con errores.
    2. Si determinaste que los parámetros del formulario que contienen caracteres que no se permiten usar forman parte de la solicitud HTTP en el paso 3 anterior, haz lo siguiente:
      1. Navega a la fase Solicitud recibida del cliente.
      2. Desplázate hacia abajo hasta la sección Phase Details y revisa el Request Content.

        ( aumentar el tamaño de la imagen)

      3. En el ejemplo anterior, ten en cuenta que el parámetro de formulario password contiene el signo de porcentaje (%).
      4. Dado que el signo de porcentaje (%) también se usa para la codificación de porcentaje de los caracteres especiales, no se puede usar tal como está en los datos del formulario.
      5. Por lo tanto, Apigee Edge responde con 500 Internal Server Error y el código de error protocol.http.BadFormData.

    Solicitud real

    Para validar con la solicitud real, haz lo siguiente:

    1. Si no tienes acceso a la solicitud real que se envió al servidor de destino, ve a Resolución.
    2. Si tienes acceso a la solicitud real que se envió a Apigee Edge, realiza los siguientes pasos:
      1. Revisa el contenido de los datos del formulario y comprueba si contiene caracteres que no se permiten, como el signo de porcentaje (%) o el signo de porcentaje (%) seguido de caracteres hexadecimales no válidos.

        Ejemplo 1

        Solicitud de ejemplo núm. 1: Datos del formulario como parte de la solicitud

        curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=123456abc123&client_secret=c23578%ZY"
        

        En este ejemplo, ten en cuenta que el elemento client_secret contiene el signo de porcentaje (%) seguido de caracteres hexadecimales no válidos ZY.

        Muestra 2

        Solicitud de ejemplo núm. 2: Datos del formulario que se pasan en un archivo:

        curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d @form_data.xml
        

        Contenido de form_data.xml:

        xml=<user><username>abc1234@google.com</username><password>qwerty12345!@#$%</password></user>

        En este ejemplo, ten en cuenta que el elemento password contiene el signo de porcentaje (%), que no se debe pasar tal cual en los datos del formulario.

    3. En los dos ejemplos anteriores, los datos del formulario que se enviaron como parte de la solicitud HTTP a Apigee Edge contienen caracteres que no se permiten.
    4. Por lo tanto, Apigee Edge responde con 500 Internal Server Error con el código de error protocol.http.BadFormData.

Solución

  1. Asegúrate de que los caracteres especiales en las claves y los valores de los datos o parámetros del formulario que envía el cliente como parte de la solicitud HTTP siempre estén codificados como se explica en Form Data - application/x-www-form-urlencoded.
  2. En los ejemplos anteriores, puedes corregir los problemas de la siguiente manera:

    Ejemplo 1

    Ejemplo 1: Datos del formulario que se pasan como parte de la solicitud:

    Usa caracteres hexadecimales válidos que coincidan con el código ASCII de un carácter específico. Por ejemplo, si quieres enviar el signo de dólar ($), usa %24, como se muestra a continuación:

    curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=123456abc123&client_secret=c23578%24"
    

    Muestra 2

    Solicitud de ejemplo núm. 2: Datos del formulario que se pasan en un archivo:

    curl -X GET "https://HOSTALIAS/myproxy -H "Content-Type: application/x-www-form-urlencoded" -d @form_data.xml
    

    Contenido de form_data.xml:

    Usa la codificación de porcentaje para el signo de porcentaje (%), es decir, modifica el archivo para que tenga %25 , como se muestra a continuación:

    xml=<user><username>abc1234@google.com</username><password>qwerty12345!!@#$%25</password></user>

Especificación

Apigee Edge espera que los datos del formulario se envíen según las siguientes especificaciones:

Especificación
Datos de formulario: application/x-www-form-urlencoded

Si aún necesitas ayuda del equipo de asistencia de Apigee, consulta Recopila información de diagnóstico.

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:

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 que se usa para reproducir el 500 Internal Server Error con el código de error protocol.http.BadFormData
  • Archivo de registro de las solicitudes a la API

Si eres usuario de la nube privada, proporciona la siguiente información:

  • Mensaje de error completo observado para las solicitudes con errores
  • Nombre del entorno
  • Paquete de proxy de API
  • Archivo de registro de las solicitudes a la API
  • Registros de acceso de NGINX

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    Dónde: ORG, ENV y PORT# se reemplazan por valores reales.

  • Registros del sistema del Message Processor

    /opt/apigee/var/log/edge-message-processor/logs/system.log

Referencias