HTTPretty
HTTPretty copied to clipboard
SSLError: [Errno bad handshake] (32, 'EPIPE')
I m trying to implement httpretty to mock a https endpoint. I m getting this error.
File "util/requests_client.py", line 18, in http_do
verify=False
File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 50, in request
response = session.request(method=method, url=url, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 464, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 576, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 431, in send
raise SSLError(e, request=request)
SSLError: [Errno bad handshake] (32, 'EPIPE')
-------------------- >> begin captured logging << --------------------
requests.packages.urllib3.connectionpool: INFO: Starting new HTTPS connection (1): gateway.agms.com
--------------------- >> end captured logging << ---------------------
Hi. I had something like this problem. Trying to write unittests. I had a dependency using ndg-httpsclient 0.4.0 It called in a weird dependency on PyOpenSSL 0.15.1
If you pin to ndg-httpsclient 0.3.0 and PyOpenSSL < 0.14, that might work.
Hopefully this helps..
I too had this same problem. Downgrading to ndg-httpsclient:0.3.0
fixed the problem for me as well. Any idea why this is happening?
ndg-httpsclient is magical monkey patcher. I didn't look deeply into it but the a handshake error usually means something like httpretty is expecting sslv3 and received sslv2.
Conversely if you pin PyOpenSSL to >=0.15.1 and ndg-httpsclient to 0.4.0 it will work as well.
We had this problem too. Downgrading ndg-httpsclient:0.3.0
fixed the tests that were failing, but caused some other tests to fail with the exception
File "/home/work/.virtualenvs/develop/local/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py", line 48, in <module>
from ndg.httpsclient.ssl_peer_verification import SUBJ_ALT_NAME_SUPPORT
ImportError: cannot import name SUBJ_ALT_NAME_SUPPORT
Rather than trying to figure out what combination of ndg-httpsclient and PyOpenSSL would work for everything, we decided to go back to ndg-httpsclient:0.4.0
and work around the issue by just monkey-patching httpretty itself.
The problem is that PyOpenSSL monkey-patches the ssl_wrap_socket
function in requests/urllib3, and this version won't work with httpretty. But PyOpenSSL conveniently has inject_into_urllib3
and extract_from_urllib3
functions for doing and undoing the monkey-patch, respectively. So our solution was to just extend HTTPretty to call these functions in its disable()
and enable()
methods, respectively; then substitute in our subclass into the httpretty module.
Just use
from mypretty import httpretty
Not sure if there's a case for a pull request to merge the fix into httpretty core itself but there it is. It fixed all our failing tests!
+1 experiencing this here too
Not sure if there's a case for a pull request to merge the fix into httpretty core itself but there it is. It fixed all our failing tests!
This issue helped me too. Would be useful create a kind of FAQ to highlight issues like this one, woudn't ?
Any update on this? Is there a plan to implement a fix?
I second Clinton's question. ndg-httpsclient is part of a requests[security] update that we need in order for some code to function properly, but we have several tests that use httpretty, so our tests break upon installing this package. Do we know about how long it would take such an update to be merged?
Hey guys, just a heads up, I just submitted an MR for this issue. The changes that I implemented seem to work on my end without issue (note that they are the same as the changes mentioned above by jmcbailey, thanks for that by the way! but implemented directly into the httpretty.core file).
So what's the final fix for this issue? When I downgrade ndg-httpsclient
to 0.3.0
and test a call to my api, I get
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
</body>
</html>
I replaced httpretty with the responses library.
this issue is still reproducible in 0.8.14.
In the shell I see:
In [9]: import requests
...: import httpretty
...:
...: @httpretty.activate
...: def run(url):
...: httpretty.register_uri(httpretty.POST, url, body='somebody')
...: rs = requests.post(url)
...: return rs
...:
In [10]: run('http://google.com')
Out[10]: <Response [200]>
In [11]: run('https://google.com')
...
/Users/traut/.p3/lib/python3.6/site-packages/requests/sessions.py in send(self, request, **kwargs)
607
608 # Send the request
--> 609 r = adapter.send(request, **kwargs)
610
611 # Total elapsed time of the request (approximately)
/Users/traut/.p3/lib/python3.6/site-packages/requests/adapters.py in send(self, request, stream, timeout, verify, cert, proxies)
495 except (_SSLError, _HTTPError) as e:
496 if isinstance(e, _SSLError):
--> 497 raise SSLError(e, request=request)
498 elif isinstance(e, ReadTimeoutError):
499 raise ReadTimeout(e, request=request)
SSLError: ('bad handshake: WantWriteError()',)
also, Trevis build for my project fails with similar error:
SSLError: HTTPSConnectionPool(host='example.locahost', port=443): Max retries exceeded with url: /some/discovery/path (Caused by SSLError(SSLError("bad handshake: SysCallError(32, 'EPIPE')",),))
Any chance to get this issue addressed? There is pull request https://docs.weblate.org/en/latest/faq.html#why-do-i-get-a-warning-about-not-reflected-changes-on-database-migration which seems to fix this and several projects have already copied that fix to their codebase to address this.
Apparently the problem is not really bound to ndg-httpsclient, it just happens with requests + pyopenssl (though not on all setups).
i usually do not like promoting other projects in a projects bug tracker, but since this issue has been around for quite a while, here's a tip: using ‘responses’ instead of ‘httpretty’ seems to solve this issue with a modern requests/pyopenssl/crypography stack.
https://github.com/getsentry/responses
the api is very similar for simple use cases.