Python 3 Windows SSL issue

I'm not super awesome at Python, so I'd appreciate any help you can provide to help nail down this issue.

Newer versions of Python 3 on Windows appear to have an issue when doing an ssl handshake. This appears to be a problem with urllib3 on Windows python packages only. I was able to successfully use Python 3.3.2 and 3.2.4 on Ubuntu without this issue.

Effected Versions: Windows Python 3.3.x, 3.2.x

Works in: Non-Windows Python 3.3.x, 3.2.x, Windows 3.1.x

While I'm almost certain here the bug is actually in Python's urllib3 and not Requests, I'm not super experienced, so I feel a little over my head. Of course, this bug effects anyone who uses Requests too. It appears related to this bug: http://bugs.python.org/issue16361

In order to communicate with the server, I am using Lantern: https://github.com/dechols/lantern

```
    v = lantern.AbstractAPI(username, password)
    v.get_app_list()
```

Which causes the failure.

But even using a very simple GET with requests directly, causes the same issue:

```
    r = requests.get(url="https://analysiscenter.veracode.com/api/4.0/getapplist.do", auth=(username, password))
```

Please help! I'd love to get this fixed, where-ever it might need fixing.

```
Traceback (most recent call last):
  File "C:\Python33\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 428, in urlopen
    body=body, headers=headers)
  File "C:\Python33\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 280, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "C:\Python33\lib\http\client.py", line 1061, in request
    self._send_request(method, url, body, headers)
  File "C:\Python33\lib\http\client.py", line 1099, in _send_request
    self.endheaders(body)
  File "C:\Python33\lib\http\client.py", line 1057, in endheaders
    self._send_output(message_body)
  File "C:\Python33\lib\http\client.py", line 902, in _send_output
    self.send(msg)
  File "C:\Python33\lib\http\client.py", line 840, in send
    self.connect()
  File "C:\Python33\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 107, in connect
    ssl_version=resolved_ssl_version)
  File "C:\Python33\lib\site-packages\requests\packages\urllib3\util.py", line 369, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "C:\Python33\lib\ssl.py", line 210, in wrap_socket
    _context=self)
  File "C:\Python33\lib\ssl.py", line 310, in __init__
    raise x
  File "C:\Python33\lib\ssl.py", line 306, in __init__
    self.do_handshake()
  File "C:\Python33\lib\ssl.py", line 513, in do_handshake
    self._sslobj.do_handshake()
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Python33\lib\site-packages\requests\adapters.py", line 292, in send
    timeout=timeout
  File "C:\Python33\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 474, in urlopen
    raise MaxRetryError(self, url, e)
[Finished in 61.3s with exit code 1]requests.packages.urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='analysiscenter.veracode.com', port=443): Max retries exceeded with url: /api/4.0/getapplist.do (Caused by <class 'ConnectionResetError'>: [WinError 10054] An existing connection was forcibly closed by the remote host)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\tfs\Vertafore_TFSDev\CQ\veracode\pythontestscriptonation.py", line 11, in <module>
    r = requests.get(url="https://analysiscenter.veracode.com/api/4.0/getapplist.do", auth=(username, password))
  File "C:\Python33\lib\site-packages\requests\api.py", line 55, in get
    return request('get', url, **kwargs)
  File "C:\Python33\lib\site-packages\requests\api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Python33\lib\site-packages\requests\sessions.py", line 335, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Python33\lib\site-packages\requests\sessions.py", line 438, in send
    r = adapter.send(request, **kwargs)
  File "C:\Python33\lib\site-packages\requests\adapters.py", line 327, in send
    raise ConnectionError(e)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='analysiscenter.veracode.com', port=443): Max retries exceeded with url: /api/4.0/getapplist.do (Caused by <class 'ConnectionResetError'>: [WinError 10054] An existing connection was forcibly closed by the remote host)
```


This is a duplicate of #1289. Right?
According to the bugreport you linked it's an issue with the SSL/TLS version requests is using to connect to the server.
@Lukasa wrote a blogpost about customizing the version, requests uses: http://lukasa.co.uk/2013/01/Choosing_SSL_Version_In_Requests/

I modified the code from the blog a bit, so that it works with the current version of requests:
(Try to remove `s.mount()` to break it again)

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


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

import requests
s = requests.Session()
s.mount('https://', MyAdapter())

print(s.get('https://analysiscenter.veracode.com'))
```

Btw, I also couldn't connect from my arch box.
And also congratulations for open sourcing your project!


> This is a duplicate of #1289. Right?

Yes. I think I have a better grasp on what's actually going on now, so I opened a new one because maybe there's a chance I can fix this now.

I'll take a look at the code and see if I can get it to work. :) THANK YOU!

Edit: IT WORKED! Now I have even more questions than when I started...


So I understand _how_ the code above works and how patching the HTTPS session variable works.

But I still don't understand _why_ this only fails to work on versions of Python (3.2/3.3) on Windows only. Do versions of Python on Windows include buggy versions of ssl? or do they not include new versions of ssl?

I just think that's pretty weird, that only windows distros of python would have this issue.


I suspect (I'm not sure) the server is buggy. It sees a TLS version it doesn't recognize and then stops responding, while the client is waiting for a respones, even an error would be better.
I have the same problem on archlinux with openssl 1.0.1.e. Rereading your last bugreport it seems It worked for me back then, with an older version of openssl.
This older version presumably used a lower TLS version, which didn't freak out the server.
So the version is rather too new :smile:

@Lukasa You may want to update your blogpost to include the `block` argument, which is needed nowadays.


Thank you t-8ch. I will bring this up with Veracode and see if we can investigate. THANK YOU SO MUCH.


@t-8ch Thanks for pointing it out, when I get my internet connection back I'll do just that. =)