files: # Licensed to the Apache Software Foundation (ASF) under one or more
  # contributor license agreements.  See the NOTICE file distributed with
  # this work for additional information regarding copyright ownership.
  # The ASF licenses this file to You under the Apache License, Version 2.0
  # (the "License"); you may not use this file except in compliance with
  # the License.  You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import copy
  import os
  import time
  import base64
  import hmac
  
  from hashlib import sha256
  from libcloud.utils.py3 import httplib
  from libcloud.utils.py3 import b
  from libcloud.utils.xml import fixxpath
  
  from libcloud.utils.py3 import ET
  from libcloud.common.types import InvalidCredsError
  from libcloud.common.types import LibcloudError, MalformedResponseError
  from libcloud.common.base import ConnectionUserAndKey, RawResponse
  from libcloud.common.base import CertificateConnection
  from libcloud.common.base import XmlResponse
  from libcloud.common.base import BaseDriver
  
  # The time format for headers in Azure requests
  AZURE_TIME_FORMAT = '%a, %d %b %Y %H:%M:%S GMT'
  
  
  class AzureRedirectException(Exception):
  
      def __init__(self, response):
          self.location = response.headers['location']
  
  
  class AzureResponse(XmlResponse):
  
      valid_response_codes = [
          httplib.NOT_FOUND,
          httplib.CONFLICT,
          httplib.BAD_REQUEST,
          # added TEMPORARY_REDIRECT as this can sometimes be
          # sent by azure instead of a success or fail response
          httplib.TEMPORARY_REDIRECT,
          # Used by Azure Blobs range downloads
          httplib.PARTIAL_CONTENT
      ]
  
      def success(self):
          i = int(self.status)
          return 200 <= i <= 299 or i in self.valid_response_codes
  
      def parse_error(self, msg=None):
          error_msg = 'Unknown error'
  
          try:
              # Azure does give some meaningful errors, but is inconsistent
              # Some APIs respond with an XML error. Others just dump HTML
              body = self.parse_body()
  
              # pylint: disable=no-member
              if type(body) == ET.Element:
                  code = body.findtext(fixxpath(xpath='Code'))
                  message = body.findtext(fixxpath(xpath='Message'))
                  message = message.split('\n')[0]
                  error_msg = '%s: %s' % (code, message)
  
          except MalformedResponseError:
              pass
  
          if msg:
              error_msg = '%s - %s' % (msg, error_msg)
  
          if self.status in [httplib.UNAUTHORIZED, httplib.FORBIDDEN]:
              raise InvalidCredsError(error_msg)
  
          raise LibcloudError(
              '%s Status code: %d.' % (error_msg, self.status),
              driver=self
          )
  
      def parse_body(self):
          is_redirect = int(self.status) == httplib.TEMPORARY_REDIRECT
  
          if is_redirect and self.connection.driver.follow_redirects:
              raise AzureRedirectException(self)
          else:
              return super(AzureResponse, self).parse_body()
  
  
  class AzureRawResponse(RawResponse):
      pass
  
  
  class AzureConnection(ConnectionUserAndKey):
      """
      Represents a single connection to Azure
      """
  
      responseCls = AzureResponse
      rawResponseCls = AzureRawResponse
  
      API_VERSION = '2012-02-12'
  
      def add_default_params(self, params):
          return params
  
      def pre_connect_hook(self, params, headers):
          headers = copy.deepcopy(headers)
  
          # We have to add a date header in GMT
          headers['x-ms-date'] = time.strftime(AZURE_TIME_FORMAT, time.gmtime())
          headers['x-ms-version'] = self.API_VERSION
  
          # Add the authorization header
          headers['Authorization'] = self._get_azure_auth_signature(
              method=self.method,
              headers=headers,
              params=params,
              account=self.user_id,
              secret_key=self.key,
              path=self.action
          )
  
          # Azure cribs about this in
  
  [... the rest is omitted ...]
