Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python requests.exceptions.SSLError: EOF occurred in violation of protocol

I would retrieve some information from an ABB G13 gateway that offer a RESTful JSON API. API is hosted by the gateway via https endpoint. Basic authentication mechanism is used for authentication. However all traffic goes through SSL layers.

On linux with command:

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

All goes well!

I'm trying to write a script for windows in Python 2.7.10 with Requests 2.8.1 and with this code:

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

I have this error:

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)

I've searched for a solution and I've tried to fix with this code:

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

But it doesn't work for me cause I get this error:

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)

I'm stuck on this problem. Could someone help me? Thanks!

like image 294
mzilio Avatar asked Oct 29 '15 09:10

mzilio


3 Answers

This thing worked for me, just make sure whether these modules are installed or not, if not then install them, following are:

pip install ndg-httpsclient

pip install pyopenssl

pip install pyasn1

It removed my SSLError: EOF occurred in violation of protocol (_ssl.c:590) error.

Hope it helps.

like image 188
enigma Avatar answered Nov 15 '22 23:11

enigma


I found it was going through a proxy when it should have connected to the server directly.

I fixed this by doing

unset https_proxy
like image 10
A G Avatar answered Nov 16 '22 01:11

A G


Step 1: Check that Python supports TLS 1.1

You may have a Python setup that only supports TLS 1.0 – not TLS 1.1 or above.

You can check it like this:

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

(If you get urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852)> you may have to disable certificate verification. NOTE: doing this will disable SSL protections against evildoers who would impersonate or intercept traffic to that website - see https://en.wikipedia.org/wiki/Man-in-the-middle_attack )

import ssl
urlopen('https://www.howsmyssl.com/a/check', context=ssl._create_unverified_context()).read()

Check the output for the key tls_version. If it says TLS 1.0 and not TLS 1.1 or TLS 1.2 that could be the problem.

If you're using a virtualenv, be sure to run the command inside.

Step 2: Install Python with a newer version of OpenSSL

In order support TLS 1.1 or above, you may need to install a newer version of OpenSSL, and the install Python again afterwards. This should give you a Python that supports TLS 1.1.

The process depends on your operating system – here's a guide for OS X.

virtualenv users
For me, the Python outside of my virtualenv had TLS 1.2 support, so just I removed my old virtualenv, and created a new one with the same packages and then it worked. Easy peasy!

like image 10
qff Avatar answered Nov 16 '22 01:11

qff