GET request to "https://sso.queensu.ca" Connection reset by peer

with python 2.7.5

``` python
import requests
requests.__version__
'1.2.3'
requests.get("https://sso.queensu.ca")
```

fails with:

``` python
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/site-packages/requests/api.py", line 55, in get
    return request('get', url, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests/api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 335, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 438, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests/adapters.py", line 327, in send
    raise ConnectionError(e)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='sso.queensu.ca', port=443): Max retries exceeded with url: / (Caused by <class 'socket.error'>: [Errno 104] Connection reset by peer)
```

The get request is successful (200) with Firefox, so I tried passing in kwarg `headers` with the headers of my browser to the same error (I thought it might have been a User-Agent issue). I can't find out how to get any more information than that Traceback.


So I think this is an SSL problem, because I have no problems running this query on my Windows box. What OS are you using?

Also, let's ping @t-8ch for his expertise here. =)


@jameh can you inspect the headers that Firefox receives when you visit that site? I have an idea that this might be unrelated to SSL but I cannot be sure. Thanks in advance.


I can reproduce this on Arch x64 with both python2 and 3.
If I force the SSL version to be `TLSv1` like described on [@Lukasa s blog](http://lukasa.co.uk/2013/01/Choosing_SSL_Version_In_Requests/) it works for me.


Problem is that the server simply doesn't respond at all to a TLSv1.2 handshake.


@t-8ch so is it then safe to say this is not an issue with requests?

Should we turn this into a feature request for falling back on older versions of TLS? I would really rather we didn't given how broken some of them are. If we automatically fall back on them we'll avoid bug reports like this but we will be giving our users a somewhat false sense of security, no? I for one would rather deal with these bug reports than compromise our users' security.

On a related note, could you provide your method of detecting what the server will accept/respond to? I would rather not keep bugging you @t-8ch. I don't want to keep nagging you to figure out our TLS/SSL issues.


Yes, I don't think this is an issue with requests.

Falling back to older versions of TLS shouldn't be much of an issue securitywise (if we stay in TLS land).
On the other hand broken servers respond in all imaginable ways to handshakes.
If they behave correctly they could simply negotiate a lower version of TLS or
abort the handshake correctly which will result in an SSLError with a more or
less understandable error message.
If they are broken it's down to pure guessing what an error means.
(Servers reset the connection, send no certificate, time out and whatnot)
I really doubt we want to do this :smile:

@sigmavirus24
The best way is probably the utility `gnutls-cli` which is part of `gnutls`.
One can use it like this:

```
gnutls-cli --priority=NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2 sso.queensu.ca
```

This means: Use your normal settings, but only use TLSv1.2 as TLS version, then
connect to the given host (port 443 is the default).
(Full docs are here: http://www.gnutls.org/manual/html_node/Priority-Strings.html, `openssl s_client` has similary functionality)


@t-8ch how complex is the re-negotiation process? I think the only good idea is to raise an exception when the server is doing something unexpected and re-negotiate only when it explicitly asks us to. If you don't have time to describe the process of negotiation, feel free to link the RFC.

In the meantime, I'm going to open an issue/feature request for this and close this issue. Thanks for opening @jameh


Thanks a lot @t-8ch and everyone. Yes I was on Arch Linux x64. Subclassing the HTTPAdapter class as shown on [your blog](http://lukasa.co.uk/2013/01/Choosing_SSL_Version_In_Requests/) and indicating to use `ssl.PROTOCOL_TLSv1` got me my 200 response. :)


@sigmavirus24 I got it a bit wrong. There isn't an explicit negotiation of the TLS version. Instead the client sends a handshake with the highest version it supports the server then can respond with the version it wishes to use.

[RFC 5246 Appendix E](https://tools.ietf.org/html/rfc5246#appendix-E):

```
A TLS 1.2 client who wishes to negotiate with such older servers will
send a normal TLS 1.2 ClientHello, containing { 3, 3 } (TLS 1.2) in
ClientHello.client_version.  If the server does not support this
version, it will respond with a ServerHello containing an older
version number.  If the client agrees to use this version, the
negotiation will proceed as appropriate for the negotiated protocol.
```

So a server timing out is simply broken.


I think we aren't beholden to do anything smart when servers do something so totally wrong. =D


@Lukasa but we could support an older version of TLS.


We do. =D

As @t-8ch points out, there is an explicit negotiation for TLS version, and we support them all. The problem here was that the server utterly failed to perform that negotiation.