files: libcloud/common/azure.py
files: # Licensed to the Apache Software Foundation (ASF) under one or more
  # contributor license agreements.  See the NOTICE file distributed with
  # this work for additional information regarding copyright ownership.
  # The ASF licenses this file to You under the Apache License, Version 2.0
  # (the "License"); you may not use this file except in compliance with
  # the License.  You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import copy
  import os
  import time
  import base64
  import hmac
  
  from hashlib import sha256
  from libcloud.utils.py3 import httplib
  from libcloud.utils.py3 import b
  from libcloud.utils.xml import fixxpath
  
  from libcloud.utils.py3 import ET
  from libcloud.common.types import InvalidCredsError
  from libcloud.common.types import LibcloudError, MalformedResponseError
  from libcloud.common.base import ConnectionUserAndKey, RawResponse
  from libcloud.common.base import CertificateConnection
  from libcloud.common.base import XmlResponse
  from libcloud.common.base import BaseDriver
  
  # The time format for headers in Azure requests
  AZURE_TIME_FORMAT = '%a, %d %b %Y %H:%M:%S GMT'
  
  
  class AzureRedirectException(Exception):
  
      def __init__(self, response):
          self.location = response.headers['location']
  
  
  class AzureResponse(XmlResponse):
  
      valid_response_codes = [
          httplib.NOT_FOUND,
          httplib.CONFLICT,
          httplib.BAD_REQUEST,
          httplib.TEMPORARY_REDIRECT
          # added TEMPORARY_REDIRECT as this can sometimes be
          # sent by azure instead of a success or fail response
      ]
  
      def success(self):
          i = int(self.status)
          return 200 <= i <= 299 or i in self.valid_response_codes
  
      def parse_error(self, msg=None):
          error_msg = 'Unknown error'
  
          try:
              # Azure does give some meaningful errors, but is inconsistent
              # Some APIs respond with an XML error. Others just dump HTML
              body = self.parse_body()
  
              # pylint: disable=no-member
              if type(body) == ET.Element:
                  code = body.findtext(fixxpath(xpath='Code'))
                  message = body.findtext(fixxpath(xpath='Message'))
                  message = message.split('\n')[0]
                  error_msg = '%s: %s' % (code, message)
  
          except MalformedResponseError:
              pass
  
          if msg:
              error_msg = '%s - %s' % (msg, error_msg)
  
          if self.status in [httplib.UNAUTHORIZED, httplib.FORBIDDEN]:
              raise InvalidCredsError(error_msg)
  
          raise LibcloudError(
              '%s Status code: %d.' % (error_msg, self.status),
              driver=self
          )
  
      def parse_body(self):
          is_redirect = int(self.status) == httplib.TEMPORARY_REDIRECT
  
          if is_redirect and self.connection.driver.follow_redirects:
              raise AzureRedirectException(self)
          else:
              return super(AzureResponse, self).parse_body()
  
  
  class AzureRawResponse(RawResponse):
      pass
  
  
  class AzureConnection(ConnectionUserAndKey):
      """
      Represents a single connection to Azure
      """
  
      responseCls = AzureResponse
      rawResponseCls = AzureRawResponse
  
      API_VERSION = '2012-02-12'
  
      def add_default_params(self, params):
          return params
  
      def pre_connect_hook(self, params, headers):
          headers = copy.deepcopy(headers)
  
          # We have to add a date header in GMT
          headers['x-ms-date'] = time.strftime(AZURE_TIME_FORMAT, time.gmtime())
          headers['x-ms-version'] = self.API_VERSION
  
          # Add the authorization header
          headers['Authorization'] = self._get_azure_auth_signature(
              method=self.method,
              headers=headers,
              params=params,
              account=self.user_id,
              secret_key=self.key,
              path=self.action
          )
  
          # Azure cribs about this in 'raw' connections
          headers.pop('Host', None)
  
          return params, headers
  
     
  
  [... the rest is omitted ...]
