コード例 #1
0
ファイル: s3.py プロジェクト: joemiller/libcloud
    def _put_object(self, container, object_name, upload_func,
                    upload_func_kwargs, extra=None, file_path=None,
                    iterator=None, file_hash=None, storage_class=None):
        headers = {}
        extra = extra or {}
        storage_class = storage_class or 'standard'
        if storage_class not in ['standard', 'reduced_redundancy']:
            raise ValueError('Invalid storage class value: %s' % (storage_class))

        headers['x-amz-storage-class'] = storage_class.upper()

        container_name_cleaned = container.name
        object_name_cleaned = self._clean_name(object_name)
        content_type = extra.get('content_type', None)
        meta_data = extra.get('meta_data', None)

        if not iterator and file_hash:
            # TODO: This driver also needs to access to the headers in the
            # add_default_params method so the correct signature can be
            # calculated when a MD5 hash is provided.
            # Uncomment this line when we decide what is the best way to handle
            # this.
            #headers['Content-MD5'] = file_hash
            pass

        if meta_data:
            for key, value in meta_data.iteritems():
                key = 'x-amz-meta--%s' % (key)
                headers[key] = value

        request_path = '/%s/%s' % (container_name_cleaned, object_name_cleaned)
        # TODO: Let the underlying exceptions bubble up and capture the SIGPIPE
        # here.
        # SIGPIPE is thrown if the provided container does not exist or the user
        # does not have correct permission
        result_dict = self._upload_object(object_name=object_name,
                                          content_type=content_type,
                                          upload_func=upload_func,
                                          upload_func_kwargs=upload_func_kwargs,
                                          request_path=request_path,
                                          request_method='PUT',
                                          headers=headers, file_path=file_path,
                                          iterator=iterator)

        response = result_dict['response']
        bytes_transferred = result_dict['bytes_transferred']
        headers = response.headers
        response = response.response

        if file_hash and file_hash != headers['etag'].replace('"', ''):
            raise ObjectHashMismatchError(
                value='MD5 hash checksum does not match',
                object_name=object_name, driver=self)
        elif response.status == httplib.OK:
            obj = Object(
                name=object_name, size=bytes_transferred, hash=file_hash,
                extra=None, meta_data=meta_data, container=container,
                driver=self)

            return obj
コード例 #2
0
    def _put_object(self, container, object_name, object_size, upload_func,
                    upload_func_kwargs, file_path=None, extra=None,
                    verify_hash=True, blob_type=None, use_lease=False):
        """
        Control function that does the real job of uploading data to a blob
        """
        extra = extra or {}
        meta_data = extra.get('meta_data', {})
        content_type = extra.get('content_type', None)

        headers = self._prepare_upload_headers(object_name, object_size,
                                               extra, meta_data, blob_type)

        object_path = self._get_object_path(container, object_name)

        # Get a lease if required and do the operations
        with AzureBlobLease(self, object_path, use_lease) as lease:
            if 'lease' in upload_func_kwargs:
                upload_func_kwargs['lease'] = lease

            lease.update_headers(headers)

            iterator = iter('')
            result_dict = self._upload_object(object_name, content_type,
                                              upload_func, upload_func_kwargs,
                                              object_path, headers=headers,
                                              file_path=file_path,
                                              iterator=iterator)

            response = result_dict['response']
            bytes_transferred = result_dict['bytes_transferred']
            data_hash = result_dict['data_hash']
            headers = response.headers
            response = response.response

        if response.status != httplib.CREATED:
            raise LibcloudError(
                'Unexpected status code, status_code=%s' % (response.status),
                driver=self)

        server_hash = headers['content-md5']

        if server_hash:
            server_hash = binascii.hexlify(base64.b64decode(b(server_hash)))
            server_hash = server_hash.decode('utf-8')
        else:
            # TODO: HACK - We could poll the object for a while and get
            # the hash
            pass

        if (verify_hash and server_hash and data_hash != server_hash):
            raise ObjectHashMismatchError(
                value='MD5 hash checksum does not match',
                object_name=object_name, driver=self)

        return Object(name=object_name, size=bytes_transferred,
                      hash=headers['etag'], extra=None,
                      meta_data=meta_data, container=container,
                      driver=self)
