Pregunta

Estamos creando un marco de prueba de integración integral en C# para nuestra aplicación que existe sobre HTTP usando IIS7 para alojar nuestras aplicaciones.

Como parte de nuestras pruebas de integración, queremos probar las solicitudes entrantes que darán como resultado EndOfStreamExceptions ("No se puede leer más allá del final de la transmisión") que ocurren cuando un cliente envía un encabezado HTTP que indica un tamaño de cuerpo mayor que el que realmente transmite como parte de el cuerpo.Queremos probar nuestro código de recuperación de errores para esta condición, por lo que necesitamos simular este tipo de solicitudes.

Estoy buscando una biblioteca de sockets basada en .NET Fx o un reemplazo personalizado de HttpWebRequest que permita específicamente a los desarrolladores simular dichas condiciones para agregarlas a nuestro conjunto de pruebas de integración.¿Alguien sabe de alguna biblioteca de este tipo?Una solución programable también funcionaría.

¿Fue útil?

Solución

Establecer la propiedad ContentLength antes de llamar GetRequestStream (o BeginGetRequestStream) y luego escribir un menor número de bytes a esa corriente. ContentLength tirará si se intenta establecer que después de haber conseguido la corriente petición. Si no se establece ContentLength, HttpWebRequest se amortiguar las cabeceras hasta que la corriente está cerrado para que se pueda establecer adecuadamente ContentLength (alternativamente, puede utilizar SendChunked pero eso no va a funcionar para usted aquí). Si desea un control máximo sobre esto, crear una solicitud de malormed o dos a mano y luego abrir un socket al puerto 80 en el servidor y escribir la solicitud al flujo TCP y luego leer la respuesta y comprobar la conexión para ver si ha sido cerrado .

Sin embargo: No creo que esta prueba es una buena idea. Aquí está el problema:

El cliente envía una solicitud al servidor. Se afirma que el contenido será de 100 bytes. A continuación, envía 90 bytes y luego simplemente deja de enviar, dejando abierta la conexión. El servidor lee 90 bytes, espera a que el resto ya que el cliente dijo que serían enviados 100 bytes. Ahora, el cliente envía una segunda solicitud. ¿Qué hará el servidor con los primeros 10 bytes de la nueva solicitud?

La respuesta es que el servidor asumirá que estos bytes eran parte de la solicitud anterior y tratarlos como tales, a continuación, iniciar la lectura de los "nuevos" de solicitud 10 bytes después de su inicio, lo que obviamente resultar en cabeceras malformados. El servidor no le va a gustar, lo que va a enviar un error 4xx y luego se va a cerrar la conexión. La razón por la que se cierra la conexión se debe a que ahora no tiene forma de saber cuáles son los datos que se envían a ella significa y no hay manera de recuperar. Además, el cierre de la conexión no será agraciado, que va a ser repentino y el HttpWebRequest en el otro extremo que se presentará una segunda solicitud (o una tercera o cuarta si están en cola) lanzará una WebException diciendo que la conexión subyacente se cerró y se deja adivinar por qué.

Este mismo comportamiento es lo que causa que la conexión se cierra con la Expect cabecera 100-continuará y el servidor devuelve un 100-CONTINUACIÓN seguido por un 4xx tal como cuando se requiere autenticación. A pesar de que ha rechazado la solicitud, que todavía debe asumir que los próximos bytes son parte de la misma petición, ya que se ha comprometido a recibir esos bytes mediante el envío de la 100-continuar. Si no dará servicio a esa petición o si el cliente desea cancelar la solicitud y presentar una nueva (presumiblemente con las credenciales de autenticación), entonces tiene que cerrar la conexión y abrir uno nuevo.

Por último, las pruebas de un EndOfStreamException de una corriente de red mediante TCP no tiene ningún sentido para mí en absoluto. TCP no marca el "fin" de una corriente, que sólo mantiene el envío de datos a medida que se escribe en el zócalo. No hay un "EOF" para ello y no hay manera de detectar si los datos se transmiten todos a menos que sepa la cantidad de datos que puede esperar. TCP no tiene realmente un "fin" a su corriente a menos que la conexión está cerrada, en cuyo caso se obtendrá un WebException o una SocketException dependiendo de donde en la pila que está operando. Cualquier error de transmisión en el protocolo se tratan en Winsock. Si no se envía más datos, un extremo de la conexión va a enviar un keepalive al otro para asegurarse de que la conexión es en realidad todavía abierto y un host no acaba de caer. Si los tiempos de mantenimiento de conexión a cabo, la conexión se cierra y es posible obtener un WebException la próxima vez que intente leer de él. Teniendo en cuenta cómo funciona todo esto, yo no veo cómo se va a conseguir cualquier valor de esta prueba. Es mucho mejor simplemente enviando solicitudes con formato incorrecto y asegurar que los errores se procesan en consecuencia y el mensaje 4xx apropiado se envían de vuelta al cliente y la conexión se cierra correctamente.

Otros consejos

No sé de cualquier biblioteca, pero me parece que sería muy simple en el lado de recepción, si es ahí donde se está codificando.

Simplemente recuperar toda la WebRequest, truncar tanto o tan poco como desee, y luego hacia adelante en. Puede que tenga que hacer una nueva copia de la WebRequest en el proceso, en lugar de truncar en el lugar, pero aún debe ser sencilla.

¿No puede establecer la propiedad HttpWebRequest.ContentLength en los clientes a un valor menor o mayor que el tamaño real de los datos?

Si desea simular cualquier tipo de cosas, en las que está violando el protocolo HTTP, entonces usted tendrá que escribir su propio código para hacerlo. HttpWebRequest no le permiten hacer cosas como esta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top