'Control function that does the real job of uploading data to a blob'

def _put_object(self, container, object_name, object_size, file_path=None, extra=None, verify_hash=True, blob_type=None, use_lease=False, stream=None):

    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)
    with AzureBlobLease(self, object_path, use_lease) as lease:
        lease.update_headers(headers)
        result_dict = self._upload_object(object_name, content_type, object_path, headers=headers, file_path=file_path, stream=stream)
        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['content-md5']
    if server_hash:
        server_hash = binascii.hexlify(base64.b64decode(b(server_hash)))
        server_hash = server_hash.decode('utf-8')
    else:
        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)