コード例 #3
0
    def _put_object(self, container, object_name, upload_func,
                    upload_func_kwargs, method='PUT', query_args=None,
                    extra=None, file_path=None, iterator=None,
                    verify_hash=True, storage_class=None):
        headers = {}
        extra = extra or {}
        storage_class = storage_class or 'standard'
        if storage_class not in ['standard', 'reduced_redundancy']:
            raise ValueError(
                'Invalid storage class value: %s' % (storage_class))

        headers['x-amz-storage-class'] = storage_class.upper()

        content_type = extra.get('content_type', None)
        meta_data = extra.get('meta_data', None)

        if meta_data:
            for key, value in list(meta_data.items()):
                key = 'x-amz-meta-%s' % (key)
                headers[key] = value

        request_path = self._get_object_path(container, object_name)

        if query_args:
            request_path = '?'.join((request_path, query_args))

        # TODO: Let the underlying exceptions bubble up and capture the SIGPIPE
        # here.
        #SIGPIPE is thrown if the provided container does not exist or the user
        # does not have correct permission
        result_dict = self._upload_object(
            object_name=object_name, content_type=content_type,
            upload_func=upload_func, upload_func_kwargs=upload_func_kwargs,
            request_path=request_path, request_method=method,
            headers=headers, file_path=file_path, iterator=iterator)

        response = result_dict['response']
        bytes_transferred = result_dict['bytes_transferred']
        headers = response.headers
        response = response.response
        server_hash = headers['etag'].replace('"', '')

        if (verify_hash and result_dict['data_hash'] != server_hash):
            raise ObjectHashMismatchError(
                value='MD5 hash checksum does not match',
                object_name=object_name, driver=self)
        elif response.status == httplib.OK:
            obj = Object(
                name=object_name, size=bytes_transferred, hash=server_hash,
                extra=None, meta_data=meta_data, container=container,
                driver=self)

            return obj
        else:
            raise LibcloudError(
                'Unexpected status code, status_code=%s' % (response.status),
                driver=self)
コード例 #4
0
ファイル: cloudfiles.py プロジェクト: joemiller/libcloud
    def _put_object(self,
                    container,
                    object_name,
                    upload_func,
                    upload_func_kwargs,
                    extra=None,
                    file_path=None,
                    iterator=None,
                    file_hash=None):
        extra = extra or {}
        container_name_cleaned = self._clean_container_name(container.name)
        object_name_cleaned = self._clean_object_name(object_name)
        content_type = extra.get('content_type', None)
        meta_data = extra.get('meta_data', None)

        headers = {}
        if not iterator and file_hash:
            headers['ETag'] = file_hash

        if meta_data:
            for key, value in meta_data.iteritems():
                key = 'X-Object-Meta-%s' % (key)
                headers[key] = value

        request_path = '/%s/%s' % (container_name_cleaned, object_name_cleaned)
        result_dict = self._upload_object(
            object_name=object_name,
            content_type=content_type,
            upload_func=upload_func,
            upload_func_kwargs=upload_func_kwargs,
            request_path=request_path,
            request_method='PUT',
            headers=headers,
            file_path=file_path,
            iterator=iterator)

        response = result_dict['response'].response
        bytes_transferred = result_dict['bytes_transferred']

        if response.status == httplib.EXPECTATION_FAILED:
            raise LibcloudError(value='Missing content-type header',
                                driver=self)
        elif response.status == httplib.UNPROCESSABLE_ENTITY:
            raise ObjectHashMismatchError(
                value='MD5 hash checksum does not match',
                object_name=object_name,
                driver=self)
        elif response.status == httplib.CREATED:
            obj = Object(name=object_name,
                         size=bytes_transferred,
                         hash=file_hash,
                         extra=None,
                         meta_data=meta_data,
                         container=container,
                         driver=self)

            return obj
