2011-03-29 25 views
10

Estoy tratando de construir un proxy que sirva las solicitudes a un sitio interno (ocultando el origen) pero al mismo tiempo inspeccionar los paquetes y publicar asincrónicamente -procesarlos.Enrutamiento de solicitud de aplicación IIS7 (proxy inverso arr) combinado con módulo administrado - tiempo de espera

E.g. digamos que todas las llamadas SOAP a http://www.foo.com irán a http://192.168.1.1, y al mismo tiempo se almacenarán en una base de datos para su posterior análisis. El servidor interno es una caja negra, por lo que cambiar algo no está dentro del alcance de esta pregunta.

De todos modos, he configurado ARR, con proxy inverso, hice el filtro de reescritura de URL con comodines, todo funciona perfectamente. Luego, traté de agregar un HttpModule administrado escrito en C# y enganchado a Application_BeginRequest y Application_EndRequest. Puedo acceder a los encabezados de solicitud, encabezados de respuesta al final (el grupo de aplicaciones está en modo integrado) e incluso puedo leer el contenido de respuesta de la salida mediante la configuración de un filtro en Response.Filter, que almacena en caché todas las escrituras en una secuencia de memoria adicional.

El problema es que el momento trato de leer (en el interior del módulo de controlador BeginRequest) el flujo de entrada de la solicitud, ARR se mantiene un tiempo y lanza una

Error HTTP 502.3 - Puerta de enlace incorrecta La operación el tiempo de espera Handler ApplicationRequestRoutingHandler Código de error 0x80072ee2

Por lo tanto, el tiempo de espera.

Mirando con solicitudes con error rastreo veo:

MODULE_SET_RESPONSE_ERROR_STATUS Advertencia ModuleName = "ApplicationRequestRouting", Notificación = "EXECUTE_REQUEST_HANDLER", httpStatus = "502", HttpReason = "Bad Gateway", HttpSubStatus = "3", ErrorCode = "2147954402", ConfigExceptionInfo = "" SET_RESPONSE_ERROR_DESCRIPTION Advertencia ErrorDescription = "La operación timed out"

Ahora cualquier puestos similares en la red no ayudó a que esto no es un error de tiempo de espera (configuración de proxy tiene 120 segundos, una página de preguntas en menos de 100 ms), y el momento de comentar el código del manejador que intenta leer datos FORM o datos InputStream, todo funciona como un amuleto.

Incluso si configuro la posición de la ruta de entrada en 0 después de leerla, aún obtengo tiempos de espera. Si leo la secuencia de entrada en EndRequest, obtiene 0 bytes, incluso si se trata de una solicitud POST. (lo cual es claramente incorrecto)

¿ARR tiene un error en el hecho de que trato de leer un flujo de entrada antes de que intente redirigirlo?

cosas usadas: Windows Server 2008 R2 IIS 7.5 ARR v2 .Net Framework 3.5 módulo

ideas? Gracias /Cosmin

Respuesta

3

Sé que esta es una pregunta de hace un año, pero acabo de pasar por lo mismo y encontré una solución. Entonces, lo estoy publicando aquí para cualquier otra persona que se encuentre con esto.

En mi caso, solo vi el problema de tiempo de espera con las solicitudes POST.

Parece que el ARR 2.0/2.1 supone que el flujo de entrada estará al comienzo de los datos publicados. Sin embargo, el siguiente código (por ejemplo) se romperá esta suposición:

HttpContext context = HttpContext.Current; 
    HttpRequest request = context.Request; 

    string value = request.Params["Name"]; 

La clave es cómo Parámetros se describe

Gets a combined collection of System.Web.HttpRequest.QueryString, 
    System.Web.HttpRequest.Form, System.Web.HttpRequest.ServerVariables, 
    and System.Web.HttpRequest.Cookies items."` 

Cuando la solicitud es un método POST, el acceso a Params leerá los datos enviados desde la corriente de entrada, invalidando la suposición de ARR. Como leerá de la secuencia de entrada.

Sabía que los datos que necesitaba estaban en la cadena de consulta, no en los datos publicados, así que trabajé alrededor de esto accediendo al QueryString en lugar de Params. Esto evita leer los datos publicados y funciona bien para mí.

string value = request.QueryString["Name"]; 

Este problema parece estar solucionado en ARR 2.5.

La actualización de ARR parece ser la única solución si necesita acceder a los datos publicados antes de entregarlos a ARR. La clave es dejar que HttpRequest maneje la adquisición de los datos en Params. Si lo lees directamente, no funcionará.

2

Acabo de toparme con este error y sus experiencias me ayudaron a determinar la causa raíz.

Mi servidor principal está basado en MVC y mira los valores de Request.Form en el método Application_BeginRequest. Si se accede a los valores de formulario, ARR no reenvía el cuerpo de una solicitud HTTP POST. Las solicitudes GET funcionarán bien ya que no hay un cuerpo.

Tengo routes.IgnoreRoute ("Forum/{*pathInfo}"); como una ruta registrada, pero ARR funciona como un HttpModule y no se activa hasta más adelante en la tubería. Eso significa que mi aplicación basada en MVC tiene la oportunidad de acceder al contenido del cuerpo POST que de alguna manera evita que ARR acceda al cuerpo mismo y lo reenvíe al servidor proxy.

Aquí está puesto relacionado con Cosmin en los foros IIS.NET: ARR 2.0 BUG - combined with managed http module timeout on read inputstream

En mi aplicación tengo todos myserver.com/Forum/* solicitudes siendo proxy'd inversa a una solicitud por separado en otro servidor. Así que simplemente verifiqué el HttpContext.Current.Request.Url en el método Application_BeginRequest de mi aplicación MVC para asegurarme de que no contiene/Forum antes de acceder a los valores de Request.Form. Una vez que hice eso, los cuerpos POST pasaron bien por ARR.

ACTUALIZACIÓN: después de nuevas pruebas, parece que todavía hay problemas con ARR, ya que la POST de los usuarios no autenticados aún falla. En lugar de que el sitio web principal sea MVC, creé un sitio web ficticio IIS .NET 4.0 con un único documento Default.html. Pero todavía tuve problemas con las solicitudes POST y ARR. Luego cambio el grupo de aplicaciones a ASP.NET 2.0 y lo que sabes, funciona.En este punto, tengo que suponer que algo en la canalización de .NET 4.0 está accediendo al flujo de entrada que impide que ARR acceda al flujo de entrada por sí mismo para reenviar el cuerpo del POST.

6

Si puede cambiar a .Net Framework 4, hay una solución para esto.

Después de terminar con BeginRequest/EndRequest en su controlador de eventos HttpModule, agregue una llamada a HttpRequest.InsertEntityBody.

/* BeginRequest event: Executes before request is processed */ 
    private void Application_BeginRequest(Object source, EventArgs e) 
    { 
     HttpApplication application = (HttpApplication)source; 
     HttpRequest request = application.Context.Request; 

     // Do something with request 
     DoMyOwnRequestProcessing(request); 

     // After you finish, make sure IIS gets the entity body 
     // For example, Application Request Routing needs this 
     request.InsertEntityBody(); 
    } 

Tome un vistazo a esto en MSDN: HttpRequest.InsertEntityBody.

+0

¡Estoy en .NET 4.0 y esto me sirvió de algo! Thanx robinet –

Cuestiones relacionadas