예제 #1
0
파일: fetchers.py 프로젝트: Heather/entropy
 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
예제 #2
0
 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
예제 #3
0
파일: fetchers.py 프로젝트: Heather/entropy
    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
예제 #4
0
    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
예제 #5
0
    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()