コード例 #5
0
ファイル: s3.py プロジェクト: orpolaczek/libcloud
    def _put_object(self, container, object_name, method='PUT',
                    query_args=None, extra=None, file_path=None,
                    stream=None, verify_hash=True, storage_class=None):
        headers = {}
        extra = extra or {}

        headers.update(self._to_storage_class_headers(storage_class))

        content_type = extra.get('content_type', None)
        meta_data = extra.get('meta_data', None)
        acl = extra.get('acl', None)

        if meta_data:
            for key, value in list(meta_data.items()):
                key = self.http_vendor_prefix + '-meta-%s' % (key)
                headers[key] = value

        if acl:
            headers[self.http_vendor_prefix + '-acl'] = acl

        request_path = self._get_object_path(container, object_name)

        if query_args:
            request_path = '?'.join((request_path, query_args))

        # TODO: Let the underlying exceptions bubble up and capture the SIGPIPE
        # here.
        # SIGPIPE is thrown if the provided container does not exist or the
        # user does not have correct permission
        result_dict = self._upload_object(
            object_name=object_name, content_type=content_type,
            request_path=request_path, request_method=method,
            headers=headers, file_path=file_path, stream=stream)

        response = result_dict['response']
        bytes_transferred = result_dict['bytes_transferred']
        headers = response.headers
        response = response
        server_hash = headers.get('etag', '').replace('"', '')

        if (verify_hash and result_dict['data_hash'] != server_hash):
            raise ObjectHashMismatchError(
                value='MD5 hash {0} checksum does not match {1}'.format(
                    server_hash, result_dict['data_hash']),
                object_name=object_name, driver=self)
        elif response.status == httplib.OK:
            obj = Object(
                name=object_name, size=bytes_transferred, hash=server_hash,
                extra={'acl': acl}, meta_data=meta_data, container=container,
                driver=self)

            return obj
        else:
            raise LibcloudError(
                'Unexpected status code, status_code=%s' % (response.status),
                driver=self)
コード例 #6
0
ファイル: oss.py プロジェクト: Eis-D-Z/libcloud
    def _put_object(self, container, object_name, method='PUT',
                    query_args=None, extra=None, file_path=None,
                    stream=None, verify_hash=False):
        """
        Create an object and upload data using the given function.
        """
        headers = {}
        extra = extra or {}

        content_type = extra.get('content_type', None)
        meta_data = extra.get('meta_data', None)
        acl = extra.get('acl', None)

        if meta_data:
            for key, value in list(meta_data.items()):
                key = self.http_vendor_prefix + 'meta-%s' % (key)
                headers[key] = value

        if acl:
            if acl not in ['public-read', 'private', 'public-read-write']:
                raise AttributeError('invalid acl value: %s' % acl)
            headers[self.http_vendor_prefix + 'object-acl'] = acl

        request_path = self._get_object_path(container, object_name)

        if query_args:
            request_path = '?'.join((request_path, query_args))

        result_dict = self._upload_object(
            object_name=object_name, content_type=content_type,
            request_path=request_path, request_method=method,
            headers=headers, file_path=file_path, stream=stream)

        response = result_dict['response']
        bytes_transferred = result_dict['bytes_transferred']
        headers = response.headers

        server_hash = headers['etag'].replace('"', '')

        if (verify_hash and result_dict['data_hash'] != server_hash):
            raise ObjectHashMismatchError(
                value='MD5 hash {0} checksum does not match {1}'.format(
                    server_hash, result_dict['data_hash']),
                object_name=object_name, driver=self)
        elif response.status == httplib.OK:
            obj = Object(
                name=object_name, size=bytes_transferred, hash=server_hash,
                extra={'acl': acl}, meta_data=meta_data, container=container,
                driver=self)

            return obj
        else:
            raise LibcloudError(
                'Unexpected status code, status_code=%s' % (response.status),
                driver=self)
