post() hangs when data is large(-ish)

This is the call in question:

```
r = requests.post(url, auth=creds, data=json.dumps(post_data), 
                  headers={'content-type':'application/json'})
```

post_data is a dictionary.
post_data['x'] is a string of varying length:

```
post_data['x'] = '.' * L
```

(a) For L < 3487 and creds is correct username/password, I receive expected 200 response right away.
(b) For L < 3487 and creds is incorrect username/password, I receive expected 401 response right away.
(c) For L >= 3487 and creds is correct username/password, I receive expected 200 response right away.
(d) For L >= 3487 and creds is incorrect username/password, the call hangs for about a minute and then I receive 401 response, but the data is empty (r.text is empty string).  I expect a JSON response which I do receive properly in (b) above.

On the server hosting the url, I see the response go out right away in all cases.  Is there anything more I can do to further isolate this and figure out what's going on?  I don't know if L=3487 is specific to my system or not; could be higher or lower for others.  I am using Python 2.7 and requests 2.3.0.


Interesting.

Here's the way the requests stack works. When we send a request in this form, we send all the headers and then immediately send the body. What we _don't_ do is attempt to read the response before sending the body: this is simply not a flow that `httplib` allows.

If the endpoint server _knows_ that it doesn't want to accept the message (because the auth credentials are wrong), it may want to immediately return the 401 and then disregard our body data. That's totally fine, but I wonder what happens if it then stops pumping the socket for data. I suspect it will fill up the TCP buffer, causing the TCP congestion window to kick in and slow data transfer. That would explain the long latency in getting the response: the latency is actually in the call to send data.

As for the response data being empty, that won't be requests' problem. Either the server is at fault (it never sent the data), or `httplib` is.

The best way to profile this would be to dump the traffic using tcpdump and then analyse it. I have two questions: a) is your traffic going over HTTP or HTTPS; and b) are you familiar with tcpdump?


a) HTTP at the moment.  HTTPS will come when plain HTTP is working.
b) No, but I can get familiar with it.  Or could I use Wireshark?  The server is a flask app running on Linux.  I'm running the python client on Win7. 


OK, got familiar with tcpdump .  It's so much easier than Wireshark for analysis.  Issue is not with requests.  In case (b) and (d) from original post, server was returning HTTP response with content length of 132 (as expected).  In case (b), the JSON response was included to fulfill the length of 132.  In case (d), the JSON response was not included so I guess client is waiting for the JSON response that never comes and then times out.  Weird thing is, once I started debug printing out the request content on the server-side flask app, I started getting the JSON response for L>3487 and things are working perfectly now.  But anyway, thanks @Lukasa for your help.


No problem. I'm going to close the issue (as it's not a requests bug), but feel free to hop into our IRC channel if you'd like further help debugging. =)