[Suggestion] allow TCP options to be set more easily

First, thanks for all the work on this library - I've been using it for about a year and it is always a joy to work with!

I've run into a situation where a request I'm making is running through a NAT that is not in my control, and the request takes >10m to complete. On a Linux machine I am able to retrieve the response using cURL, but it never completed using requests in python. I suspect this is because cURL sends TCP-level keepalive requests while the default initialization of requests does not.

In researching how I would be able to enable keepalive on the underlying sockets, it seems like I would just need to be able to provide the `socket_options` list to `requests.adapters.HTTPAdapter` at construction, and have HTTPAdapter include that in `pool_kwargs`. I imagine this could be accomplished by adding a `**kwargs` argument to `HTTPAdapter` and passing it through / merging it into `pool_kwargs`.

This issue is meant to be a discussion on the appropriateness of that solution.


For added context, below is a workaround that seems to work for me on Linux (but not OS X):

``` python
s = requests.Session()

from requests.packages.urllib3.connection import HTTPConnection
my_socket_options = HTTPConnection.default_socket_options + [
 (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
, (socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 60)
, (socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 20)
, (socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5)
]

adapter = requests.adapters.HTTPAdapter()
adapter.init_poolmanager(10, 10, block=False, socket_options=my_socket_options)
s.mount('https://', adapter)
```

I feel dirty calling `adapter.init_pooolmanager()` after constructing the `HTTPAdapter` but wasn't willing to write my own Adapter just to make that connection.


Hey @hoodja I'm glad you like the library.

We've had several (suggestions|feature requests) to add various different (and usually of little popularity) keyword arguments to `HTTPAdapter.__init__`. We've been consistently resistant because the ideology of the project author and its maintainers is to serve the 95% (or greater) use case. I personally added the ability to configure socket options to urllib3 and you're the third person I've ever found who has needed to set socket options through requests.  So we're certainly not likely to add a socket options keyword argument to `HTTPAdapter.__init__`. The [toolbelt](/sigmavirus24/requests-toolbelt) already has one or two adapters for less common but non-trivial use-cases and we can discuss there whether a `CustomSocketOptionsAdapter` would fit your needs there and what that API would look like.

Cheers!
Ian


Hey @hoodja I added both a socket options adapter to the toolbelt and a TCP Keep-Alive adapter: https://github.com/sigmavirus24/requests-toolbelt/pull/59


Thanks Ian! I'll definitely give that a spin.

On Tue, Feb 17, 2015 at 9:35 PM, Ian Cordasco notifications@github.com
wrote:

> Hey @hoodja https://github.com/hoodja I added both a socket options
> adapter to the toolbelt and a TCP Keep-Alive adapter:
> sigmavirus24/requests-toolbelt#59
> https://github.com/sigmavirus24/requests-toolbelt/pull/59
> 
> —
> Reply to this email directly or view it on GitHub
> https://github.com/kennethreitz/requests/issues/2447#issuecomment-74805834
> .