コード例 #7
0
ファイル: cloudfiles.py プロジェクト: wandera/libcloud
    def _upload_object_manifest(self,
                                container,
                                object_name,
                                extra=None,
                                verify_hash=True):
        extra = extra or {}
        meta_data = extra.get("meta_data")

        container_name_encoded = self._encode_container_name(container.name)
        object_name_encoded = self._encode_object_name(object_name)
        request_path = "/%s/%s" % (container_name_encoded, object_name_encoded)

        # pylint: disable=no-member
        headers = {
            "X-Auth-Token":
            self.connection.auth_token,
            "X-Object-Manifest":
            "%s/%s/" % (container_name_encoded, object_name_encoded),
        }

        data = ""
        response = self.connection.request(request_path,
                                           method="PUT",
                                           data=data,
                                           headers=headers,
                                           raw=True)

        object_hash = None

        if verify_hash:
            hash_function = self._get_hash_function()
            hash_function.update(b(data))
            data_hash = hash_function.hexdigest()
            object_hash = response.headers.get("etag")

            if object_hash != data_hash:
                raise ObjectHashMismatchError(
                    value=("MD5 hash checksum does not match (expected=%s, " +
                           "actual=%s)") % (data_hash, object_hash),
                    object_name=object_name,
                    driver=self,
                )

        obj = Object(
            name=object_name,
            size=0,
            hash=object_hash,
            extra=None,
            meta_data=meta_data,
            container=container,
            driver=self,
        )

        return obj
コード例 #8
0
ファイル: cloudfiles.py プロジェクト: dahlia/libcloud
    def _put_object(self, container, object_name, upload_func,
                    upload_func_kwargs, extra=None, file_path=None,
                    iterator=None, verify_hash=True):
        extra = extra or {}
        container_name_encoded = self._encode_container_name(container.name)
        object_name_encoded = self._encode_object_name(object_name)
        content_type = extra.get('content_type', None)
        meta_data = extra.get('meta_data', None)
        content_disposition = extra.get('content_disposition', None)

        headers = {}
        if meta_data:
            for key, value in list(meta_data.items()):
                key = 'X-Object-Meta-%s' % (key)
                headers[key] = value

        if content_disposition is not None:
            headers['Content-Disposition'] = content_disposition

        request_path = '/%s/%s' % (container_name_encoded, object_name_encoded)
        result_dict = self._upload_object(
            object_name=object_name, content_type=content_type,
            upload_func=upload_func, upload_func_kwargs=upload_func_kwargs,
            request_path=request_path, request_method='PUT',
            headers=headers, file_path=file_path, iterator=iterator)

        response = result_dict['response'].response
        bytes_transferred = result_dict['bytes_transferred']
        server_hash = result_dict['response'].headers.get('etag', None)

        if response.status == httplib.EXPECTATION_FAILED:
            raise LibcloudError(value='Missing content-type header',
                                driver=self)
        elif verify_hash and not server_hash:
            raise LibcloudError(value='Server didn\'t return etag',
                                driver=self)
        elif (verify_hash and result_dict['data_hash'] != server_hash):
            raise ObjectHashMismatchError(
                value=('MD5 hash checksum does not match (expected=%s, ' +
                       'actual=%s)') % (result_dict['data_hash'], server_hash),
                object_name=object_name, driver=self)
        elif response.status == httplib.CREATED:
            obj = Object(
                name=object_name, size=bytes_transferred, hash=server_hash,
                extra=None, meta_data=meta_data, container=container,
                driver=self)

            return obj
        else:
            # @TODO: Add test case for this condition (probably 411)
            raise LibcloudError('status_code=%s' % (response.status),
                                driver=self)