files: libcloud/common/azure.py
files: # Licensed to the Apache Software Foundation (ASF) under one or more
  # contributor license agreements.  See the NOTICE file distributed with
  # this work for additional information regarding copyright ownership.
  # The ASF licenses this file to You under the Apache License, Version 2.0
  # (the "License"); you may not use this file except in compliance with
  # the License.  You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  """
  Provides base classes for working with storage
  """
  
  # Backward compatibility for Python 2.5
  from __future__ import with_statement
  
  from typing import Dict
  from typing import Iterator
  from typing import List
  from typing import Optional
  from typing import Type
  
  import os.path                          # pylint: disable-msg=W0404
  import hashlib
  import warnings
  import errno
  from os.path import join as pjoin
  
  from libcloud.utils.py3 import httplib
  from libcloud.utils.py3 import b
  
  import libcloud.utils.files
  from libcloud.common.types import LibcloudError
  from libcloud.common.base import Connection
  from libcloud.common.base import ConnectionUserAndKey, BaseDriver
  from libcloud.storage.types import ObjectDoesNotExistError
  
  __all__ = [
      'Object',
      'Container',
      'StorageDriver',
  
      'CHUNK_SIZE',
      'DEFAULT_CONTENT_TYPE'
  ]
  
  CHUNK_SIZE = 8096
  
  # 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'
  
  
  class Object(object):
      """
      Represents an object (BLOB).
      """
  
      def __init__(self,
                   name,  # type: str
                   size,  # type: int
                   hash,  # type: str
                   extra,  # type: dict
                   meta_data,  # type: dict
                   container,  # type: Container
                   driver,  # type: StorageDriver
                   ):
          """
          :param name: Object name (must be unique per container).
          :type  name: ``str``
  
          :param size: Object size in bytes.
          :type  size: ``int``
  
          :param hash: Object hash.
          :type  hash: ``str``
  
          :param container: Object container.
          :type  container: :class:`libcloud.storage.base.Container`
  
          :param extra: Extra attributes.
          :type  extra: ``dict``
  
          :param meta_data: Optional object meta data.
          :type  meta_data: ``dict``
  
          :param driver: StorageDriver instance.
          :type  driver: :class:`libcloud.storage.base.StorageDriver`
          """
  
          self.name = name
          self.size = size
          self.hash = hash
          self.container = container
          self.extra = extra or {}
          self.meta_data = meta_data or {}
          self.driver = driver
  
      def get_cdn_url(self):
          # type: () -> str
          return self.driver.get_object_cdn_url(obj=self)
  
      def enable_cdn(self):
          # type: () -> bool
          return self.driver.enable_object_cdn(obj=self)
  
      def download(self, destination_path, overwrite_existing=False,
                   delete_on_failure=True):
          # type: (str, bool, bool) -> bool
          return self.driver.download_object(
              obj=self,
              destination_path=destination_path,
              overwrite_existing=overwrite_existing,
              delete_on_failure=delete_on_failure)
  
      def as_stream(self, chunk_size=None):
          # type: (Optional[int]) -> Iterator[bytes]
          return self.driver.download_object_as_stream(obj=self,
                                                       chunk_size=chunk_size)
  
      def download_range(self, destination_path, start_bytes, end_bytes=None,
                         overwrite_existing=False,
                         delete_on_failure=True):
          # type: (str, int, Optional[int], bool, bool) -> bool
          return self.driver.download_object_range(
              obj=self,
              destination_path=destination_path,
              start_bytes=start_bytes,
              end_bytes=end_bytes,
              overwrite_existing=overwrite_existing,
              delete_on_failure=delete
  
  [... the rest is omitted ...]
files: libcloud/storage/base.py
files: # Licensed to the Apache Software Foundation (ASF) under one or more
  # contributor license agreements.  See the NOTICE file distributed with
  # this work for additional information regarding copyright ownership.
  # The ASF licenses this file to You under the Apache License, Version 2.0
  # (the "License"); you may not use this file except in compliance with
  # the License.  You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  """
  Provides base classes for working with storage
  """
  
  # Backward compatibility for Python 2.5
  from __future__ import with_statement
  
  from typing import Dict
  from typing import Iterator
  from typing import List
  from typing import Optional
  from typing import Type
  
  import os.path                          # pylint: disable-msg=W0404
  import hashlib
  import warnings
  import errno
  from os.path import join as pjoin
  
  from libcloud.utils.py3 import httplib
  from libcloud.utils.py3 import b
  
  import libcloud.utils.files
  from libcloud.common.types import LibcloudError
  from libcloud.common.base import Connection
  from libcloud.common.base import ConnectionUserAndKey, BaseDriver
  from libcloud.storage.types import ObjectDoesNotExistError
  
  __all__ = [
      'Object',
      'Container',
      'StorageDriver',
  
      'CHUNK_SIZE',
      'DEFAULT_CONTENT_TYPE'
  ]
  
  CHUNK_SIZE = 8096
  
  # 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'
  
  
  class Object(object):
      """
      Represents an object (BLOB).
      """
  
      def __init__(self,
                   name,  # type: str
                   size,  # type: int
                   hash,  # type: str
                   extra,  # type: dict
                   meta_data,  # type: dict
                   container,  # type: Container
                   driver,  # type: StorageDriver
                   ):
          """
          :param name: Object name (must be unique per container).
          :type  name: ``str``
  
          :param size: Object size in bytes.
          :type  size: ``int``
  
          :param hash: Object hash.
          :type  hash: ``str``
  
          :param container: Object container.
          :type  container: :class:`libcloud.storage.base.Container`
  
          :param extra: Extra attributes.
          :type  extra: ``dict``
  
          :param meta_data: Optional object meta data.
          :type  meta_data: ``dict``
  
          :param driver: StorageDriver instance.
          :type  driver: :class:`libcloud.storage.base.StorageDriver`
          """
  
          self.name = name
          self.size = size
          self.hash = hash
          self.container = container
          self.extra = extra or {}
          self.meta_data = meta_data or {}
          self.driver = driver
  
      def get_cdn_url(self):
          # type: () -> str
          return self.driver.get_object_cdn_url(obj=self)
  
      def enable_cdn(self):
          # type: () -> bool
          return self.driver.enable_object_cdn(obj=self)
  
      def download(self, destination_path, overwrite_existing=False,
                   delete_on_failure=True):
          # type: (str, bool, bool) -> bool
          return self.driver.download_object(
              obj=self,
              destination_path=destination_path,
              overwrite_existing=overwrite_existing,
              delete_on_failure=delete_on_failure)
  
      def as_stream(self, chunk_size=None):
          # type: (Optional[int]) -> Iterator[bytes]
          return self.driver.download_object_as_stream(obj=self,
                                                       chunk_size=chunk_size)
  
      def download_range(self, destination_path, start_bytes, end_bytes=None,
                         overwrite_existing=False,
                         delete_on_failure=True):
          # type: (str, int, Optional[int], bool, bool) -> bool
          return self.driver.download_object_range(
              obj=self,
              destination_path=destination_path,
              start_bytes=start_bytes,
              end_bytes=end_bytes,
              overwrite_existing=overwrite_existing,
              delete_on_failure=delete
  
  [... the rest is omitted ...]
files: libcloud/storage/base.py
files: # Licensed to the Apache Software Foundation (ASF) under one or more
  # contributor license agreements.  See the NOTICE file distributed with
  # this work for additional information regarding copyright ownership.
  # The ASF licenses this file to You under the Apache License, Version 2.0
  # (the "License"); you may not use this file except in compliance with
  # the License.  You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  from __future__ import with_statement
  
  import base64
  import hashlib
  import hmac
  import os
  import binascii
  from datetime import datetime, timedelta
  
  from libcloud.utils.py3 import ET
  from libcloud.utils.py3 import httplib
  from libcloud.utils.py3 import urlencode
  from libcloud.utils.py3 import urlquote
  from libcloud.utils.py3 import tostring
  from libcloud.utils.py3 import b
  
  from libcloud.utils.xml import fixxpath
  from libcloud.utils.files import read_in_chunks
  from libcloud.common.types import LibcloudError
  from libcloud.common.azure import AzureConnection
  
  from libcloud.storage.base import Object, Container, StorageDriver
  from libcloud.storage.types import ContainerIsNotEmptyError
  from libcloud.storage.types import ContainerAlreadyExistsError
  from libcloud.storage.types import InvalidContainerNameError
  from libcloud.storage.types import ContainerDoesNotExistError
  from libcloud.storage.types import ObjectDoesNotExistError
  from libcloud.storage.types import ObjectHashMismatchError
  
  # Desired number of items in each response inside a paginated request
  RESPONSES_PER_REQUEST = 100
  
  # According to the Azure Docs:
  # > The block must be less than or equal to 100 MB in size for version
  # > 2016-05-31 and later (4 MB for older versions).
  # However for performance reasons, using a lower upload chunk size
  # usually leads to fewer dropped requests and retries.
  AZURE_UPLOAD_CHUNK_SIZE = int(
      os.getenv('LIBCLOUD_AZURE_UPLOAD_CHUNK_SIZE_MB', '4')
  ) * 1024 * 1024
  
  AZURE_DOWNLOAD_CHUNK_SIZE = int(
      os.getenv('LIBCLOUD_AZURE_DOWNLOAD_CHUNK_SIZE_MB', '4')
  ) * 1024 * 1024
  
  # The time period (in seconds) for which a lease must be obtained.
  # If set as -1, we get an infinite lease, but that is a bad idea. If
  # after getting an infinite lease, there was an issue in releasing the
  # lease, the object will remain 'locked' forever, unless the lease is
  # released using the lease_id (which is not exposed to the user)
  AZURE_LEASE_PERIOD = int(
      os.getenv('LIBCLOUD_AZURE_LEASE_PERIOD_SECONDS', '60')
  )
  
  AZURE_STORAGE_HOST_SUFFIX = 'blob.core.windows.net'
  
  AZURE_STORAGE_CDN_URL_DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
  
  AZURE_STORAGE_CDN_URL_START_MINUTES = float(
      os.getenv('LIBCLOUD_AZURE_STORAGE_CDN_URL_START_MINUTES', '5')
  )
  
  AZURE_STORAGE_CDN_URL_EXPIRY_HOURS = float(
      os.getenv('LIBCLOUD_AZURE_STORAGE_CDN_URL_EXPIRY_HOURS', '24')
  )
  
  
  class AzureBlobLease(object):
      """
      A class to help in leasing an azure blob and renewing the lease
      """
      def __init__(self, driver, object_path, use_lease):
          """
          :param driver: The Azure storage driver that is being used
          :type driver: :class:`AzureStorageDriver`
  
          :param object_path: The path of the object we need to lease
          :type object_path: ``str``
  
          :param use_lease: Indicates if we must take a lease or not
          :type use_lease: ``bool``
          """
          self.object_path = object_path
          self.driver = driver
          self.use_
  
  [... the rest is omitted ...]
files: libcloud/storage/drivers/azure_blobs.py
files: # Licensed to the Apache Software Foundation (ASF) under one or more
  # contributor license agreements.  See the NOTICE file distributed with
  # this work for additional information regarding copyright ownership.
  # The ASF licenses this file to You under the Apache License, Version 2.0
  # (the "License"); you may not use this file except in compliance with
  # the License.  You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  from __future__ import with_statement
  
  import base64
  import hashlib
  import hmac
  import os
  import binascii
  from datetime import datetime, timedelta
  
  from libcloud.utils.py3 import ET
  from libcloud.utils.py3 import httplib
  from libcloud.utils.py3 import urlencode
  from libcloud.utils.py3 import urlquote
  from libcloud.utils.py3 import tostring
  from libcloud.utils.py3 import b
  
  from libcloud.utils.xml import fixxpath
  from libcloud.utils.files import read_in_chunks
  from libcloud.common.types import LibcloudError
  from libcloud.common.azure import AzureConnection
  
  from libcloud.storage.base import Object, Container, StorageDriver
  from libcloud.storage.types import ContainerIsNotEmptyError
  from libcloud.storage.types import ContainerAlreadyExistsError
  from libcloud.storage.types import InvalidContainerNameError
  from libcloud.storage.types import ContainerDoesNotExistError
  from libcloud.storage.types import ObjectDoesNotExistError
  from libcloud.storage.types import ObjectHashMismatchError
  
  # Desired number of items in each response inside a paginated request
  RESPONSES_PER_REQUEST = 100
  
  # According to the Azure Docs:
  # > The block must be less than or equal to 100 MB in size for version
  # > 2016-05-31 and later (4 MB for older versions).
  # However for performance reasons, using a lower upload chunk size
  # usually leads to fewer dropped requests and retries.
  AZURE_UPLOAD_CHUNK_SIZE = int(
      os.getenv('LIBCLOUD_AZURE_UPLOAD_CHUNK_SIZE_MB', '4')
  ) * 1024 * 1024
  
  AZURE_DOWNLOAD_CHUNK_SIZE = int(
      os.getenv('LIBCLOUD_AZURE_DOWNLOAD_CHUNK_SIZE_MB', '4')
  ) * 1024 * 1024
  
  # The time period (in seconds) for which a lease must be obtained.
  # If set as -1, we get an infinite lease, but that is a bad idea. If
  # after getting an infinite lease, there was an issue in releasing the
  # lease, the object will remain 'locked' forever, unless the lease is
  # released using the lease_id (which is not exposed to the user)
  AZURE_LEASE_PERIOD = int(
      os.getenv('LIBCLOUD_AZURE_LEASE_PERIOD_SECONDS', '60')
  )
  
  AZURE_STORAGE_HOST_SUFFIX = 'blob.core.windows.net'
  
  AZURE_STORAGE_CDN_URL_DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
  
  AZURE_STORAGE_CDN_URL_START_MINUTES = float(
      os.getenv('LIBCLOUD_AZURE_STORAGE_CDN_URL_START_MINUTES', '5')
  )
  
  AZURE_STORAGE_CDN_URL_EXPIRY_HOURS = float(
      os.getenv('LIBCLOUD_AZURE_STORAGE_CDN_URL_EXPIRY_HOURS', '24')
  )
  
  
  class AzureBlobLease(object):
      """
      A class to help in leasing an azure blob and renewing the lease
      """
      def __init__(self, driver, object_path, use_lease):
          """
          :param driver: The Azure storage driver that is being used
          :type driver: :class:`AzureStorageDriver`
  
          :param object_path: The path of the object we need to lease
          :type object_path: ``str``
  
          :param use_lease: Indicates if we must take a lease or not
          :type use_lease: ``bool``
          """
          self.object_path = object_path
          self.driver = driver
          self.use_
  
  [... the rest is omitted ...]
files: libcloud/storage/drivers/azure_blobs.py
files: # Licensed to the Apache Software Foundation (ASF) under one or more
  # contributor license agreements.  See the NOTICE file distributed with
  # this work for additional information regarding copyright ownership.
  # The ASF licenses this file to You under the Apache License, Version 2.0
  # (the "License"); you may not use this file except in compliance with
  # the License.  You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import base64
  import hmac
  import time
  from hashlib import sha1
  
  import libcloud.utils.py3
  
  try:
      if libcloud.utils.py3.DEFAULT_LXML:
          from lxml.etree import Element, SubElement
      else:
          from xml.etree.ElementTree import Element, SubElement
  except ImportError:
      from xml.etree.ElementTree import Element, SubElement
  
  from libcloud.utils.py3 import httplib
  from libcloud.utils.py3 import urlquote
  from libcloud.utils.py3 import b
  from libcloud.utils.py3 import tostring
  
  from libcloud.utils.xml import fixxpath, findtext
  from libcloud.utils.files import read_in_chunks
  from libcloud.common.types import InvalidCredsError, LibcloudError
  from libcloud.common.base import ConnectionUserAndKey, RawResponse
  from libcloud.common.aws import AWSBaseResponse, AWSDriver, \
      AWSTokenConnection, SignedAWSConnection
  
  from libcloud.storage.base import Object, Container, StorageDriver
  from libcloud.storage.types import ContainerError
  from libcloud.storage.types import ContainerIsNotEmptyError
  from libcloud.storage.types import InvalidContainerNameError
  from libcloud.storage.types import ContainerDoesNotExistError
  from libcloud.storage.types import ObjectDoesNotExistError
  from libcloud.storage.types import ObjectHashMismatchError
  
  # How long before the token expires
  EXPIRATION_SECONDS = 15 * 60
  
  S3_US_STANDARD_HOST = 's3.amazonaws.com'
  S3_US_EAST2_HOST = 's3-us-east-2.amazonaws.com'
  S3_US_WEST_HOST = 's3-us-west-1.amazonaws.com'
  S3_US_WEST_OREGON_HOST = 's3-us-west-2.amazonaws.com'
  S3_US_GOV_WEST_HOST = 's3-us-gov-west-1.amazonaws.com'
  S3_CN_NORTH_HOST = 's3.cn-north-1.amazonaws.com.cn'
  S3_CN_NORTHWEST_HOST = 's3.cn-northwest-1.amazonaws.com.cn'
  S3_EU_WEST_HOST = 's3-eu-west-1.amazonaws.com'
  S3_EU_WEST2_HOST = 's3-eu-west-2.amazonaws.com'
  S3_EU_CENTRAL_HOST = 's3-eu-central-1.amazonaws.com'
  S3_EU_NORTH1_HOST = 's3-eu-north-1.amazonaws.com'
  S3_AP_SOUTH_HOST = 's3-ap-south-1.amazonaws.com'
  S3_AP_SOUTHEAST_HOST = 's3-ap-southeast-1.amazonaws.com'
  S3_AP_SOUTHEAST2_HOST = 's3-ap-southeast-2.amazonaws.com'
  S3_AP_NORTHEAST1_HOST = 's3-ap-northeast-1.amazonaws.com'
  S3_AP_NORTHEAST2_HOST = 's3-ap-northeast-2.amazonaws.com'
  S3_AP_NORTHEAST_HOST = S3_AP_NORTHEAST1_HOST
  S3_SA_EAST_HOST = 's3-sa-east-1.amazonaws.com'
  S3_SA_SOUTHEAST2_HOST = 's3-sa-east-2.amazonaws.com'
  S3_CA_CENTRAL_HOST = 's3-ca-central-1.amazonaws.com'
  
  # Maps AWS region name to connection hostname
  REGION_TO_HOST_MAP = {
      'us-east-1': S3_US_STANDARD_HOST,
      'us-east-2': S3_US_EAST2_HOST,
      'us-west-1': S3_US_WEST_HOST,
      'us-west-2': S3_US_WEST_OREGON
  
  [... the rest is omitted ...]
files: libcloud/storage/drivers/s3.py
files: # Licensed to the Apache Software Foundation (ASF) under one or more
  # contributor license agreements.  See the NOTICE file distributed with
  # this work for additional information regarding copyright ownership.
  # The ASF licenses this file to You under the Apache License, Version 2.0
  # (the "License"); you may not use this file except in compliance with
  # the License.  You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  from typing import Optional
  
  import base64
  import hmac
  import time
  from hashlib import sha1
  
  import libcloud.utils.py3
  
  try:
      if libcloud.utils.py3.DEFAULT_LXML:
          from lxml.etree import Element, SubElement
      else:
          from xml.etree.ElementTree import Element, SubElement
  except ImportError:
      from xml.etree.ElementTree import Element, SubElement
  
  from libcloud.utils.py3 import httplib
  from libcloud.utils.py3 import urlquote
  from libcloud.utils.py3 import b
  from libcloud.utils.py3 import tostring
  
  from libcloud.utils.xml import fixxpath, findtext
  from libcloud.utils.files import read_in_chunks
  from libcloud.common.types import InvalidCredsError, LibcloudError
  from libcloud.common.base import ConnectionUserAndKey, RawResponse
  from libcloud.common.aws import AWSBaseResponse, AWSDriver, \
      AWSTokenConnection, SignedAWSConnection
  
  from libcloud.storage.base import Object, Container, StorageDriver
  from libcloud.storage.types import ContainerError
  from libcloud.storage.types import ContainerIsNotEmptyError
  from libcloud.storage.types import InvalidContainerNameError
  from libcloud.storage.types import ContainerDoesNotExistError
  from libcloud.storage.types import ObjectDoesNotExistError
  from libcloud.storage.types import ObjectHashMismatchError
  
  # How long before the token expires
  EXPIRATION_SECONDS = 15 * 60
  
  S3_US_STANDARD_HOST = 's3.amazonaws.com'
  S3_US_EAST2_HOST = 's3-us-east-2.amazonaws.com'
  S3_US_WEST_HOST = 's3-us-west-1.amazonaws.com'
  S3_US_WEST_OREGON_HOST = 's3-us-west-2.amazonaws.com'
  S3_US_GOV_WEST_HOST = 's3-us-gov-west-1.amazonaws.com'
  S3_CN_NORTH_HOST = 's3.cn-north-1.amazonaws.com.cn'
  S3_CN_NORTHWEST_HOST = 's3.cn-northwest-1.amazonaws.com.cn'
  S3_EU_WEST_HOST = 's3-eu-west-1.amazonaws.com'
  S3_EU_WEST2_HOST = 's3-eu-west-2.amazonaws.com'
  S3_EU_CENTRAL_HOST = 's3-eu-central-1.amazonaws.com'
  S3_EU_NORTH1_HOST = 's3-eu-north-1.amazonaws.com'
  S3_AP_SOUTH_HOST = 's3-ap-south-1.amazonaws.com'
  S3_AP_SOUTHEAST_HOST = 's3-ap-southeast-1.amazonaws.com'
  S3_AP_SOUTHEAST2_HOST = 's3-ap-southeast-2.amazonaws.com'
  S3_AP_NORTHEAST1_HOST = 's3-ap-northeast-1.amazonaws.com'
  S3_AP_NORTHEAST2_HOST = 's3-ap-northeast-2.amazonaws.com'
  S3_AP_NORTHEAST_HOST = S3_AP_NORTHEAST1_HOST
  S3_SA_EAST_HOST = 's3-sa-east-1.amazonaws.com'
  S3_SA_SOUTHEAST2_HOST = 's3-sa-east-2.amazonaws.com'
  S3_CA_CENTRAL_HOST = 's3-ca-central-1.amazonaws.com'
  
  # Maps AWS region name to connection hostname
  REGION_TO_HOST_MAP = {
      'us-east-1': S3_US_STANDARD_HOST,
      'us-east-2': S3_US_EAST2_HOST,
      'us-west-1': S3_US_WEST_HOST,
      'us-west-2': S3_US_W
  
  [... the rest is omitted ...]
files: libcloud/storage/drivers/s3.py