X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/624c5c8d13d6c2e21a80379928387944bedae2a3..11253affeb95b9e15528fce5117ff0ffc83c238d:/sdk/python/arvados/keep.py diff --git a/sdk/python/arvados/keep.py b/sdk/python/arvados/keep.py index 5caa5721dd..aca10dea0c 100644 --- a/sdk/python/arvados/keep.py +++ b/sdk/python/arvados/keep.py @@ -340,7 +340,8 @@ class KeepClient(object): 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) @@ -419,12 +420,20 @@ class KeepClient(object): 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)