コード例 #9
0
    def _upload_object_manifest(self,
                                container,
                                object_name,
                                extra=None,
                                verify_hash=True):
        extra = extra or {}
        meta_data = extra.get('meta_data')

        container_name_encoded = self._encode_container_name(container.name)
        object_name_encoded = self._encode_object_name(object_name)
        request_path = '/%s/%s' % (container_name_encoded, object_name_encoded)

        # pylint: disable=no-member
        headers = {
            'X-Auth-Token':
            self.connection.auth_token,
            'X-Object-Manifest':
            '%s/%s/' % (container_name_encoded, object_name_encoded)
        }

        data = ''
        response = self.connection.request(request_path,
                                           method='PUT',
                                           data=data,
                                           headers=headers,
                                           raw=True)

        object_hash = None

        if verify_hash:
            hash_function = self._get_hash_function()
            hash_function.update(b(data))
            data_hash = hash_function.hexdigest()
            object_hash = response.headers.get('etag')

            if object_hash != data_hash:
                raise ObjectHashMismatchError(
                    value=('MD5 hash checksum does not match (expected=%s, ' +
                           'actual=%s)') % (data_hash, object_hash),
                    object_name=object_name,
                    driver=self)

        obj = Object(name=object_name,
                     size=0,
                     hash=object_hash,
                     extra=None,
                     meta_data=meta_data,
                     container=container,
                     driver=self)

        return obj
コード例 #10
0
    def _put_object(self,
                    container,
                    object_name,
                    method='PUT',
                    query_args=None,
                    extra=None,
                    file_path=None,
                    stream=None,
                    verify_hash=True,
                    storage_class=None,
                    headers=None):
        headers = headers or {}
        extra = extra or {}

        headers.update(self._to_storage_class_headers(storage_class))

        content_type = extra.get('content_type', None)
        meta_data = extra.get('meta_data', None)
        acl = extra.get('acl', None)

        if meta_data:
            for key, value in list(meta_data.items()):
                key = self.http_vendor_prefix + '-meta-%s' % (key)
                headers[key] = value

        if acl:
            headers[self.http_vendor_prefix + '-acl'] = acl

        request_path = self._get_object_path(container, object_name)

        if query_args:
            request_path = '?'.join((request_path, query_args))

        result_dict = self._upload_object(object_name=object_name,
                                          content_type=content_type,
                                          request_path=request_path,
                                          request_method=method,
                                          headers=headers,
                                          file_path=file_path,
                                          stream=stream)

        response = result_dict['response']
        bytes_transferred = result_dict['bytes_transferred']
        headers = response.headers
        response = response
        server_hash = headers.get('etag', '').replace('"', '')
        server_side_encryption = headers.get('x-amz-server-side-encryption',
                                             None)
        aws_kms_encryption = (server_side_encryption == 'aws:kms')
        hash_matches = (result_dict['data_hash'] == server_hash)

        # NOTE: If AWS KMS server side encryption is enabled, ETag won't
        # contain object MD5 digest so we skip the checksum check
        # See https://docs.aws.amazon.com/AmazonS3/latest/API
        # /RESTCommonResponseHeaders.html
        # and https://github.com/apache/libcloud/issues/1401
        # for details
        if verify_hash and not aws_kms_encryption and not hash_matches:
            raise ObjectHashMismatchError(
                value='MD5 hash {0} checksum does not match {1}'.format(
                    server_hash, result_dict['data_hash']),
                object_name=object_name,
                driver=self)
        elif response.status == httplib.OK:
            obj = Object(name=object_name,
                         size=bytes_transferred,
                         hash=server_hash,
                         extra={'acl': acl},
                         meta_data=meta_data,
                         container=container,
                         driver=self)

            return obj
        else:
            raise LibcloudError('Unexpected status code, status_code=%s' %
                                (response.status),
                                driver=self)
