You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2013/12/09 15:25:02 UTC

[1/6] git commit: LIBCLOUD-433: Make storage backend send content-type of "application/octet-stream" if none is supplied and none can be guessed.

Updated Branches:
  refs/heads/trunk 9e4397034 -> 90df4f66c


LIBCLOUD-433: Make storage backend send content-type of
"application/octet-stream" if none is supplied and none can be guessed.

Also update affected tests.

Signed-off-by: Tomaz Muraus <to...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/c5b23838
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/c5b23838
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/c5b23838

Branch: refs/heads/trunk
Commit: c5b2383847eded88f1f570c6dca4450848a82508
Parents: 9e43970
Author: Michael Farrell <mi...@gmail.com>
Authored: Wed Nov 6 12:01:20 2013 +1030
Committer: Tomaz Muraus <to...@apache.org>
Committed: Mon Dec 9 14:22:27 2013 +0100

----------------------------------------------------------------------
 libcloud/storage/base.py                 |  6 +++---
 libcloud/test/storage/test_atmos.py      | 19 ++++++++-----------
 libcloud/test/storage/test_cloudfiles.py | 18 +++++++-----------
 3 files changed, 18 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/c5b23838/libcloud/storage/base.py
----------------------------------------------------------------------
diff --git a/libcloud/storage/base.py b/libcloud/storage/base.py
index 3408d24..88979a4 100644
--- a/libcloud/storage/base.py
+++ b/libcloud/storage/base.py
@@ -598,9 +598,9 @@ class StorageDriver(BaseDriver):
             content_type, _ = libcloud.utils.files.guess_file_mime_type(name)
 
             if not content_type:
-                raise AttributeError(
-                    'File content-type could not be guessed and' +
-                    ' no content_type value provided')
+                # Fallback to a content-type that will cause most browsers to
+                # download it again as a binary file.
+                content_type = 'application/octet-stream'
 
         file_size = None
 

http://git-wip-us.apache.org/repos/asf/libcloud/blob/c5b23838/libcloud/test/storage/test_atmos.py
----------------------------------------------------------------------
diff --git a/libcloud/test/storage/test_atmos.py b/libcloud/test/storage/test_atmos.py
index d19a5f8..561ac2f 100644
--- a/libcloud/test/storage/test_atmos.py
+++ b/libcloud/test/storage/test_atmos.py
@@ -316,17 +316,14 @@ class AtmosTests(unittest.TestCase):
         file_path = os.path.abspath(__file__)
         container = Container(name='fbc', extra={}, driver=self)
         object_name = 'ftu'
-        try:
-            self.driver.upload_object(file_path=file_path, container=container,
-                                      object_name=object_name)
-        except AttributeError:
-            pass
-        else:
-            self.fail(
-                'File content type not provided'
-                ' but an exception was not thrown')
-        finally:
-            libcloud.utils.files.guess_file_mime_type = old_func
+        obj = self.driver.upload_object(file_path=file_path,
+                                        container=container,
+                                        object_name=object_name)
+
+        # Just check that the file was uploaded OK, as the fallback
+        # Content-Type header should be set (application/octet-stream).
+        self.assertEqual(obj.name, object_name)
+        libcloud.utils.files.guess_file_mime_type = old_func
 
     def test_upload_object_error(self):
         def dummy_content_type(name):

http://git-wip-us.apache.org/repos/asf/libcloud/blob/c5b23838/libcloud/test/storage/test_cloudfiles.py
----------------------------------------------------------------------
diff --git a/libcloud/test/storage/test_cloudfiles.py b/libcloud/test/storage/test_cloudfiles.py
index 29143cc..c71b71e 100644
--- a/libcloud/test/storage/test_cloudfiles.py
+++ b/libcloud/test/storage/test_cloudfiles.py
@@ -439,17 +439,13 @@ class CloudFilesTests(unittest.TestCase):
         file_path = os.path.abspath(__file__)
         container = Container(name='foo_bar_container', extra={}, driver=self)
         object_name = 'foo_test_upload'
-        try:
-            self.driver.upload_object(file_path=file_path, container=container,
-                                      object_name=object_name)
-        except AttributeError:
-            pass
-        else:
-            self.fail(
-                'File content type not provided'
-                ' but an exception was not thrown')
-        finally:
-            libcloud.utils.files.guess_file_mime_type = old_func
+
+        obj = self.driver.upload_object(file_path=file_path, verify_hash=False,
+                                        container=container,
+                                        object_name=object_name)
+
+        self.assertEqual(obj.name, object_name)
+        libcloud.utils.files.guess_file_mime_type = old_func
 
     def test_upload_object_error(self):
         def dummy_content_type(name):


