Requests: socket.error: [Errno 54] Verbindungsreset durch Peer

Erstellt am 22. Sept. 2011  ·  19Kommentare  ·  Quelle: psf/requests

Ich erhalte derzeit den Fehler socket.error: [Errno 54] Connection reset by peer wenn ich requests.get(url, params=kwargs) und die params große Textkörper enthalten. Wenn ich die beiden großen Textkörper auf jeweils weniger als 2.900 Zeichen kürze, funktioniert es. Wenn ich dieselbe Get-Anfrage über die Befehlszeile mit curl ausführe, funktioniert es. Ich verwende Requests Version 0.6.1, die ich mit pip install python-requests installiert habe.

Ich bin mir nicht sicher, wie ich Ihnen sagen soll, dass Sie das Problem replizieren sollen, da ich die Python-Sendgrid- Bibliothek verwende, um meinem sendgrid-Konto einen Newsletter hinzuzufügen, und ich meinen API-Benutzernamen und mein Passwort nicht im Issue-Ticket veröffentlichen möchte. :)

Um von der Befehlszeile aus mit curl zu testen, habe ich zwei Dateien erstellt, die jeweils Nur-Text und HTML-Text enthielten, der mit einem Urlencoder urlencodiert wurde . Dann habe ich folgenden Befehl ausgeführt.

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

Hilfreichster Kommentar

Süße Aktion! Der Wechsel von requests.get(url, params=kwargs) zu requests.post(url, data=kwargs) Problem behoben! Sorry, dass ich dich damit belästige und danke für die Hilfe!

Alle 19 Kommentare

Hmm, interessant. Wenn dies der Fehler ist, der ausgegeben wird, habe ich wenig Grund zu der Annahme, dass der Server die Verbindung _nicht_ zurücksetzt.

Haben Sie einen HTTP-Proxy wie Charles zur Verfügung? Es könnte helfen, etwas Licht ins Dunkel zu bringen, was tatsächlich vor sich geht.

Entschuldigung, ich habe vergessen, den vollständigen Traceback bereitzustellen. Hier ist der Traceback, den ich bekomme, wenn ich den Fehler erhalte. Außerdem verstehe ich nicht, wie man den HTTP-Proxy verwendet und warum das einen Unterschied machen würde, wenn es von der Befehlszeile aus mit curl funktioniert.

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

Die Antwort, die ich von github bekomme, ist ...

<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>

Was seltsam ist, denn wie ich bereits erwähnt habe, funktioniert es mit curl .

Wenn Sie sich die Zeit nehmen, sich die beiden Anfragen durch Charles (oder ähnliches) anzusehen, werden Sie das Problem sicherlich recht schnell sehen.


Wie der Fehler sagt, ist der Request-URI zu groß für die Verarbeitung durch den Server, sodass die Verbindung abgebrochen wird.

Mit Requests senden Sie alle Daten als massive Abfragezeichenfolge im Request-URI, bekannt als GET-Parameter. Wenn Sie curl verwenden, laden Sie formularcodierte Daten in den Textkörper der Anfrage hoch, die als POST-Daten bezeichnet werden.

Ich habe versucht, sowohl requests.get(url, params=kwargs) als auch requests.post(url, params=kwargs) und beide geben den gleichen Fehler zurück. Aus irgendeinem Grund erfasst Charles keine Anfragen von curl, sondern nur Anfragen von meinem Browser und meinem Python-Befehlszeilenskript, das Python-Anfragen verwendet.

Kein Problem.

params ist für Abfragezeichenfolgen, data ist für POST-Daten.

Süße Aktion! Der Wechsel von requests.get(url, params=kwargs) zu requests.post(url, data=kwargs) Problem behoben! Sorry, dass ich dich damit belästige und danke für die Hilfe!

Keine Sorge :)

Es ist seltsam, dass ich bei ähnlichen Daten den gleichen Fehler erhalte, der einzige Unterschied besteht darin, dass ich in meinem Fall keine große Liste oder Größe von Parametern habe. Die gleiche Anfrage über CURL funktioniert einwandfrei, aber über Anfragen bekomme ich diesen Fehler.

Requests.Exceptions.ConnectionError: HTTPSConnectionPool(host='sbarnea.com', port=443): Max. Wiederholungen überschritten mit URL: /jira/rest/api/2/group?groupname=jira-administrators&expand=users (Verursacht durch: [Errno 54] Verbindungsreset durch Peer)

Noch interessanter scheint es, dass die Anfrage nicht einmal den Webserver erreicht.

Irgendeine Idee woran es liegen könnte?

@ssbarnea Dieses Problem ist mehr als zwei Jahre alt: Es hat nichts mit dem Problem zu tun, das Sie derzeit haben. =) Können Sie bitte eine neue Ausgabe eröffnen, um Ihr Problem zu verfolgen?

