Stuck on request when changing proxy while inside a session

Hi,

I've been tinkering with the following issue for the last couple of days and boy it was frustrating.. The issue is not being able to sent requests after you've changed your external IP adress while inside a sesison. It took me a while to figure this out.

Like I said the problem only excist if you're inside a session for some reason the requests are just stuck, for ever. I tested the same thing without a session and that works just fine.


When you say "changed your external IP address", what exactly do you mean?


Hi,

I've written a script which I use on my Raspberry Pi plugged with 3G modem. So I use the 3G modem to connect and make requests. I've also written a script that changes the external IP adress of the modem. It's like a proxy server basically.


I'm still not entirely following. What does changing the IP address look like to your OS?


Hey, I have been having the same issue.
I stripped my code down till the bare minimum needed to reproduce this issue consistently.

_test1.py_ reproduces the issue, as it will hang forever on the second request, and it will eventually timeout when we set a timeout.

_test2.py_ ommits the session object and makes a regular request in the same fashion, however does not 'hang' and executes like expected.

---

See here _test1.py_:

```
import requests
import time


# Create session object.
s = requests.session()


# Simple request using the session object.
s.post('http://httpbin.org')  # <= Makes request without issue. (!!)


# Fetch verification token for the 3G modem
token = requests.get('http://192.168.8.1/api/' + 'webserver/token').content
token = lxml.html.fromstring(token).xpath('//token/text()')[0]

# Change 3G session variable by logging in
requests.post('http://192.168.8.1/api/' + 'user/login',
    headers={'__RequestVerificationToken': token},
    data= '<?xml version="1.0" encoding="UTF-8"?><request><Username>admin</Username><Password>YWRtaW4=</Password></request>'
)

# Disconnect from 3G network
requests.post('http://192.168.8.1/api/' + 'dialup/mobile-dataswitch',
    headers={'__RequestVerificationToken': token},
    data= '<?xml version="1.0" encoding="UTF-8"?><request><dataswitch>0</dataswitch></request>'
)

# Connect to 3G network, with a new IP (hopefully)
requests.post('http://192.168.8.1/api/' + 'dialup/mobile-dataswitch',
    headers={'__RequestVerificationToken': token},
    data= '<?xml version="1.0" encoding="UTF-8"?><request><dataswitch>1</dataswitch></request>'
)

# A small delay to make sure we are connected.
time.sleep(15)


# Simple request using the session object.
s.post('http://httpbin.org')  # <= Hangs forever. (!!)
```

See here _test2.py_:

```
import requests
import time


# Create session object.
s = requests.session()


# Simple request WITHOUT using the session object.
requests.post('http://httpbin.org')  # <= Makes request without issue. (!!)


# Fetch verification token for the 3G modem
token = requests.get('http://192.168.8.1/api/' + 'webserver/token').content
token = lxml.html.fromstring(token).xpath('//token/text()')[0]

# Change 3G session variable by logging in
requests.post('http://192.168.8.1/api/' + 'user/login',
    headers={'__RequestVerificationToken': token},
    data= '<?xml version="1.0" encoding="UTF-8"?><request><Username>admin</Username><Password>YWRtaW4=</Password></request>'
)

# Disconnect from 3G network
requests.post('http://192.168.8.1/api/' + 'dialup/mobile-dataswitch',
    headers={'__RequestVerificationToken': token},
    data= '<?xml version="1.0" encoding="UTF-8"?><request><dataswitch>0</dataswitch></request>'
)

# Connect to 3G network, with a new IP (hopefully)
requests.post('http://192.168.8.1/api/' + 'dialup/mobile-dataswitch',
    headers={'__RequestVerificationToken': token},
    data= '<?xml version="1.0" encoding="UTF-8"?><request><dataswitch>1</dataswitch></request>'
)

# A small delay to make sure we are connected.
time.sleep(15)


# Simple request WITHOUT using the session object.
requests.post('http://httpbin.org')  # <= Makes request without issue. (!!)
```

Running without passing a timeout argument to the call there does not seem to be an error / traceback, all it does is 'hang', again passing a timeout argument in the call makes the request timeout and provides a timeout error.


It should be clarified we are using python 3.5 on the Raspbian OS.


Let's be clear. A `Session` object uses connection pooling; that is, it keeps hold of connections if possible to increase efficiency. That includes `socket` objects, which otherwise cause us to need to make syscalls to recreate them. 

If you change your source IP, I wouldn't be at all surprised to find that those sockets no longer behave as expected. You'd need to invalidate them by closing the Session and using a new one, or at least clearing the pools. 


Thanks for the details, didn't know that. Seeing as a similar setup worked in the past like expected I am assuming it has to do with the logic of the code rather than the module itself.

I'll keep investigating!