it-swarm.com.de

Python-Anforderungen.Exceptions.SSLError: EOF ist protokollverletzt aufgetreten

Ich würde einige Informationen von einem ABB G13-Gateway abrufen, die eine RESTful-JSON-API anbieten. Die API wird vom Gateway über den https-Endpunkt gehostet. Für die Authentifizierung wird ein Standardauthentifizierungsmechanismus verwendet. Der gesamte Datenverkehr Durchläuft jedoch SSL-Schichten.

Unter Linux mit dem Befehl:

curl -s -k -X GET -u user:password https://Host/meters/a_serial/power

Alles wird Gut!

Ich versuche, ein Skript für Windows in Python 2.7.10 mit Requests 2.8.1 und mit diesem Code zu schreiben:

import requests
requests.get('https://Host/meters/a_serial/power', auth=('user', 'password'))

Ich habe diesen Fehler:

Traceback (most recent call last):
  File "C:/Users/mzilio/PycharmProjects/pwrgtw/test.py", line 20, in <module>
    requests.get('https://Host/meters/a_serial/power', auth=('user', 'password'))
  File "C:\Python27\lib\site-packages\requests\api.py", line 69, in get
    return request('get', url, params=params, **kwargs)
  File "C:\Python27\lib\site-packages\requests\api.py", line 50, in request
    response = session.request(method=method, url=url, **kwargs)
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 468, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 576, in send
    r = adapter.send(request, **kwargs)
  File "C:\Python27\lib\site-packages\requests\adapters.py", line 433, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: EOF occurred in violation of protocol (_ssl.c:590)

Ich habe nach einer Lösung gesucht und versucht, mit diesem Code zu beheben:

import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
import ssl

class MyAdapter(HTTPAdapter):
    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(num_pools=connections,
                                       maxsize=maxsize,
                                       block=block,
                                       ssl_version=ssl.PROTOCOL_TLSv1)

s = requests.Session()
s.mount('https://', MyAdapter())
s.get('https://Host/meters/a_serial/power')

Aber es funktioniert nicht für mich, weil ich diesen Fehler bekomme:

Traceback (most recent call last):
  File "C:/Users/mzilio/PycharmProjects/pwrgtw/test.py", line 16, in <module>
    s.get('https://Host/meters/a_serial/power')
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 480, in get
    return self.request('GET', url, **kwargs)
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 468, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 576, in send
    r = adapter.send(request, **kwargs)
  File "C:\Python27\lib\site-packages\requests\adapters.py", line 433, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: EOF occurred in violation of protocol (_ssl.c:590)

Ich halte dieses Problem fest. Könnte mir jemand helfen? Vielen Dank!

6
mzilio

Dieses Ding hat für mich funktioniert, vergewissere dich einfach, ob diese Module installiert sind oder nicht, wenn nicht, dann installiere sie:

pip install ndg-httpsclient

pip install pyopenssl

pip install pyasn1

Mein SSLError wurde entfernt: EOF trat in Verletzung des Protokollfehlers (_ssl.c: 590) auf.

Ich hoffe es hilft.

8

Ich hatte genau den gleichen Fehler, es stellte sich heraus, dass ich ndg-httpsclients nicht installiert hatte. Siehe mein ursprüngliches issue in github.

3
James Lin

Ich fand heraus, dass es sich um einen Proxy handelte, als er direkt mit dem Server verbunden sein sollte.

Ich habe das Problem dadurch behoben

unset https_proxy
2
A G

Schritt 1: Überprüfen Sie, ob Python TLS 1.1 unterstützt

Sie haben möglicherweise ein Python-Setup, das nur TLS 1.0 unterstützt - nicht TLS 1.1 oder höher.

Sie können es so überprüfen:

Python 3

> from urllib.request import urlopen
> urlopen('https://www.howsmyssl.com/a/check').read()

Python 2

> from urllib2 import urlopen
> urlopen('https://www.howsmyssl.com/a/check').read()

Überprüfen Sie die Ausgabe für den Schlüssel tls_version. Wenn dort TLS 1.0 und nicht TLS 1.1 oder TLS 1.2 steht, könnte dies das Problem sein.

Wenn Sie eine Virtualenv verwenden, müssen Sie den Befehl innen ausführen.

Schritt 2: Installieren Sie Python mit einer neueren Version von OpenSSL

Um TLS 1.1 oder höher zu unterstützen, müssen Sie möglicherweise eine neuere Version von OpenSSL installieren und anschließend Python erneut installieren. Dies sollte Ihnen einen Python geben, der TLS 1.1 unterstützt.

Der Vorgang hängt von Ihrem Betriebssystem ab - hier ist eine Anleitung für OS X .

virtualenv Benutzer
Für mich hatte der Python außerhalb meiner virtualenv TLS 1.2-Unterstützung, also habe ich nur meine alte virtualenv entfernt und ein neues mit den gleichen Paketen erstellt, und dann funktionierte es. Kinderleicht!

1
qff

Wenn Sie diesen Fehler für Zwischenanfragen erhalten, können Sie auf die in https://github.com/requests/requests/issues/3391 erwähnte Lösung verweisen.

Grundsätzlich können Sie Session verwenden, um die Anforderungen zu wiederholen, wenn Sie viele Anfragen an einen Server stellen und dieses Problem mit einigen dieser Anforderungen konfrontiert wird. 

Sag mir, ob das funktioniert.

1
varun

Das einzige Mal, dass ich Fehler dieser Art gesehen habe, waren Zeiten, in denen ich requests zum Scannen von Daten und eine Multiprocessing-Bibliothek verwendete. Ich würde Ihren Code entweder ohne den Pool-Manager ausprobieren oder Ihre App in zwei Apps aufteilen, eine, die URLs ausgibt, und eine, die sie verbraucht.

Das Client-Server-Paar hier sollte Ihnen einige Ideen geben. Ich konnte meinen Client horizontal skalieren, als ich den Hacky-Server-Code zum Laden aller URLs in eine Warteschlange im Speicher unmittelbar vor app.run verwendet habe. Hoffentlich hilft das.

0
hughdbrown