Example #1
0
    def _put_object(self,
                    path,
                    content,
                    chunk=None,
                    content_type=None,
                    content_encoding=None,
                    headers=None):
        # ReadableToIterable supports both file-like objects yielding str or bytes,
        # and will try utf-8 encode the result if it is a string.
        # The following assertion make sure that the content is either some bytes or
        # a file-like stream of bytes, for consistency across all storage implementations.
        assert isinstance(content, bytes) or issubclass(
            type(content), (IOBase, GeneratorFile, ReadableToIterable,
                            filelike.BaseStreamFilelike))

        path = self._normalize_path(path)
        headers = headers or {}

        if content_encoding is not None:
            headers["Content-Encoding"] = content_encoding

        is_filelike = hasattr(content, "read")
        if is_filelike:
            content = ReadableToIterable(content, md5=True)

        try:
            etag = self._get_connection().put_object(
                self._swift_container,
                path,
                content,
                chunk_size=chunk,
                content_type=content_type,
                headers=headers,
            )
        except ClientException:
            # We re-raise client exception here so that validation of config during setup can see
            # the client exception messages.
            raise

        # If we wrapped the content in a ReadableToIterable, compare its MD5 to the etag returned. If
        # they don't match, raise an IOError indicating a write failure.
        if is_filelike:
            if etag != content.get_md5sum():
                logger.error(
                    "Got mismatch in md5 etag for path %s: Expected %s, but server has %s",
                    path,
                    content.get_md5sum(),
                    etag,
                )
                raise IOError("upload verification failed for path {0}:"
                              "md5 mismatch, local {1} != remote {2}".format(
                                  path, content.get_md5sum(), etag))
Example #2
0
    def _put_object(self,
                    path,
                    content,
                    chunk=None,
                    content_type=None,
                    content_encoding=None,
                    headers=None):
        path = self._normalize_path(path)
        headers = headers or {}

        if content_encoding is not None:
            headers["Content-Encoding"] = content_encoding

        is_filelike = hasattr(content, "read")
        if is_filelike:
            content = ReadableToIterable(content, md5=True)

        try:
            etag = self._get_connection().put_object(
                self._swift_container,
                path,
                content,
                chunk_size=chunk,
                content_type=content_type,
                headers=headers,
            )
        except ClientException:
            # We re-raise client exception here so that validation of config during setup can see
            # the client exception messages.
            raise

        # If we wrapped the content in a ReadableToIterable, compare its MD5 to the etag returned. If
        # they don't match, raise an IOError indicating a write failure.
        if is_filelike:
            if etag != content.get_md5sum():
                logger.error(
                    "Got mismatch in md5 etag for path %s: Expected %s, but server has %s",
                    path,
                    content.get_md5sum(),
                    etag,
                )
                raise IOError("upload verification failed for path {0}:"
                              "md5 mismatch, local {1} != remote {2}".format(
                                  path, content.get_md5sum(), etag))