Noch besser, öffnen Sie kein Problem, sprechen Sie mit StackOverflow, Sie stellen eine Frage und haben keinen Grund zu der Annahme, dass es sich um ein Problem mit dem Verhalten von Anfragen handelt. Hash die Details auf StackOverflow und dann können wir einen Fehlerbericht einreichen (falls erforderlich).

Es ist ein sehr seltsames Verhalten und ich habe Grund zu der Annahme, dass es sich nicht um einen Fehler in Anfragen handelt, deshalb habe ich einen neuen Fehler geöffnet. Ich untersuche immer noch, was dies verursachen könnte, es passiert nur von meinem Computer aus, aber der interessanteste Teil ist, dass CURL funktioniert (und auch Browser). Dankeschön.

Entschuldigung, dass ich das hier behalte, aber ich habe die Ursache dafür gefunden:

#  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;

Durch das Deaktivieren dieser Tunnings auf dem nginx-Server begann er mit Anfragen zu arbeiten, wobei eindeutig einer von ihnen die Fehlfunktion verursacht.

@ssbarnea
Es ist höchstwahrscheinlich ein fehlerhafter Server, der in bestimmten SSL/TLS-Versionen, wie in #1567 (und mehreren mehr) beschrieben, falsche Sachen macht, wenn er angesprochen wird.
Versuchen Sie, eine andere Version zu zwingen , wie es erklärt wird hier (einige mehr ein dickes Lob an @Lukasa)

Und der Gewinner (Verlierer) ist ssl_protocols TLSv1.2 TLSv1.1;
Es scheint, dass das Entfernen von TLSv1 aus den unterstützten Protokollen auf dem Server verhindert, dass Anfragen funktionieren.

Kann ich das jetzt als Fehler in Anfragen oder als zugrunde liegende Bibliothek bezeichnen?

Hinweis: Das Entfernen von TLSv1 wird aus Sicherheitsgründen empfohlen, da es Exploits gibt.

@ssbarnea Sie werden feststellen, dass die Einschränkung nicht in Requests, sondern in Python liegt. Derzeit unterstützt keine der ausgelieferten Python-Versionen eine neuere TLS-Version als V1.0, wie Sie in der Tabelle hier sehen können .

Python 3.4 (noch nicht ausgeliefert, keine Garantie, dass Requests damit kompatibel ist) unterstützt TLS1.2 und TLS1.1, also können Sie es damit versuchen. Andernfalls müssen Sie TLSv1 erlauben, Anfragen durchzulassen.

Trotzdem gibt es etwas Seltsames: In beiden Fällen habe ich Python verwendet, beim Testen von OS X ist es fehlgeschlagen, beim Testen von Ubuntu hat es funktioniert.

Normalerweise würde ich die Standardeinstellungen für SSL nicht berühren, aber ich führe einen SSL-Bericht aus und habe versucht, die meisten Warnungen zu lösen:

FIPS erfordert: SSL v2 und SSL v3 sind deaktiviert (nur Protokolle der TLS-Version werden verwendet)
Lesen Sie auch über BEAST-Angriffe.

Überprüfen Sie es hier:
https://sslcheck.globalsign.com/en_US/sslcheck/?host=sbarnea.com

Ich frage mich also, ob es möglich ist, dies zu beheben. Wenn es mit Python unter Ubuntu funktioniert, kann es nicht für alle Python-Versionen spezifisch sein.

Hm, das kann es leider. Die relativen Funktionen der ssl Unterstützung, die Sie erhalten, hängen von der Version von OpenSSL ab, die Sie installiert haben. Vergleichen Sie die beiden Versionen. =)

Nur um das Thema kurz abzuschließen. Wenn Ihr Webserver TLSv1 nicht zulässt, erhalten Sie mit Python 2.7.9 TLSv1.1 und 1.2 (erscheint im Dezember 2014). Sie können jedoch auch PYOpenSSL installieren und in urrlib3 (http://urllib3.readthedocs.org/en/latest/security.html#openssl-pyopenssl) einfügen, was die Verwendung von Anforderungen für einen Webserver zu ermöglichen scheint, der TLSv1 mit Python deaktiviert hat 2.7.6 (und wahrscheinlich andere).

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

Aber wirklich, der Webserver sollte wahrscheinlich nichts ablehnen, was die Leute dazu zwingt, durch diese vielen seltsamen Reifen zu springen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

jakul picture jakul  ·  3Kommentare

thadeusb picture thadeusb  ·  3Kommentare

NoahCardoza picture NoahCardoza  ·  4Kommentare

avinassh picture avinassh  ·  4Kommentare

Matt3o12 picture Matt3o12  ·  3Kommentare