[2/6] git commit: Make 'DEFAULT_CONTENT_TYPE' a constant and add a test case for it.

Posted by to...@apache.org.
Make 'DEFAULT_CONTENT_TYPE' a constant and add a test case for it.


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/888b3d59
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/888b3d59
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/888b3d59

Branch: refs/heads/trunk
Commit: 888b3d598ee0d67cea6ec899d1aa1ec330dd36c4
Parents: c5b2383
Author: Tomaz Muraus <to...@apache.org>
Authored: Mon Dec 9 14:42:12 2013 +0100
Committer: Tomaz Muraus <to...@apache.org>
Committed: Mon Dec 9 14:42:12 2013 +0100

----------------------------------------------------------------------
 libcloud/storage/base.py           | 15 +++++++++++----
 libcloud/test/storage/test_base.py | 19 +++++++++++++++++++
 2 files changed, 30 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/888b3d59/libcloud/storage/base.py
----------------------------------------------------------------------
diff --git a/libcloud/storage/base.py b/libcloud/storage/base.py
index 88979a4..5b441a6 100644
--- a/libcloud/storage/base.py
+++ b/libcloud/storage/base.py
@@ -33,14 +33,21 @@ from libcloud.common.types import LibcloudError
 from libcloud.common.base import ConnectionUserAndKey, BaseDriver
 from libcloud.storage.types import ObjectDoesNotExistError
 
-CHUNK_SIZE = 8096
-
 __all__ = [
     'Object',
     'Container',
-    'StorageDriver'
+    'StorageDriver',
+
+    'CHUNK_SIZE',
+    'DEFAULT_CONTENT_TYPE'
 ]
 