コード例 #11
0
    def _put_object(self, container, object_name, stream,
                    extra=None, verify_hash=True, headers=None,
                    blob_size=None, file_path=None,
                    use_lease=False):
        """
        Control function that does the real job of uploading data to a blob
        """
        extra = extra or {}
        content_type = extra.get('content_type', None)
        meta_data = extra.get('meta_data', {})

        object_path = self._get_object_path(container, object_name)

        # Get a lease if required and do the operations
        with AzureBlobLease(self, object_path, use_lease) as lease:
            if blob_size is not None and blob_size <= AZURE_UPLOAD_CHUNK_SIZE:
                result_dict = self._upload_directly(stream=stream,
                                                    object_path=object_path,
                                                    lease=lease,
                                                    blob_size=blob_size,
                                                    meta_data=meta_data,
                                                    headers=headers,
                                                    content_type=content_type,
                                                    object_name=object_name,
                                                    file_path=file_path)
            else:
                result_dict = self._upload_in_chunks(stream=stream,
                                                     object_path=object_path,
                                                     lease=lease,
                                                     meta_data=meta_data,
                                                     headers=headers,
                                                     content_type=content_type,
                                                     object_name=object_name,
                                                     file_path=file_path,
                                                     verify_hash=verify_hash)

            response = result_dict['response']
            bytes_transferred = result_dict['bytes_transferred']
            data_hash = result_dict['data_hash']
            headers = response.headers

        if response.status != httplib.CREATED:
            raise LibcloudError(
                'Unexpected status code, status_code=%s' % (response.status),
                driver=self)

        server_hash = headers.get('content-md5')

        if server_hash:
            server_hash = binascii.hexlify(base64.b64decode(b(server_hash)))
            server_hash = server_hash.decode('utf-8')
        else:
            # TODO: HACK - We could poll the object for a while and get
            # the hash
            pass

        if (verify_hash and server_hash and data_hash != server_hash):
            raise ObjectHashMismatchError(
                value='MD5 hash checksum does not match',
                object_name=object_name, driver=self)

        return Object(name=object_name, size=bytes_transferred,
                      hash=headers['etag'], extra=None,
                      meta_data=meta_data, container=container,
                      driver=self)
コード例 #12
0
    def _put_object(self,
                    container,
                    object_name,
                    upload_func,
                    upload_func_kwargs,
                    extra=None,
                    file_path=None,
                    iterator=None,
                    file_hash=None,
                    storage_class=None):
        headers = {}
        extra = extra or {}
        storage_class = storage_class or 'standard'
        if storage_class not in ['standard', 'reduced_redundancy']:
            raise ValueError('Invalid storage class value: %s' %
                             (storage_class))

        headers['x-amz-storage-class'] = storage_class.upper()

        container_name_cleaned = container.name
        object_name_cleaned = self._clean_object_name(object_name)
        content_type = extra.get('content_type', None)
        meta_data = extra.get('meta_data', None)

        if not iterator and file_hash:
            headers['Content-MD5'] = base64.b64encode(file_hash.decode('hex'))

        if meta_data:
            for key, value in meta_data.iteritems():
                key = 'x-amz-meta-%s' % (key)
                headers[key] = value

        request_path = '/%s/%s' % (container_name_cleaned, object_name_cleaned)
        # TODO: Let the underlying exceptions bubble up and capture the SIGPIPE
        # here.
        # SIGPIPE is thrown if the provided container does not exist or the user
        # does not have correct permission
        result_dict = self._upload_object(
            object_name=object_name,
            content_type=content_type,
            upload_func=upload_func,
            upload_func_kwargs=upload_func_kwargs,
            request_path=request_path,
            request_method='PUT',
            headers=headers,
            file_path=file_path,
            iterator=iterator)

        response = result_dict['response']
        bytes_transferred = result_dict['bytes_transferred']
        headers = response.headers
        response = response.response

        if (file_hash and response.status == httplib.BAD_REQUEST) or \
           (file_hash and file_hash != headers['etag'].replace('"', '')):
            raise ObjectHashMismatchError(
                value='MD5 hash checksum does not match',
                object_name=object_name,
                driver=self)
        elif response.status == httplib.OK:
            obj = Object(name=object_name,
                         size=bytes_transferred,
                         hash=file_hash,
                         extra=None,
                         meta_data=meta_data,
                         container=container,
                         driver=self)

            return obj
