Мы разрабатываем веб-сервис Python и веб-сайт клиента параллельно. Когда мы делаем HTTP-запрос от клиента к службе, один вызов последовательно вызывает socket.error в socket.py, в read:
(104, 'Connection reset by peer')
Когда я слушаю с помощью wirehark, "хорошие" и "плохие" ответы выглядят очень похожими:
- Из-за размера заголовка OAuth запрос разбивается на два пакета. Служба отвечает как с помощью ACK
- Служба отправляет ответ, один пакет на заголовок (HTTP/1.0 200 OK, затем заголовок Date и т.д.). Клиент отвечает каждому из ACK.
- (Хороший запрос) сервер отправляет FIN, ACK. Клиент отвечает FIN, ACK. Сервер отвечает ACK.
- (неверный запрос) сервер отправляет RST, ACK, клиент не отправляет ответ TCP, socket.error возникает на стороне клиента.
Как веб-служба, так и клиент работают на блоке x86-64 Gentoo Linux, работающем под управлением glibc-2.6.1. Мы используем Python 2.5.2 внутри того же virtual_env.
Клиент - это приложение Django 1.0.2, которое вызывает запросы httplib2 0.4.0. Мы подписываем запросы с помощью алгоритма подписи OAuth, а токен OAuth всегда задает пустую строку.
В службе работает Werkzeug 0.3.1, которая использует Python wsgiref.simple_server. Я запускал приложение WSGI через wsgiref.validator без проблем.
Похоже, что это должно быть легко отлаживать, но когда я просматриваю хороший запрос со стороны службы, он выглядит так же, как неудачный запрос, в функции socket._socketobject.close(), превращая методы делегата в манекен методы. Когда метод send или sendto (не может запомнить, который) отключен, FIN или RST отправляются, и клиент начинает обработку.
"Соединение reset by peer", похоже, накладывает вину на службу, но я не доверяю httplib2. Может ли клиент быть виноват?
** Дальнейшая отладка - выглядит как сервер на Linux **
У меня есть MacBook, поэтому я попытался запустить службу на одном и на веб-сайте клиента на другом. Клиент Linux вызывает сервер OS X без ошибки (FIN ACK). Клиент OS X вызывает службу Linux с ошибкой (RST ACK и (54, "Соединение reset одноранговым узлом" )). Итак, похоже, что это служба, работающая в Linux. Это x86_64? Плохое glibc? wsgiref? Еще глядя...
** Дальнейшее тестирование - wsgiref выглядит flaky **
Мы пошли на производство с Apache и mod_wsgi, а сбрасываем соединение. См. Мой ответ ниже, но мой совет - зарегистрировать соединение reset и повторить попытку. Это позволит вашему серверу нормально работать в режиме разработки и прочно работать.