+CHUNK_SIZE = 8096
+
+# Default Content-Type which is sent when upload an object if one is not
+# supplied and can't be detected
+DEFAULT_CONTENT_TYPE = 'application/octet-stream'
+
 
 class Object(object):
     """
@@ -600,7 +607,7 @@ class StorageDriver(BaseDriver):
             if not content_type:
                 # Fallback to a content-type that will cause most browsers to
                 # download it again as a binary file.
-                content_type = 'application/octet-stream'
+                content_type = DEFAULT_CONTENT_TYPE
 
         file_size = None
 

http://git-wip-us.apache.org/repos/asf/libcloud/blob/888b3d59/libcloud/test/storage/test_base.py
----------------------------------------------------------------------
diff --git a/libcloud/test/storage/test_base.py b/libcloud/test/storage/test_base.py
index 05dfea7..9e4bd2d 100644
--- a/libcloud/test/storage/test_base.py
+++ b/libcloud/test/storage/test_base.py
@@ -27,6 +27,7 @@ if PY3:
     from io import FileIO as file
 
 from libcloud.storage.base import StorageDriver
+from libcloud.storage.base import DEFAULT_CONTENT_TYPE
 
 from libcloud.test import StorageMockHttp  # pylint: disable-msg=E0611
 
@@ -151,5 +152,23 @@ class BaseStorageTests(unittest.TestCase):
         else:
             self.fail('Invalid hash type but exception was not thrown')
 
+    def test_upload_default_content_type_is_specified_when_not_supplied(self):
+        iterator = StringIO()
+
+        upload_func = Mock()
+        upload_func.return_value = True, '', 0
+
+        self.driver1.connection = Mock()
+
+        self.driver1._upload_object(object_name='test',
+                                    content_type=None,
+                                    upload_func=upload_func,
+                                    upload_func_kwargs={},
+                                    request_path='/',
+                                    iterator=iterator)
+
+        headers = self.driver1.connection.request.call_args[-1]['headers']
+        self.assertEqual(headers['Content-Type'], DEFAULT_CONTENT_TYPE)
+
 if __name__ == '__main__':
     sys.exit(unittest.main())


[4/6] git commit: Add "strict_mode" to the storage driver.

Posted by to...@apache.org.
Add "strict_mode" to the storage driver.

When this mode is enabled (disabled by default), it will default to an old
behavior when no content type is provided and none can't be automatically
detected.


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/ec90fcb8
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/ec90fcb8
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/ec90fcb8

Branch: refs/heads/trunk
Commit: ec90fcb8a32f5e4a0330ffa6d7b932b65bc82077
Parents: 1f249f5
Author: Tomaz Muraus <to...@apache.org>
Authored: Mon Dec 9 15:05:56 2013 +0100
Committer: Tomaz Muraus <to...@apache.org>
Committed: Mon Dec 9 15:05:56 2013 +0100

----------------------------------------------------------------------
 libcloud/storage/base.py           | 18 +++++++++++++-----
 libcloud/test/storage/test_base.py | 21 ++++++++++++++++++++-
 2 files changed, 33 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/ec90fcb8/libcloud/storage/base.py
----------------------------------------------------------------------
diff --git a/libcloud/storage/base.py b/libcloud/storage/base.py
index 5b441a6..cbfff9c 100644
--- a/libcloud/storage/base.py
+++ b/libcloud/storage/base.py
@@ -44,8 +44,8 @@ __all__ = [
 
 CHUNK_SIZE = 8096
 
-# Default Content-Type which is sent when upload an object if one is not
-# supplied and can't be detected
+# Default Content-Type which is sent when uploading an object if one is not
+# supplied and can't be detected when using non-strict mode.
 DEFAULT_CONTENT_TYPE = 'application/octet-stream'
 
 
@@ -186,6 +186,10 @@ class StorageDriver(BaseDriver):
     hash_type = 'md5'
     supports_chunked_encoding = False
 
+    # When strict mode is used, exception will be thrown if no content type is
+    # provided and none can be detected when uploading an object
+    strict_mode = False
+
     def __init__(self, key, secret=None, secure=True, host=None, port=None,
                  **kwargs):
         super(StorageDriver, self).__init__(key=key, secret=secret,
@@ -605,9 +609,13 @@ class StorageDriver(BaseDriver):
             content_type, _ = libcloud.utils.files.guess_file_mime_type(name)
 
             if not content_type:
-                # Fallback to a content-type that will cause most browsers to
-                # download it again as a binary file.
-                content_type = DEFAULT_CONTENT_TYPE
+                if self.strict_mode:
+                    raise AttributeError('File content-type could not be '
+                                         'guessed and no content_type value '
+                                         'is provided')
+                else:
+                    # Fallback to a content-type
+                    content_type = DEFAULT_CONTENT_TYPE
 
         file_size = None
 

http://git-wip-us.apache.org/repos/asf/libcloud/blob/ec90fcb8/libcloud/test/storage/test_base.py
----------------------------------------------------------------------
diff --git a/libcloud/test/storage/test_base.py b/libcloud/test/storage/test_base.py
index 9e4bd2d..28ad528 100644
--- a/libcloud/test/storage/test_base.py
+++ b/libcloud/test/storage/test_base.py
@@ -43,6 +43,9 @@ class BaseStorageTests(unittest.TestCase):
         self.driver2 = StorageDriver('username', 'key', host='localhost')
         self.driver2.supports_chunked_encoding = False
 
+        self.driver1.strict_mode = False
+        self.driver1.strict_mode = False
+
     def test__upload_object_iterator_must_have_next_method(self):
         class Iterator(object):
 
@@ -152,12 +155,13 @@ class BaseStorageTests(unittest.TestCase):
         else:
             self.fail('Invalid hash type but exception was not thrown')
 
-    def test_upload_default_content_type_is_specified_when_not_supplied(self):
+    def test_upload_no_content_type_supplied_or_detected(self):
         iterator = StringIO()
 
         upload_func = Mock()
         upload_func.return_value = True, '', 0
 
+        # strict_mode is disabled, default content type should be used
         self.driver1.connection = Mock()
 
         self.driver1._upload_object(object_name='test',
@@ -170,5 +174,20 @@ class BaseStorageTests(unittest.TestCase):
         headers = self.driver1.connection.request.call_args[-1]['headers']
         self.assertEqual(headers['Content-Type'], DEFAULT_CONTENT_TYPE)
 
+        # strict_mode is enabled, exception should be thrown
+
+        self.driver1.strict_mode = True
+        expected_msg = ('File content-type could not be guessed and no'
+                        ' content_type value is provided')
+        self.assertRaisesRegexp(AttributeError, expected_msg,
+                                self.driver1._upload_object,
+                                object_name='test',
+                                content_type=None,
+                                upload_func=upload_func,
+                                upload_func_kwargs={},
+                                request_path='/',
+                                iterator=iterator)
+
+
 if __name__ == '__main__':
     sys.exit(unittest.main())


[5/6] git commit: docs: Update upgrade notes.

Posted by to...@apache.org.
docs: Update upgrade notes.


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/0e8c2f06
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/0e8c2f06
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/0e8c2f06

Branch: refs/heads/trunk
Commit: 0e8c2f06e2b6c1ca245f86000471563d4aaeaa79
Parents: ec90fcb
Author: Tomaz Muraus <to...@apache.org>
Authored: Mon Dec 9 15:13:36 2013 +0100
Committer: Tomaz Muraus <to...@apache.org>
Committed: Mon Dec 9 15:13:36 2013 +0100

----------------------------------------------------------------------
 docs/upgrade_notes.rst | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/0e8c2f06/docs/upgrade_notes.rst
----------------------------------------------------------------------
diff --git a/docs/upgrade_notes.rst b/docs/upgrade_notes.rst
index 8b0065d..41aa17e 100644
--- a/docs/upgrade_notes.rst
+++ b/docs/upgrade_notes.rst
@@ -15,6 +15,33 @@ single class plus ``region`` argument model.
 More information on how this affects existing drivers and your code can be
 found bellow.
 
+Default Content-Type is now provided if none is supplied and none can be guessed
+--------------------------------------------------------------------------------
+
+In older versions, Libcloud would throw an exception when a content type is not
+supplied and none can't be automatically detected when uploading an object.
+
+This has changed with the 0.14.0 release. Now if no content type is specified
+and none can't be detected, a default content type of
+``application/octet-stream`` is used.
+
+If you want to preserve the old behavior, you can set ``strict_mode`` attribute
+on the driver object to ``True``.
+
+.. sourcecode:: python
+
+    from libcloud.storage.types import Provider
+    from libcloud.stoage.providers import get_driver
+
+    cls = get_driver(Provider.CLOUDFILES)
+    driver = cls('username', 'api key')
+
+    driver.strict_mode = True
+
+If you are not using strict mode and you are uploading a binary object, we
+still encourage you to practice Python's "explicit is better than implicit"
+mantra and explicitly specify Content-Type of ``application/octet-stream``.
+
 libcloud.security.VERIFY_SSL_CERT_STRICT variable has been removed
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 


[3/6] git commit: Update CHANGES.

Posted by to...@apache.org.
Update CHANGES.


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/1f249f54
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/1f249f54
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/1f249f54

Branch: refs/heads/trunk
Commit: 1f249f54d4f1dc68361eebcc771118de0cb6d153
Parents: 888b3d5
Author: Tomaz Muraus <to...@apache.org>
Authored: Mon Dec 9 14:49:00 2013 +0100
Committer: Tomaz Muraus <to...@apache.org>
Committed: Mon Dec 9 14:49:00 2013 +0100

----------------------------------------------------------------------
 CHANGES | 5 +++++
 1 file changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/1f249f54/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 75990f3..ff3905c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -76,6 +76,11 @@ Changes with Apache Libcloud in development
       Rackspace drivers to use auth 2.0 by default.
       [John Obelenus]
 
+    - Update storage drivers to default to "application/octet-stream"
+      Content-Type if none is provided and none can be guessed.
+      (LIBCLOUD-433)
+      [Michael Farrell]
+
   *) DNS
 
     - Implement iterate_* methods in the Route53 driver and makes it work


[6/6] git commit: Use unittest2.

Posted by to...@apache.org.
Use unittest2.


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/90df4f66
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/90df4f66
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/90df4f66

Branch: refs/heads/trunk
Commit: 90df4f66ca2b06edfcab611a1cf260b282a50eda
Parents: 0e8c2f0
Author: Tomaz Muraus <to...@apache.org>
Authored: Mon Dec 9 15:20:11 2013 +0100
Committer: Tomaz Muraus <to...@apache.org>
Committed: Mon Dec 9 15:20:11 2013 +0100

----------------------------------------------------------------------
 libcloud/test/storage/test_base.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/90df4f66/libcloud/test/storage/test_base.py
----------------------------------------------------------------------
diff --git a/libcloud/test/storage/test_base.py b/libcloud/test/storage/test_base.py
index 28ad528..5c234b8 100644
--- a/libcloud/test/storage/test_base.py
+++ b/libcloud/test/storage/test_base.py
@@ -14,7 +14,6 @@
 # limitations under the License.
 
 import sys
-import unittest
 import hashlib
 
 from mock import Mock
@@ -29,7 +28,8 @@ if PY3:
 from libcloud.storage.base import StorageDriver
 from libcloud.storage.base import DEFAULT_CONTENT_TYPE
 
-from libcloud.test import StorageMockHttp  # pylint: disable-msg=E0611
+from libcloud.test import unittest
+from libcloud.test import StorageMockHttp
 
 
 class BaseStorageTests(unittest.TestCase):