Estamos desarrollando un servicio web de Python y un sitio web de cliente en paralelo. Cuando hacemos una petición HTTP desde el cliente al servicio, una llamada plantea sistemáticamente una socket.error en socket.py, en la lectura:104, error de socket de 'Restablecimiento de conexión por igual' o ¿Cuándo el cierre de un socket da como resultado un RST en vez de un FIN?
(104, 'Connection reset by peer')
Cuando escucho con Wireshark, el "bueno" y "malo "las respuestas se ven muy similares:
- Debido al tamaño del encabezado OAuth, la solicitud se divide en dos paquetes. El servicio responde a ambos con ACK
- El servicio envía la respuesta, un paquete por encabezado (HTTP/1.0 200 OK, luego el encabezado de fecha, etc.). El cliente responde a cada uno con ACK.
- (Buena solicitud) el servidor envía un FIN, ACK. El cliente responde con un FIN, ACK. El servidor responde ACK.
- (Solicitud incorrecta) el servidor envía un RST, ACK, el cliente no envía una respuesta TCP, el socket.error se genera en el lado del cliente.
Tanto el servicio web como el cliente se ejecutan en una caja de Gentoo Linux x86-64 ejecutando glibc-2.6.1. Estamos usando Python 2.5.2 dentro del mismo virtual_env.
El cliente es una aplicación Django 1.0.2 que llama a httplib2 0.4.0 para realizar solicitudes. Estamos firmando solicitudes con el algoritmo de firma OAuth, con el token OAuth siempre configurado en una cadena vacía.
El servicio ejecuta Werkzeug 0.3.1, que está utilizando el servidor wsgiref.simple_server de Python. Ejecuté la aplicación WSGI a través de wsgiref.validator sin problemas.
Parece que esto debería ser fácil de depurar, pero cuando rastreamos a través de una buena solicitud en el lado del servicio, se ve como la solicitud incorrecta, en la función socket._socketobject.close(), convirtiendo los métodos delegados en métodos ficticios. Cuando el método send o sendto (no se puede recordar) se apaga, se envía FIN o RST y el cliente comienza a procesar.
"Connection reset by peer" parece culpar al servicio, pero tampoco confío en httplib2. ¿Puede el cliente tener la culpa?
** Además depuración - Parece que el servidor en Linux **
Tengo un MacBook, así que traté de ejecutar el servicio en uno y el sitio web del cliente por el otro. El cliente Linux llama al servidor OS X sin el error (FIN ACK). El cliente de OS X llama al servicio de Linux con el error (RST ACK, y a (54, 'Restablecimiento de conexión por pares')). Entonces, parece que es el servicio que se ejecuta en Linux. ¿Es x86_64? Un mal glibc? wsgiref? Todavía estás ...
** La prueba adicional - wsgiref ve escamosa **
Hemos ido a la producción con Apache y mod_wsgi, y se repone de conexión han desaparecido. Vea mi respuesta a continuación, pero mi consejo es que registre el restablecimiento de la conexión y vuelva a intentarlo. Esto permitirá que su servidor funcione correctamente en modo de desarrollo y en producción sólida.
La pregunta es, en efecto por qué el servidor envía los reques RST. El cliente debe restablecer la conexión e informar el mensaje 'Restablecimiento de conexión por pares'. Así que creo que está en el camino correcto –