def __urllib_open_local_file(self, mode): # if client uses this instance more than # once, make sure we close previously opened # files. if const_isfileobj(self.__localfile): try: if hasattr(self.__localfile, 'flush'): self.__localfile.flush() self.__localfile.close() except (IOError, OSError,): pass self.__localfile = open(self.__path_to_save, mode) if mode.startswith("a"): self.__resumed = True else: self.__resumed = False
def __urllib_close(self, errored): self._update_speed() try: if const_isfileobj(self.__localfile): if hasattr(self.__localfile, 'flush'): self.__localfile.flush() self.__localfile.close() except IOError: pass if (not self.__existed_before) and errored: try: os.remove(self.__path_to_save) except OSError: pass if self.__remotefile is not None: try: self.__remotefile.close() except socket.error: pass
def _generic_post_handler(self, function_name, params, file_params, timeout): """ Given a function name and the request data (dict format), do the actual HTTP request and return the response object to caller. WARNING: params and file_params dict keys must be ASCII string only. @param function_name: name of the function that called this method @type function_name: string @param params: POST parameters @type params: dict @param file_params: mapping composed by file names as key and tuple composed by (file_name, file object) as values @type file_params: dict @param timeout: socket timeout @type timeout: float @return: tuple composed by the server response string or None (in case of empty response) and the HTTPResponse object (useful for checking response status) @rtype: tuple """ if timeout is None: timeout = self._default_timeout_secs multipart_boundary = "---entropy.services,boundary---" request_path = self._request_path.rstrip("/") + "/" + function_name const_debug_write( __name__, "WebService _generic_post_handler, calling: %s at %s -- %s," " tx_callback: %s, timeout: %s" % ( self._request_host, request_path, params, self._transfer_callback, timeout, )) connection = None try: if self._request_protocol == "http": connection = httplib.HTTPConnection(self._request_host, timeout=timeout) elif self._request_protocol == "https": ssl_context = None if hasattr(ssl, 'create_default_context'): ssl_context = ssl.create_default_context( purpose=ssl.Purpose.CLIENT_AUTH) connection = httplib.HTTPSConnection(self._request_host, timeout=timeout, context=ssl_context) else: raise WebService.RequestError("invalid request protocol", method=function_name) headers = { "Accept": "text/plain", "User-Agent": self._generate_user_agent(function_name), } if file_params is None: file_params = {} # autodetect file parameters in params for k in list(params.keys()): if isinstance(params[k], (tuple, list)) \ and (len(params[k]) == 2): f_name, f_obj = params[k] if const_isfileobj(f_obj): file_params[k] = params[k] del params[k] elif const_isunicode(params[k]): # convert to raw string params[k] = const_convert_to_rawstring( params[k], from_enctype="utf-8") elif not const_isstring(params[k]): # invalid ? if params[k] is None: # will be converted to "" continue int_types = const_get_int() supported_types = (float, list, tuple) + int_types if not isinstance(params[k], supported_types): raise WebService.UnsupportedParameters( "%s is unsupported type %s" % (k, type(params[k]))) list_types = (list, tuple) if isinstance(params[k], list_types): # not supporting nested lists non_str = [x for x in params[k] if not \ const_isstring(x)] if non_str: raise WebService.UnsupportedParameters( "%s is unsupported type %s" % (k, type(params[k]))) body = None if not file_params: headers["Content-Type"] = "application/x-www-form-urlencoded" encoded_params = urllib_parse.urlencode(params) data_size = len(encoded_params) if self._transfer_callback is not None: self._transfer_callback(0, data_size, False) if data_size < 65536: try: connection.request("POST", request_path, encoded_params, headers) except socket.error as err: raise WebService.RequestError(err, method=function_name) else: try: connection.request("POST", request_path, None, headers) except socket.error as err: raise WebService.RequestError(err, method=function_name) sio = StringIO(encoded_params) data_size = len(encoded_params) while True: chunk = sio.read(65535) if not chunk: break try: connection.send(chunk) except socket.error as err: raise WebService.RequestError(err, method=function_name) if self._transfer_callback is not None: self._transfer_callback(sio.tell(), data_size, False) # for both ways, send a signal through the callback if self._transfer_callback is not None: self._transfer_callback(data_size, data_size, False) else: headers["Content-Type"] = "multipart/form-data; boundary=" + \ multipart_boundary body_file, body_fpath = self._encode_multipart_form( params, file_params, multipart_boundary) try: data_size = body_file.tell() headers["Content-Length"] = str(data_size) body_file.seek(0) if self._transfer_callback is not None: self._transfer_callback(0, data_size, False) try: connection.request("POST", request_path, None, headers) except socket.error as err: raise WebService.RequestError(err, method=function_name) while True: chunk = body_file.read(65535) if not chunk: break try: connection.send(chunk) except socket.error as err: raise WebService.RequestError(err, method=function_name) if self._transfer_callback is not None: self._transfer_callback(body_file.tell(), data_size, False) if self._transfer_callback is not None: self._transfer_callback(data_size, data_size, False) finally: body_file.close() os.remove(body_fpath) try: response = connection.getresponse() except socket.error as err: raise WebService.RequestError(err, method=function_name) const_debug_write( __name__, "WebService.%s(%s), " "response header: %s" % ( function_name, params, response.getheaders(), )) total_length = response.getheader("Content-Length", "-1") try: total_length = int(total_length) except ValueError: total_length = -1 outcome = const_convert_to_rawstring("") current_len = 0 if self._transfer_callback is not None: self._transfer_callback(current_len, total_length, True) while True: try: chunk = response.read(65536) except socket.error as err: raise WebService.RequestError(err, method=function_name) if not chunk: break outcome += chunk current_len += len(chunk) if self._transfer_callback is not None: self._transfer_callback(current_len, total_length, True) if self._transfer_callback is not None: self._transfer_callback(total_length, total_length, True) if const_is_python3(): outcome = const_convert_to_unicode(outcome) if not outcome: return None, response return outcome, response except httplib.HTTPException as err: raise WebService.RequestError(err, method=function_name) finally: if connection is not None: connection.close()