pyopenssl: maximum recursion depth exceeded while calling a Python object

I recently installed `requests[security]` to get rid of the [InsecurePlatformWarning](http://stackoverflow.com/a/29099439) and have been getting intermittent Runtime errors in pyopenssl. Here's a sample stacktrace:

```
Stacktrace (most recent call last):

  File "requests/sessions.py", line 465, in request
    resp = self.send(prep, **send_kwargs)
  File "requests/sessions.py", line 605, in send
    r.content
  File "requests/models.py", line 750, in content
    self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes()
  File "requests/models.py", line 673, in generate
    for chunk in self.raw.stream(chunk_size, decode_content=True):
  File "requests/packages/urllib3/response.py", line 307, in stream
    data = self.read(amt=amt, decode_content=decode_content)
  File "requests/packages/urllib3/response.py", line 243, in read
    data = self._fp.read(amt)
  File "python2.7/httplib.py", line 567, in read
    s = self.fp.read(amt)
  File "python2.7/socket.py", line 380, in read
    data = self._sock.recv(left)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 188, in recv
    return self.recv(*args, **kwargs)
  File "requests/packages/urllib3/contrib/pyopenssl.py", line 171, in recv
    data = self.connection.recv(*args, **kwargs)
  File "OpenSSL/SSL.py", line 1318, in recv
    buf = _ffi.new("char[]", bufsiz)
  File "cffi/api.py", line 235, in new
    if isinstance(cdecl, basestring):
```

Any ideas?


After a quick look at [WrappedSocket.recv()](https://github.com/kennethreitz/requests/blob/master/requests/packages/urllib3/contrib/pyopenssl.py#L169), seems like converting recursion to iteration could fix it. If that's the case I could make a pull request.


As you've spotted this is a urllib3 bug, so I'm closing to focus discussion there.


Thanks. On a related note, another regression I noticed since installing `requests[security]` is that `WrappedSocket.recv()` may raise `socket.timeout` and this isn't wrapped into a `requests.Timeout` that I've been handling. Should I open a new issue for it?


What's the full stacktrace?


Here's one example:

```
  File "requests/sessions.py", line 465, in request
    resp = self.send(prep, **send_kwargs)
  File "requests/sessions.py", line 594, in send
    history = [resp for resp in gen] if allow_redirects else []
  File "requests/sessions.py", line 196, in resolve_redirects
    **adapter_kwargs
  File "requests/sessions.py", line 605, in send
    r.content
  File "requests/models.py", line 750, in content
    self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes()
  File "requests/models.py", line 673, in generate
    for chunk in self.raw.stream(chunk_size, decode_content=True):
  File "requests/packages/urllib3/response.py", line 303, in stream
    for line in self.read_chunked(amt, decode_content=decode_content):
  File "requests/packages/urllib3/response.py", line 447, in read_chunked
    self._update_chunk_length()
  File "requests/packages/urllib3/response.py", line 394, in _update_chunk_length
    line = self._fp.fp.readline()
  File "python2.7/socket.py", line 447, in readline
    data = self._sock.recv(self._rbufsize)
```


I _think_ this is another manifestation of the problem fixed in shazow/urllib3#674, and so will be fixed by the 2.8.0 release of requests.


Indeed it looks like it's the same problem. Thanks, looking forward to 2.8.0!


@gsakkis feel free to try out https://github.com/kennethreitz/requests/pull/2678 to make sure it fixes the issue for you