Python demande des requêtes.exception.SSLError: [Errno 8] ssl.c: 504: L'EOF s'est produit en violation du protocole
je suis sur Ubuntu 12.10 avec OpenSSL 1.0.1 c, python 2.7.3, Demandes 1.0.3 et 1.0.4 (essayé les deux), et lorsque vous tentez de vous connecter au site web de la variable d'url avec le code suivant.
def SendInitialRequest(xmlmessage, redirecturl):
url = 'https://centineltest.cardinalcommerce.com/maps/txns.asp'
payload = 'cmpi_msg=' + ET.tostring(xmlmessage)
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
}
r = requests.post(url, data=payload, headers=headers, verify=None)
print r.text
il lance l'erreur suivante:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "clams/libs/centinel/thinclient.py", line 134, in SendInitialRequest
r = requests.post(url, data=payload, headers=headers, verify=None)
File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/api.py", line 87, in post
return request('post', url, data=data, **kwargs)
File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/api.py", line 44, in request
return session.request(method=method, url=url, **kwargs)
File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/sessions.py", line 269, in request
resp = self.send(prep, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies)
File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/sessions.py", line 364, in send
r = adapter.send(request, **kwargs)
File "/home/jasonamyers/.virtualenv/clams/lib/python2.7/site-packages/requests/adapters.py", line 163, in send
raise SSLError(e)
requests.exceptions.SSLError: [Errno 8] _ssl.c:504: EOF occurred in violation of protocol
tenter la connexion avec openssl renvoie ce qui suit:
$ openssl s_client -connect centineltest.cardinalcommerce.com:443
CONNECTED(00000003)
140019346777760:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:s23_lib.c:177:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 226 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
---
si je le force à utiliser tls1 il fonctionne (sortie tronqué):
$ openssl s_client -tls1 -connect centineltest.cardinalcommerce.com:443
CONNECTED(00000003)
depth=2 C = US, O = "thawte, Inc.", OU = Certification Services Division, OU
verify error:num=20:unable to get local issuer certificate
verify return:0
---
j'ai vu de nombreux rapports de bogues pour ceci; cependant, je n'ai pas trouvé un moyen de le contourner en utilisant la bibliothèque des requêtes python. Toute aide serait grandement appréciée.
10 réponses
Reposter ici pour d'autres de la demande de la page :
Requests " ne supporte pas de faire cela avant la version 1. Après la version 1, Vous êtes censé sous-classe le HTTPAdapter, comme suit:
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)
quand vous avez fait cela, vous pouvez le faire:
import requests
s = requests.Session()
s.mount('https://', MyAdapter())
toute requête via cet objet de session utilisera alors TLSv1.
paramètre verify=False ne fait que sauter la vérification du certificat du serveur, mais ne permettra pas de résoudre les erreurs de protocole SSL.
ce problème est probablement dû au fait que SSLv2 est désactivé sur le serveur web, mais Python 2.x essaie d'établir une connexion avec PROTOCOL_SSLv23 par défaut. Cela se produit à https://github.com/python/cpython/blob/360aa60b2a36f5f6e9e20325efd8d472f7559b1e/Lib/ssl.py#L1057
Vous pouvez singe-patch SSL.wrap_socket () dans le module ssl en remplaçant le paramètre mot-clé ssl_version. Le code suivant peut être utilisé comme tel. Mettre ceci au début de votre programme avant de faire toute demande.
import ssl
from functools import wraps
def sslwrap(func):
@wraps(func)
def bar(*args, **kw):
kw['ssl_version'] = ssl.PROTOCOL_TLSv1
return func(*args, **kw)
return bar
ssl.wrap_socket = sslwrap(ssl.wrap_socket)
installation des options du paquet "sécurité" pour requests
résolu pour moi:
sudo apt-get install libffi-dev
sudo pip install-U des demandes[de sécurité]
c'est un bug connu, vous pouvez le contourner avec un hack:
ouvrez site-packages/requests/packages/urllib3/connectionpool.py
(ou faites une copie locale des requêtes à l'intérieur de votre propre projet), et changez le bloc qui dit:
def connect(self):
# Add certificate verification
sock = socket.create_connection((self.host, self.port), self.timeout)
# Wrap socket using verification with the root certs in
# trusted_root_certs
self.sock = ssl_wrap_socket(sock, self.key_file, self.cert_file,
cert_reqs=self.cert_reqs,
ca_certs=self.ca_certs,
server_hostname=self.host,
ssl_version=self.ssl_version)
à:
def connect(self):
# Add certificate verification
sock = socket.create_connection((self.host, self.port), self.timeout)
# Wrap socket using verification with the root certs in
# trusted_root_certs
self.sock = ssl_wrap_socket(sock, self.key_file, self.cert_file,
cert_reqs=self.cert_reqs,
ca_certs=self.ca_certs,
server_hostname=self.host,
ssl_version=ssl.PROTOCOL_TLSv1)
sinon, je suppose qu'il y a un contrôleur quelque part qui est moins hacky, mais je n'ai pas pu en trouver un avec quelques regards.
NOTE : sidenote, requests
de PIP (1.0.4) sur un MacOS ne fonctionne qu'avec l'URL que vous avez fournie.
j'ai rencontré cette erreur, et le correctif semble désactiver SNI, ce que Python 2.7 ne supporte pas:
pour les gens qui ne peuvent pas obtenir au-dessus des corrections de travail.
a dû changer de fichier ssl.py pour arranger ça. Rechercher la fonction create_default_context et modifier la ligne:
context = SSLContext(PROTOCOL_SSLv23)
à
context = SSLContext(PROTOCOL_TLSv1)
peut-être que quelqu'un peut créer une solution plus facile sans éditer ssl.py Je ne sais pas.
j'ai eu le même problème:
raise SSLError (e)
demande.exception.SSLError: [Errno 8] _ssl.c:504: EOF eu lieu en violation du protocole
j'ai fait courir fiddler, j'ai arrêté la capture de fiddler et je n'ai pas vu cette erreur. Peut-être parce que de violoneux.
malheureusement, la réponse acceptée n'a pas fonctionné pour moi. Comme solution temporaire, vous pouvez également utiliser verify=False
lorsque vous vous connectez au site Web sécurisé.
From Python Requests giving up SSLError
requests.get('https://example.com', verify=True)
j'ai eu cette erreur en me connectant à un serveur MQTT RabbitMQ via TLS. Je suis assez sûr que le serveur est cassé mais de toute façon il a fonctionné avec OpenSSL 1.0.1, mais pas OpenSSL 1.0.2.
vous pouvez vérifier votre version en Python en utilisant ceci:
import ssl
ssl.OPENSSL_VERSION
Je ne suis pas sûr de savoir comment déclasser OpenSSL en Python (il semble être lié statiquement sur Windows au moins), à part utiliser une ancienne version de Python.
j'avais un problème similaire et je pense que si nous ignorons simplement la vérification ssl
fonctionnera comme charme comme il a fonctionné pour moi. Donc se connecter au serveur avec le schéma https
mais en leur demandant de ne pas vérifier le certificat.
par requests
. Il suffit de mentionner verify=False
au lieu de None
requests.post(url, data=payload, headers=headers, verify=False)
en Espérant que cela fonctionne pour ceux qui ont besoin :).