コード例 #13
0
ファイル: oss.py プロジェクト: wandera/libcloud
    def _put_object(
        self,
        container,
        object_name,
        method="PUT",
        query_args=None,
        extra=None,
        file_path=None,
        stream=None,
        verify_hash=False,
        headers=None,
    ):
        """
        Create an object and upload data using the given function.
        """
        headers = headers or {}
        extra = extra or {}

        content_type = extra.get("content_type", None)
        meta_data = extra.get("meta_data", None)
        acl = extra.get("acl", None)

        if meta_data:
            for key, value in list(meta_data.items()):
                key = self.http_vendor_prefix + "meta-%s" % (key)
                headers[key] = value

        if acl:
            if acl not in ["public-read", "private", "public-read-write"]:
                raise AttributeError("invalid acl value: %s" % acl)
            headers[self.http_vendor_prefix + "object-acl"] = acl

        request_path = self._get_object_path(container, object_name)

        if query_args:
            request_path = "?".join((request_path, query_args))

        result_dict = self._upload_object(
            object_name=object_name,
            content_type=content_type,
            request_path=request_path,
            request_method=method,
            headers=headers,
            file_path=file_path,
            stream=stream,
        )

        response = result_dict["response"]
        bytes_transferred = result_dict["bytes_transferred"]
        headers = response.headers

        server_hash = headers["etag"].replace('"', "")

        if verify_hash and result_dict["data_hash"] != server_hash:
            raise ObjectHashMismatchError(
                value="MD5 hash {0} checksum does not match {1}".format(
                    server_hash, result_dict["data_hash"]),
                object_name=object_name,
                driver=self,
            )
        elif response.status == httplib.OK:
            obj = Object(
                name=object_name,
                size=bytes_transferred,
                hash=server_hash,
                extra={"acl": acl},
                meta_data=meta_data,
                container=container,
                driver=self,
            )

            return obj
        else:
            raise LibcloudError(
                "Unexpected status code, status_code=%s" % (response.status),
                driver=self,
            )
コード例 #14
0
    def _put_object(self,
                    upload_func,
                    upload_func_args,
                    container,
                    object_name,
                    extra=None,
                    file_path=None,
                    iterator=None,
                    file_hash=None):
        container_name_cleaned = self._clean_container_name(container.name)
        object_name_cleaned = self._clean_object_name(object_name)

        extra = extra or {}
        content_type = extra.get('content_type', None)
        meta_data = extra.get('meta_data', None)

        if not content_type:
            if file_path:
                name = file_path
            else:
                name = object_name
            content_type, _ = utils.guess_file_mime_type(name)

            if not content_type:
                raise AttributeError(
                    'File content-type could not be guessed and' +
                    ' no content_type value provided')

        headers = {}
        if iterator:
            headers['Transfer-Encoding'] = 'chunked'
            upload_func_args['chunked'] = True
        else:
            file_size = os.path.getsize(file_path)
            headers['Content-Length'] = file_size
            upload_func_args['chunked'] = False

            if file_hash:
                headers['ETag'] = file_hash

        headers['Content-Type'] = content_type

        if meta_data:
            for key, value in meta_data.iteritems():
                key = 'X-Object-Meta-%s' % (key)
                headers[key] = value

        response = self.connection.request(
            '/%s/%s' % (container_name_cleaned, object_name_cleaned),
            method='PUT',
            data=None,
            headers=headers,
            raw=True)

        upload_func_args['response'] = response
        success, data_hash, bytes_transferred = upload_func(**upload_func_args)

        if not success:
            raise LibcloudError('Object upload failed, Perhaps a timeout?')

        response = response.response

        if response.status == httplib.EXPECTATION_FAILED:
            raise LibcloudError('Missing content-type header')
        elif response.status == httplib.UNPROCESSABLE_ENTITY:
            raise ObjectHashMismatchError(
                value='MD5 hash checksum does not match',
                object_name=object_name,
                driver=self)
        elif response.status == httplib.CREATED:
            obj = Object(name=object_name,
                         size=bytes_transferred,
                         hash=file_hash,
                         extra=None,
                         meta_data=meta_data,
                         container=container,
                         driver=self)

            return obj
