Requests: socket.error: [Errno 54] Соединение сброшено одноранговым узлом

Созданный на 22 сент. 2011  ·  19Комментарии  ·  Источник: psf/requests

В настоящее время я получаю сообщение об ошибке socket.error: [Errno 54] Connection reset by peer когда я использую requests.get(url, params=kwargs) а params содержат большие объемы текста. Если я усекаю два больших текста до менее чем 2900 символов каждый, это сработает. Если я запускаю тот же запрос на получение из командной строки, используя curl он работает. Я использую запросы версии 0.6.1, которые я установил, pip install python-requests .

Я не уверен, как сказать вам воспроизвести проблему, потому что я использую библиотеку python-sendgrid для добавления информационного бюллетеня в мою учетную запись sendgrid, и я не хочу публиковать свое имя пользователя и пароль api в запросе на выпуск. :)

Для тестирования из командной строки с помощью curl я создал два файла, каждый из которых содержал простой текст и текст html, который был закодирован с помощью urlencoder . Затем я выполнил следующую команду.

export IDENTITY='<my identity number>'
export API_KEY='<my smtp password>'
export API_USER='<my smtp username>'
export NAME='<My Urlencoded Newsletter Name>'
export SUBJECT='<My Urlencoded Newsletter Subject>'
TEXT=`cat urlencoded.txt`; HTML=`cat urlencoded.html`; curl -d "api_user=$API_USER&api_key=$API_KEY&identity=$IDENTITY&name=$NAME&subject=$SUBJECT&text=$TEXT&html=$HTML" https://sendgrid.com/api/newsletter/newsletter/add.json

Самый полезный комментарий

Сладкое действие! Переключение с requests.get(url, params=kwargs) на requests.post(url, data=kwargs) исправлено! Извините за беспокойство и спасибо за помощь!

Все 19 Комментарий

Хм, интересно. Если возникает эта ошибка, у меня мало оснований полагать, что сервер _не_ действительно сбрасывает соединение.

У вас есть HTTP-прокси, как у Чарльза? Это может помочь пролить свет на то, что на самом деле происходит.

Извините, я забыл предоставить полную трассировку. Вот трассировка, которую я получаю, когда получаю сообщение об ошибке. Кроме того, я не понимаю, как использовать прокси-сервер HTTP и почему это имеет значение, когда он работает из командной строки с помощью curl.

Traceback (most recent call last):
  File "/Users/oconnor/.virtualenvs/emails/bin/django-admin.py", line 5, in <module>
    management.execute_from_command_line()
  File "/Users/oconnor/.virtualenvs/emails/lib/python2.7/site-packages/django/core/management/__init__.py", line 429, in execute_from_command_line
    utility.execute()
  File "/Users/oconnor/.virtualenvs/emails/lib/python2.7/site-packages/django/core/management/__init__.py", line 379, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/oconnor/.virtualenvs/emails/lib/python2.7/site-packages/django/core/management/base.py", line 191, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/Users/oconnor/.virtualenvs/emails/lib/python2.7/site-packages/django/core/management/base.py", line 220, in execute
    output = self.handle(*args, **options)
  File "/Users/oconnor/Sites/wenworld/emails/emails/management/commands/ww_daily_headlines_send.py", line 114, in handle
    self.add_newsletter_to_sendgrid(sendgrid_newsletter_name, NEWSLETTER_SLUG)
  File "/Users/oconnor/Sites/wenworld/emails/emails/management/commands/ww_daily_headlines_send.py", line 94, in add_newsletter_to_sendgrid
    html=email.html
  File "/Users/oconnor/.virtualenvs/emails/src/sendgrid/src/sendgrid/__init__.py", line 67, in newsletter_add
    subject=subject, text=text, html=html)
  File "/Users/oconnor/.virtualenvs/emails/src/sendgrid/src/sendgrid/__init__.py", line 157, in get
    return self.call(method, **kwargs)
  File "/Users/oconnor/.virtualenvs/emails/src/sendgrid/src/sendgrid/__init__.py", line 56, in call
    result_json = json.loads(response.content)
  File "/Users/oconnor/.virtualenvs/emails/lib/python2.7/site-packages/requests/models.py", line 429, in __getattr__
    self._content = self.read()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 351, in read
    data = self._sock.recv(rbufsize)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 553, in read
    s = self.fp.read(amt)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 1276, in read
    return s + self._file.read(amt - len(s))
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 380, in read
    data = self._sock.recv(left)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 219, in recv
    return self.read(buflen)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 138, in read
    return self._sslobj.read(len)
socket.error: [Errno 54] Connection reset by peer

Ответ, который я получил от github, такой ...

<html>
<head><title>414 Request-URI Too Large</title></head>
<body bgcolor="white">
<center><h1>414 Request-URI Too Large</h1></center>
<hr><center>nginx/0.7.65</center>
</body>
</html>

Что странно, потому что, как я уже упоминал ранее, он работает с curl .

Если вы потратите время на то, чтобы взглянуть на два запроса через Чарльза (или аналогичный), я уверен, что вы довольно быстро заметите проблему.


Как говорится в сообщении об ошибке, Request-URI слишком велик для обработки сервером, поэтому соединение разрывается.

С помощью запросов вы отправляете все данные в виде массивной строки запроса в URI запроса, известной как параметр GET. Когда вы используете curl, вы загружаете закодированные в форму данные в тело запроса, известное как данные POST.

