except:
ua.close()
- def _socket_open(self, family, socktype, protocol, address):
+ @staticmethod
+ def _socket_open(family, socktype, protocol, address=None):
"""Because pycurl doesn't have CURLOPT_TCP_KEEPALIVE"""
s = socket.socket(family, socktype, protocol)
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
curl = self._get_user_agent()
try:
self._headers = {}
+ body_reader = StringIO.StringIO(body)
response_body = StringIO.StringIO()
curl.setopt(pycurl.NOSIGNAL, 1)
curl.setopt(pycurl.OPENSOCKETFUNCTION, self._socket_open)
curl.setopt(pycurl.URL, url.encode('utf-8'))
- curl.setopt(pycurl.POSTFIELDS, body)
- curl.setopt(pycurl.CUSTOMREQUEST, 'PUT')
+ # Using UPLOAD tells cURL to wait for a "go ahead" from the
+ # Keep server (in the form of a HTTP/1.1 "100 Continue"
+ # response) instead of sending the request body immediately.
+ # This allows the server to reject the request if the request
+ # is invalid or the server is read-only, without waiting for
+ # the client to send the entire block.
+ curl.setopt(pycurl.UPLOAD, True)
+ curl.setopt(pycurl.INFILESIZE, len(body))
+ curl.setopt(pycurl.READFUNCTION, body_reader.read)
curl.setopt(pycurl.HTTPHEADER, [
'{}: {}'.format(k,v) for k,v in self.put_headers.iteritems()])
curl.setopt(pycurl.WRITEFUNCTION, response_body.write)