コード例 #15
0
    def _put_object(self,
                    container,
                    object_name,
                    upload_func,
                    upload_func_kwargs,
                    method='PUT',
                    query_args=None,
                    extra=None,
                    file_path=None,
                    iterator=None,
                    verify_hash=False):
        """
        Create an object and upload data using the given function.
        """
        headers = {}
        extra = extra or {}

        content_type = extra.get('content_type', None)
        meta_data = extra.get('meta_data', None)
        acl = extra.get('acl', None)

        if meta_data:
            for key, value in list(meta_data.items()):
                key = self.http_vendor_prefix + 'meta-%s' % (key)
                headers[key] = value

        if acl:
            if acl not in ['public-read', 'private', 'public-read-write']:
                raise AttributeError('invalid acl value: %s' % acl)
            headers[self.http_vendor_prefix + 'object-acl'] = acl

        request_path = self._get_object_path(container, object_name)

        if query_args:
            request_path = '?'.join((request_path, query_args))

        # TODO: Let the underlying exceptions bubble up and capture the SIGPIPE
        # here.
        # SIGPIPE is thrown if the provided container does not exist or the
        # user does not have correct permission
        result_dict = self._upload_object(
            object_name=object_name,
            content_type=content_type,
            upload_func=upload_func,
            upload_func_kwargs=upload_func_kwargs,
            request_path=request_path,
            request_method=method,
            headers=headers,
            file_path=file_path,
            iterator=iterator,
            container=container)

        response = result_dict['response']
        bytes_transferred = result_dict['bytes_transferred']
        headers = response.headers
        response = response.response
        server_hash = headers['etag'].replace('"', '')

        if (verify_hash and result_dict['data_hash'].upper() != server_hash):
            raise ObjectHashMismatchError(
                value='MD5 hash checksum does not match',
                object_name=object_name,
                driver=self)
        elif response.status == httplib.OK:
            obj = Object(name=object_name,
                         size=bytes_transferred,
                         hash=server_hash,
                         extra={'acl': acl},
                         meta_data=meta_data,
                         container=container,
                         driver=self)

            return obj
        else:
            raise LibcloudError('Unexpected status code, status_code=%s' %
                                (response.status),
                                driver=self)
コード例 #16
0
ファイル: cloudfiles.py プロジェクト: wandera/libcloud
    def _put_object(
        self,
        container,
        object_name,
        extra=None,
        file_path=None,
        stream=None,
        verify_hash=True,
        headers=None,
    ):
        extra = extra or {}
        container_name_encoded = self._encode_container_name(container.name)
        object_name_encoded = self._encode_object_name(object_name)
        content_type = extra.get("content_type", None)
        meta_data = extra.get("meta_data", None)
        content_disposition = extra.get("content_disposition", None)

        headers = headers or {}
        if meta_data:
            for key, value in list(meta_data.items()):
                key = "X-Object-Meta-%s" % (key)
                headers[key] = value

        if content_disposition is not None:
            headers["Content-Disposition"] = content_disposition

        request_path = "/%s/%s" % (container_name_encoded, object_name_encoded)
        result_dict = self._upload_object(
            object_name=object_name,
            content_type=content_type,
            request_path=request_path,
            request_method="PUT",
            headers=headers,
            file_path=file_path,
            stream=stream,
        )

        response = result_dict["response"]
        bytes_transferred = result_dict["bytes_transferred"]
        server_hash = result_dict["response"].headers.get("etag", None)

        if response.status == httplib.EXPECTATION_FAILED:
            raise LibcloudError(value="Missing content-type header",
                                driver=self)
        elif verify_hash and not server_hash:
            raise LibcloudError(value="Server didn't return etag", driver=self)
        elif verify_hash and result_dict["data_hash"] != server_hash:
            raise ObjectHashMismatchError(
                value=("MD5 hash checksum does not match (expected=%s, " +
                       "actual=%s)") % (result_dict["data_hash"], server_hash),
                object_name=object_name,
                driver=self,
            )
        elif response.status == httplib.CREATED:
            obj = Object(
                name=object_name,
                size=bytes_transferred,
                hash=server_hash,
                extra=None,
                meta_data=meta_data,
                container=container,
                driver=self,
            )

            return obj
        else:
            # @TODO: Add test case for this condition (probably 411)
            raise LibcloudError("status_code=%s" % (response.status),
                                driver=self)