Я пробовал использовать как requests.get(url, params=kwargs) и requests.post(url, params=kwargs) и оба возвращают одну и ту же ошибку. По какой-то причине Чарльз не захватывает запросы из curl, а просто захватывает запросы из моего браузера и моего скрипта командной строки python, который использует запросы python.

Не стоит беспокоиться.

params - для строк запроса, data - для данных POST.

Сладкое действие! Переключение с requests.get(url, params=kwargs) на requests.post(url, data=kwargs) исправлено! Извините за беспокойство и спасибо за помощь!

Совершенно не беспокойтесь :)

Странно, что у меня такая же ошибка с похожими данными, разница только в том, что в моем случае у меня нет большого списка или размера параметров. Тот же запрос, сделанный через CURL, работает нормально, но через запросы выдает эту ошибку.

request.exceptions.ConnectionError: HTTPSConnectionPool (host = 'sbarnea.com', port = 443): Превышено максимальное количество повторных попыток с URL: / jira / rest / api / 2 / group? groupname = jira-administrators & expand = users (вызвано: [Errno 54] Соединение сброшено одноранговым узлом)

Что еще интереснее, кажется, что запрос даже не доходит до веб-сервера.

Есть идеи, что это может быть причиной?

@ssbarnea Этой проблеме больше двух лет: она не имеет ничего общего с проблемой, с которой вы столкнулись в настоящее время. =) Не могли бы вы открыть новый выпуск, чтобы отследить вашу проблему?

Более того, не открывайте проблему, поговорите со StackOverflow, вы задаете вопрос, и у вас нет оснований полагать, что это проблема с поведением запросов. Разместите подробности о StackOverflow, и тогда мы сможем отправить отчет об ошибке (при необходимости).

Это очень странное поведение, и у меня есть основания полагать, что это не ошибка в запросах, поэтому я открыл новую ошибку. Я все еще изучаю, что могло вызвать это, это происходит только с моей машины, но самое интересное то, что CURL работает (и браузеры тоже). Спасибо.

Извините, что держу это здесь, но я нашел причину этого:

#  resolver 127.0.0.1;
#  ssl_protocols TLSv1.2 TLSv1.1 ; # TLSv1
#  ssl_stapling on;
#  ssl_stapling_verify on;
#  ssl_session_cache builtin:1000;
#  ssl_session_timeout 30m;
#  ssl_ciphers HIGH:!RC4:!aNULL:!MD5;
#  ssl_prefer_server_ciphers on;

Отключив эти настройки на сервере nginx, он начал работать с запросами, очевидно, что один из них вызывает сбой.

@ssbarnea
Скорее всего, это ошибочный сервер, который делает неправильные вещи, когда к нему обращаются в определенных версиях SSL / TLS, как описано в # 1567 (и некоторых других).
Попробуйте принудительно установить другую версию, как описано здесь (еще немного похвалы @Lukasa)

И победитель (проигравший) - ssl_protocols TLSv1.2 TLSv1.1;
Кажется, что удаление TLSv1 из поддерживаемых протоколов на сервере препятствует работе запросов.

Теперь я могу назвать это ошибкой в ​​запросах или базовой библиотеке?

Примечание: удаление TLSv1 рекомендуется из соображений безопасности, с ним есть эксплойты.

@ssbarnea Вы обнаружите, что ограничение не в запросах, а в Python. В настоящее время ни одна из поставляемых версий Python не поддерживает какую-либо версию TLS, более позднюю, чем V1.0, как вы можете видеть в таблице здесь .

Python 3.4 (еще не поставлен, нет гарантий, что Requests совместим с ним) поддерживает TLS1.2 и TLS1.1, так что вы можете попробовать с этим. В противном случае вам придется разрешить TLSv1 разрешать запросы.

Тем не менее, есть кое-что странное: в обоих случаях я использовал Python, при тестировании из OS X он не удался, при тестировании из Ubuntu он работал.

Обычно я бы не стал трогать настройки по умолчанию для SSL, но я запустил отчет SSL и попытался устранить большинство предупреждений:

FIPS требует: SSL v2 и SSL v3 отключены (используются только протоколы версии TLS)
Также читайте об атаках BEAST.

Проверьте это здесь:
https://sslcheck.globalsign.com/en_US/sslcheck/?host=sbarnea.com

Итак, мне интересно, можно ли это исправить, очевидно, если он работает с Python в Ubuntu, он не может быть специфичным для всех версий python.

Мм, к сожалению, может. Относительные характеристики получаемой вами поддержки ssl зависят от установленной вами версии OpenSSL. Сравните две версии. знак равно

Просто чтобы немного завершить эту тему. Если ваш веб-сервер не поддерживает TLSv1, вы получите TLSv1.1 и 1.2 с python 2.7.9 (выйдет в декабре 2014 года). Однако вы также можете установить PYOpenSSL и ввести его в urrlib3 (http://urllib3.readthedocs.org/en/latest/security.html#openssl-pyopenssl), который, похоже, позволяет использовать запросы для веб-сервера, который отключил TLSv1 с помощью python. 2.7.6 (и, возможно, другие).

import urllib3.contrib.pyopenssl
urllib3.contrib.pyopenssl.inject_into_urllib3()

Но на самом деле веб-сервер, вероятно, не должен отказываться от чего-то, что заставляет людей прыгать через все эти странные обручи.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги