-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
411 response results in exception in Session.send #2490
Comments
So this is probably a stupid question, but does that server actually work? As you discussed with @mjpieters on the question, this doesn't happen with our typical test server. Is there a server we can actually reproduce this with? |
The application server works with Httplib2, cURL command line tool and browsers (Safari/Chrome). |
I can see this happening in a number of cases. What I think we'd want to test is whether we can attempt to read from the socket after it threw an exception on the send. Put another way, if we call |
I understand that it doesn't work with requests. Could you share (even privately, since our emails are publicly accessible) what server it is that you're experiencing problems with so we can attempt to debug this further? |
Sorry, I'm afraid the client won't allow that to happen :(. I can inform you that placing a sleep(1) after asio::write( response ) within the server code allows Requests to do its job accurately. Server
|
So let's be clear, the problem is that the |
With that detail, we can definitely write a socket-level test. Thank you @ben-crowhurst |
@sigmavirus24 FYI, if you're planning to take this, I think the fix will actually go into urllib3 (or maybe even httplib, if it turns out httplib can't handle it). |
Yeah. "socket-level test" was my hint at you that this would be in urllib3 ;) |
So some quick local tests suggest that for EPIPE we're ok. Running this 'server': import socket
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 8080))
s.listen(0)
while True:
c = s.accept()[0]
c.send('HTTP/1.1 411 Length Needed\r\nContent-Length: 0\r\n\r\n')
c.close() We can achieve the following in >>> import httplib
>>> c = httplib.HTTPConnection('localhost', 8080)
>>> c.putrequest('GET', '/'); c.endheaders(); c.send('some data');
>>> c.send('some data')
>>> c.send('some data')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 826, in send
self.sock.sendall(data)
File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 32] Broken pipe
>>> r = c.getresponse()
>>> r.status
411
>>> r.read()
'' So an EPIPE has the potential to give us a response when there is one. If there isn't a response, it seems that instead we get a |
Having looked at the HTTP Adapter I'm suggesting the following alteration?
This would stop making a behavioural change to the API but allow those interested to respond accordingly. |
I don't think HTTP Adapter is low enough down. I think urllib3 needs to know what's going on here. |
@Lukasa you're correct. |
Closing this as it was never a concern for Requests. |
Full details can be found over at StackOverflow
The text was updated successfully, but these errors were encountered: