コード例 #1
0
ファイル: __init__.py プロジェクト: bopopescu/Boto-4
 def create_invalidation_request(self, distribution_id, paths,
                                 caller_reference=None):
     """Creates a new invalidation request
         :see: http://goo.gl/8vECq
     """
     # We allow you to pass in either an array or
     # an InvalidationBatch object
     if not isinstance(paths, InvalidationBatch):
         paths = InvalidationBatch(paths)
     paths.connection = self
     uri = '/%s/distribution/%s/invalidation' % (self.Version,
                                                 distribution_id)
     response = self.make_request('POST', uri,
                                  {'Content-Type': 'text/xml'},
                                  data=paths.to_xml())
     body = response.read()
     if response.status == 201:
         h = handler.XmlHandler(paths, self)
         xml.sax.parseString(body, h)
         return paths
     else:
         raise CloudFrontServerError(response.status, response.reason, body)
コード例 #2
0
ファイル: bucket.py プロジェクト: Xsardas1000/Django-server
    def get_lifecycle_config(self, headers=None):
        """
        Returns the current lifecycle configuration on the bucket.

        :rtype: :class:`boto.gs.lifecycle.LifecycleConfig`
        :returns: A LifecycleConfig object that describes all current
            lifecycle rules in effect for the bucket.
        """
        response = self.connection.make_request('GET',
                                                self.name,
                                                query_args=LIFECYCLE_ARG,
                                                headers=headers)
        body = response.read()
        boto.log.debug(body)
        if response.status == 200:
            lifecycle_config = LifecycleConfig()
            h = handler.XmlHandler(lifecycle_config, self)
            xml.sax.parseString(body, h)
            return lifecycle_config
        else:
            raise self.connection.provider.storage_response_error(
                response.status, response.reason, body)
コード例 #3
0
 def get_all_parts(self, max_parts=None, part_number_marker=None):
     """
     Return the uploaded parts of this MultiPart Upload.  This is
     a lower-level method that requires you to manually page through
     results.  To simplify this process, you can just use the
     object itself as an iterator and it will automatically handle
     all of the paging with S3.
     """
     self._parts = []
     query_args = 'uploadId=%s' % self.id
     if max_parts:
         query_args += '&max_parts=%d' % max_parts
     if part_number_marker:
         query_args += '&part-number-marker=%s' % part_number_marker
     response = self.bucket.connection.make_request('GET', self.bucket.name,
                                                    self.key_name,
                                                    query_args=query_args)
     body = response.read()
     if response.status == 200:
         h = handler.XmlHandler(self, self)
         xml.sax.parseString(body, h)
         return self._parts
コード例 #4
0
ファイル: exception.py プロジェクト: zuhaozou1/h-store
    def __init__(self, status, reason, body=None, *args):
        StandardError.__init__(self, status, reason, body, *args)
        self.status = status
        self.reason = reason
        self.body = body or ''
        self.request_id = None
        self.error_code = None
        self.error_message = None
        self.box_usage = None

        # Attempt to parse the error response. If body isn't present,
        # then just ignore the error response.
        if self.body:
            try:
                h = handler.XmlHandler(self, self)
                xml.sax.parseString(self.body, h)
            except xml.sax.SAXParseException, pe:
                # Go ahead and clean up anything that may have
                # managed to get into the error data so we
                # don't get partial garbage.
                print "Warning: failed to parse error message from AWS: %s" % pe
                self._cleanupParsedProperties()
コード例 #5
0
 def test_parse_xml(self):
     x = pretty_print_xml
     xml_in = """<?xml version="1.0" encoding="UTF-8"?>
         <WebsiteConfiguration xmlns='http://s3.amazonaws.com/doc/2006-03-01/'>
           <IndexDocument>
             <Suffix>index.html</Suffix>
           </IndexDocument>
           <ErrorDocument>
             <Key>error.html</Key>
           </ErrorDocument>
           <RoutingRules>
             <RoutingRule>
             <Condition>
               <KeyPrefixEquals>docs/</KeyPrefixEquals>
             </Condition>
             <Redirect>
               <Protocol>https</Protocol>
               <HostName>www.example.com</HostName>
               <ReplaceKeyWith>documents/</ReplaceKeyWith>
               <HttpRedirectCode>302</HttpRedirectCode>
             </Redirect>
             </RoutingRule>
             <RoutingRule>
             <Condition>
               <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
             </Condition>
             <Redirect>
               <HostName>example.com</HostName>
               <ReplaceKeyPrefixWith>report-404/</ReplaceKeyPrefixWith>
             </Redirect>
             </RoutingRule>
           </RoutingRules>
         </WebsiteConfiguration>
     """
     webconfig = WebsiteConfiguration()
     h = handler.XmlHandler(webconfig, None)
     xml.sax.parseString(xml_in, h)
     xml_out = webconfig.to_xml()
     self.assertEqual(x(xml_in), x(xml_out))
コード例 #6
0
    def get_attributes(self,
                       domain_or_name,
                       item_name,
                       attribute_names=None,
                       item=None):
        """
        Retrieve attributes for a given item in a domain.

        @type domain_or_name: string or L{Domain<boto.sdb.domain.Domain>} object.
        @param domain_or_name: Either the name of a domain or a Domain object

        @type item_name: string
        @param item_name: The name of the item whose attributes are being retrieved.

        @type attribute_names: string or list of strings
        @param attribute_names: An attribute name or list of attribute names.  This
                                parameter is optional.  If not supplied, all attributes
                                will be retrieved for the item.

        @rtype: L{Item<boto.sdb.item.Item>}
        @return: An Item mapping type containing the requested attribute name/values
        """
        domain, domain_name = self.get_domain_and_name(domain_or_name)
        params = {'DomainName': domain_name, 'ItemName': item_name}
        if attribute_names:
            if not isinstance(attribute_names, list):
                attribute_names = [attribute_names]
            self.build_list_params(params, attribute_names, 'AttributeName')
        response = self.make_request('GetAttributes', params)
        body = response.read()
        if response.status == 200:
            if item == None:
                item = Item(domain, item_name)
            h = handler.XmlHandler(item, self)
            xml.sax.parseString(body, h)
            return item
        else:
            raise SDBResponseError(response.status, response.reason, body)
コード例 #7
0
  def RunCommand(self):
    cors_arg = self.args[0]
    uri_args = self.args[1:]
    # Disallow multi-provider setcors requests.
    storage_uri = self.UrisAreForSingleProvider(uri_args)
    if not storage_uri:
      raise CommandException('"%s" command spanning providers not allowed.' %
                             self.command_name)

    # Open, read and parse file containing XML document.
    cors_file = open(cors_arg, 'r')
    cors_txt = cors_file.read()
    cors_file.close()
    cors_obj = Cors()

    # Parse XML document and convert into Cors object.
    h = handler.XmlHandler(cors_obj, None)
    try:
      xml.sax.parseString(cors_txt, h)
    except xml.sax._exceptions.SAXParseException, e:
      raise CommandException('Requested CORS is invalid: %s at line %s, '
                             'column %s' % (e.getMessage(), e.getLineNumber(),
                                            e.getColumnNumber()))
コード例 #8
0
    def __init__(self, status, reason, body=None, *args):
        StandardError.__init__(self, status, reason, body, *args)
        self.status = status
        self.reason = reason
        self.body = body or ''
        self.request_id = None
        self.error_code = None
        self.error_message = None
        self.box_usage = None

        # Attempt to parse the error response. If body isn't present,
        # then just ignore the error response.
        if self.body:
            try:
                h = handler.XmlHandler(self, self)
                xml.sax.parseString(self.body, h)
            except xml.sax.SAXParseException, pe:
                # Remove unparsable message body so we don't include garbage
                # in exception. But first, save self.body in self.error_message
                # because occasionally we get error messages from Eucalyptus
                # that are just text strings that we want to preserve.
                self.error_message = self.body
                self.body = None
コード例 #9
0
 def create_distribution(self,
                         origin,
                         enabled,
                         caller_reference='',
                         cnames=None,
                         comment=''):
     config = DistributionConfig(origin=origin,
                                 enabled=enabled,
                                 caller_reference=caller_reference,
                                 cnames=cnames,
                                 comment=comment)
     response = self.make_request('POST',
                                  '/%s/distribution' % self.Version,
                                  {'Content-Type': 'text/xml'},
                                  data=config.to_xml())
     body = response.read()
     if response.status == 201:
         d = Distribution(connection=self)
         h = handler.XmlHandler(d, self)
         xml.sax.parseString(body, h)
         return d
     else:
         raise CloudFrontServerError(response.status, response.reason, body)
コード例 #10
0
    def get_response(self, action, params, page=0, itemSet=None):
        """
        Utility method to handle calls to ECS and parsing of responses.
        """
        params['Service'] = "AWSECommerceService"
        params['Operation'] = action
        if page:
            params['ItemPage'] = page
        response = self.make_request(None, params, "/onca/xml")
        body = response.read()
        boto.log.debug(body)

        if response.status != 200:
            boto.log.error('%s %s' % (response.status, response.reason))
            boto.log.error('%s' % body)
            raise self.ResponseError(response.status, response.reason, body)

        if itemSet == None:
            rs = ItemSet(self, action, params, page)
        else:
            rs = itemSet
        h = handler.XmlHandler(rs, self)
        xml.sax.parseString(body, h)
        return rs
コード例 #11
0
ファイル: connection.py プロジェクト: vikalp/boto
 def get_object(self,
                action,
                params,
                cls,
                path='/',
                parent=None,
                verb='GET'):
     if not parent:
         parent = self
     response = self.make_request(action, params, path, verb)
     body = response.read()
     boto.log.debug(body)
     if not body:
         boto.log.error('Null body %s' % body)
         raise self.ResponseError(response.status, response.reason, body)
     elif response.status == 200:
         obj = cls(parent)
         h = handler.XmlHandler(obj, parent)
         xml.sax.parseString(body, h)
         return obj
     else:
         boto.log.error('%s %s' % (response.status, response.reason))
         boto.log.error('%s' % body)
         raise self.ResponseError(response.status, response.reason, body)
コード例 #12
0
ファイル: lifecycle.py プロジェクト: jkff/gsutil
    def _SetLifecycleConfig(self):
        lifecycle_arg = self.args[0]
        uri_args = self.args[1:]
        # Disallow multi-provider setlifecycle requests.
        storage_uri = self.UrisAreForSingleProvider(uri_args)
        if not storage_uri:
            raise CommandException(
                '"%s" command spanning providers not allowed.' %
                self.command_name)

        # Open, read and parse file containing XML document.
        lifecycle_file = open(lifecycle_arg, 'r')
        lifecycle_txt = lifecycle_file.read()
        lifecycle_file.close()
        lifecycle_config = LifecycleConfig()

        # Parse XML document and convert into LifecycleConfig object.
        h = handler.XmlHandler(lifecycle_config, None)
        try:
            xml.sax.parseString(lifecycle_txt, h)
        except xml.sax._exceptions.SAXParseException, e:
            raise CommandException(
                'Requested lifecycle config is invalid: %s at line %s, column %s'
                % (e.getMessage(), e.getLineNumber(), e.getColumnNumber()))
コード例 #13
0
 def refund(self, callerReference, transactionId, refundAmount=None,
            callerDescription=None):
     """
     Refund a transaction. This refunds the full amount by default
     unless 'refundAmount' is specified.
     """
     params = {}
     params['CallerReference'] = callerReference
     params['TransactionId'] = transactionId
     if(refundAmount != None):
         params['RefundAmount.Value'] = refundAmount
         params['RefundAmount.CurrencyCode'] = "USD"
     if(callerDescription != None):
         params['CallerDescription'] = callerDescription
     
     response = self.make_request("Refund", params)
     body = response.read()
     if(response.status == 200):
         rs = ResultSet([("RefundResponse", FPSResponse)])
         h = handler.XmlHandler(rs, self)
         xml.sax.parseString(body, h)
         return rs
     else:
         raise FPSResponseError(response.status, response.reason, body)
コード例 #14
0
ファイル: connection.py プロジェクト: bopopescu/MyTiramola
    def get_all_rrsets(self,
                       hosted_zone_id,
                       type=None,
                       name=None,
                       identifier=None,
                       maxitems=None):
        """
        Retrieve the Resource Record Sets defined for this Hosted Zone.
        Returns the raw XML data returned by the Route53 call.
        
        :type hosted_zone_id: str
        :param hosted_zone_id: The unique identifier for the Hosted Zone

        :type type: str
        :param type: The type of resource record set to begin the record
            listing from.  Valid choices are:

                * A
                * AAAA
                * CNAME
                * MX
                * NS
                * PTR
                * SOA
                * SPF
                * SRV
                * TXT

            Valid values for weighted resource record sets:

                * A
                * AAAA
                * CNAME
                * TXT

            Valid values for Zone Apex Aliases:

                * A
                * AAAA

        :type name: str
        :param name: The first name in the lexicographic ordering of domain
                     names to be retrieved

        :type identifier: str
        :param identifier: In a hosted zone that includes weighted resource
            record sets (multiple resource record sets with the same DNS
            name and type that are differentiated only by SetIdentifier),
            if results were truncated for a given DNS name and type,
            the value of SetIdentifier for the next resource record
            set that has the current DNS name and type

        :type maxitems: int
        :param maxitems: The maximum number of records

        """
        params = {
            'type': type,
            'name': name,
            'Identifier': identifier,
            'maxitems': maxitems
        }
        uri = '/%s/hostedzone/%s/rrset' % (self.Version, hosted_zone_id)
        response = self.make_request('GET', uri, params=params)
        body = response.read()
        boto.log.debug(body)
        if response.status >= 300:
            raise exception.DNSServerError(response.status, response.reason,
                                           body)
        rs = ResourceRecordSets(connection=self, hosted_zone_id=hosted_zone_id)
        h = handler.XmlHandler(rs, self)
        xml.sax.parseString(body, h)
        return rs
コード例 #15
0
    def copy_key(self, new_key_name, src_bucket_name,
                 src_key_name, metadata=None, src_version_id=None,
                 storage_class='STANDARD', preserve_acl=False):
        """
        Create a new key in the bucket by copying another existing key.

        :type new_key_name: string
        :param new_key_name: The name of the new key

        :type src_bucket_name: string
        :param src_bucket_name: The name of the source bucket

        :type src_key_name: string
        :param src_key_name: The name of the source key

        :type src_version_id: string
        :param src_version_id: The version id for the key.  This param
                               is optional.  If not specified, the newest
                               version of the key will be copied.

        :type metadata: dict
        :param metadata: Metadata to be associated with new key.
                         If metadata is supplied, it will replace the
                         metadata of the source key being copied.
                         If no metadata is supplied, the source key's
                         metadata will be copied to the new key.

        :type storage_class: string
        :param storage_class: The storage class of the new key.
                              By default, the new key will use the
                              standard storage class.  Possible values are:
                              STANDARD | REDUCED_REDUNDANCY

        :type preserve_acl: bool
        :param preserve_acl: If True, the ACL from the source key
                             will be copied to the destination
                             key.  If False, the destination key
                             will have the default ACL.
                             Note that preserving the ACL in the
                             new key object will require two
                             additional API calls to S3, one to
                             retrieve the current ACL and one to
                             set that ACL on the new object.  If
                             you don't care about the ACL, a value
                             of False will be significantly more
                             efficient.

        :rtype: :class:`boto.s3.key.Key` or subclass
        :returns: An instance of the newly created key object
        """
        if preserve_acl:
            acl = self.get_xml_acl(src_key_name)
        src = '%s/%s' % (src_bucket_name, urllib.quote(src_key_name))
        if src_version_id:
            src += '?version_id=%s' % src_version_id
        provider = self.connection.provider
        headers = {provider.copy_source_header : src}
        if storage_class != 'STANDARD':
            headers[provider.storage_class_header] = storage_class
        if metadata:
            headers[provider.metadata_directive_header] = 'REPLACE'
            headers = boto.utils.merge_meta(headers, metadata)
        else:
            headers[provider.metadata_directive_header] = 'COPY'
        response = self.connection.make_request('PUT', self.name, new_key_name,
                                                headers=headers)
        body = response.read()
        if response.status == 200:
            key = self.new_key(new_key_name)
            h = handler.XmlHandler(key, self)
            xml.sax.parseString(body, h)
            if hasattr(key, 'Error'):
                raise provider.storage_copy_error(key.Code, key.Message, body)
            key.handle_version_headers(response)
            if preserve_acl:
                self.set_xml_acl(acl, new_key_name)
            return key
        else:
            raise provider.storage_response_error(response.status, response.reason, body)
コード例 #16
0
    def pay(self,
            transactionAmount,
            senderTokenId,
            recipientTokenId=None,
            callerTokenId=None,
            chargeFeeTo="Recipient",
            callerReference=None,
            senderReference=None,
            recipientReference=None,
            senderDescription=None,
            recipientDescription=None,
            callerDescription=None,
            metadata=None,
            transactionDate=None,
            reserve=False):
        """
        Make a payment transaction. You must specify the amount.
        This can also perform a Reserve request if 'reserve' is set to True.
        """
        params = {}
        params['SenderTokenId'] = senderTokenId
        # this is for 2008-09-17 specification
        params['TransactionAmount.Amount'] = str(transactionAmount)
        params['TransactionAmount.CurrencyCode'] = "USD"
        #params['TransactionAmount'] = str(transactionAmount)
        params['ChargeFeeTo'] = chargeFeeTo

        params['RecipientTokenId'] = (recipientTokenId if recipientTokenId
                                      is not None else boto.config.get(
                                          "FPS", "recipient_token"))
        params['CallerTokenId'] = (callerTokenId if callerTokenId is not None
                                   else boto.config.get("FPS", "caller_token"))
        if (transactionDate != None):
            params['TransactionDate'] = transactionDate
        if (senderReference != None):
            params['SenderReference'] = senderReference
        if (recipientReference != None):
            params['RecipientReference'] = recipientReference
        if (senderDescription != None):
            params['SenderDescription'] = senderDescription
        if (recipientDescription != None):
            params['RecipientDescription'] = recipientDescription
        if (callerDescription != None):
            params['CallerDescription'] = callerDescription
        if (metadata != None):
            params['MetaData'] = metadata
        if (callerReference == None):
            callerReference = uuid.uuid4()
        params['CallerReference'] = callerReference

        if reserve:
            action = "Reserve"
        else:
            action = "Pay"
        response = self.make_request(action, params)
        body = response.read()
        if (response.status == 200):
            rs = ResultSet([("%sResponse" % action, FPSResponse)])
            h = handler.XmlHandler(rs, self)
            xml.sax.parseString(body, h)
            return rs
        else:
            raise FPSResponseError(response.status, response.reason, body)
コード例 #17
0
    def copy_key(self,
                 new_key_name,
                 src_bucket_name,
                 src_key_name,
                 metadata=None,
                 src_version_id=None):
        """
        Create a new key in the bucket by copying another existing key.

        :type new_key_name: string
        :param new_key_name: The name of the new key

        :type src_bucket_name: string
        :param src_bucket_name: The name of the source bucket

        :type src_key_name: string
        :param src_key_name: The name of the source key

        :type src_version_id: string
        :param src_version_id: The version id for the key.  This param
                               is optional.  If not specified, the newest
                               version of the key will be copied.

        :type metadata: dict
        :param metadata: Metadata to be associated with new key.
                         If metadata is supplied, it will replace the
                         metadata of the source key being copied.
                         If no metadata is supplied, the source key's
                         metadata will be copied to the new key.

        :rtype: :class:`boto.s3.key.Key` or subclass
        :returns: An instance of the newly created key object
        """
        src = '%s/%s' % (src_bucket_name, urllib.quote(src_key_name))
        if src_version_id:
            src += '?version_id=%s' % src_version_id
        if metadata:
            headers = {
                'x-amz-copy-source': src,
                'x-amz-metadata-directive': 'REPLACE'
            }
            headers = boto.utils.merge_meta(headers, metadata)
        else:
            headers = {
                'x-amz-copy-source': src,
                'x-amz-metadata-directive': 'COPY'
            }
        response = self.connection.make_request('PUT',
                                                self.name,
                                                new_key_name,
                                                headers=headers)
        body = response.read()
        if response.status == 200:
            key = self.new_key(new_key_name)
            h = handler.XmlHandler(key, self)
            xml.sax.parseString(body, h)
            if hasattr(key, 'Error'):
                raise S3CopyError(key.Code, key.Message, body)
            key.handle_version_headers(response)
            return key
        else:
            raise S3ResponseError(response.status, response.reason, body)
コード例 #18
0
ファイル: object_hooks.py プロジェクト: bopopescu/botornado-1
def get_all_buckets_hook(body):
    rs = ResultSet([('Bucket', self.bucket_class)])
    h = handler.XmlHandler(rs, self)
    xml.sax.parseString(body, h)
    return rs
コード例 #19
0
ファイル: object_hooks.py プロジェクト: bopopescu/botornado-1
def get_all_hook(body):
    boto.log.debug(body)
    rs = ResultSet(element_map)
    h = handler.XmlHandler(rs, self)
    xml.sax.parseString(body, h)
    return rs
コード例 #20
0
 def _parse_xml(self, body, markers):
     rs = ResultSet(markers)
     h = handler.XmlHandler(rs, None)
     xml.sax.parseString(body, h)
     return rs
コード例 #21
0
    def test_1_basic(self):
        """basic regression test for Google Cloud Storage"""
        print '--- running GSConnection tests ---'
        c = GSConnection()
        # create a new, empty bucket
        bucket_name = 'test-%d' % int(time.time())
        bucket = c.create_bucket(bucket_name)
        # now try a get_bucket call and see if it's really there
        bucket = c.get_bucket(bucket_name)
        key_name = 'foobar'
        k = bucket.new_key(key_name)
        s1 = 'This is a test of file upload and download'
        s2 = 'This is a second string to test file upload and download'
        k.set_contents_from_string(s1)
        fp = open(key_name, 'wb')
        # now get the contents from s3 to a local file
        k.get_contents_to_file(fp)
        fp.close()
        fp = open(key_name)
        # check to make sure content read from s3 is identical to original
        assert s1 == fp.read(), 'corrupted file'
        fp.close()
        bucket.delete_key(k)
        # test a few variations on get_all_keys - first load some data
        # for the first one, let's override the content type
        phony_mimetype = 'application/x-boto-test'
        headers = {'Content-Type': phony_mimetype}
        k.name = 'foo/bar'
        k.set_contents_from_string(s1, headers)
        k.name = 'foo/bas'
        k.set_contents_from_filename('foobar')
        k.name = 'foo/bat'
        k.set_contents_from_string(s1)
        k.name = 'fie/bar'
        k.set_contents_from_string(s1)
        k.name = 'fie/bas'
        k.set_contents_from_string(s1)
        k.name = 'fie/bat'
        k.set_contents_from_string(s1)
        # try resetting the contents to another value
        md5 = k.md5
        k.set_contents_from_string(s2)
        assert k.md5 != md5
        # Test for stream API
        fp2 = open('foobar', 'rb')
        k.md5 = None
        k.base64md5 = None
        k.set_contents_from_stream(fp2, headers=headers)
        fp = open('foobar1', 'wb')
        k.get_contents_to_file(fp)
        fp.close()
        fp2.seek(0, 0)
        fp = open('foobar1', 'rb')
        assert (fp2.read() == fp.read()), 'Chunked Transfer corrupted the Data'
        fp.close()
        fp2.close()
        os.unlink('foobar1')
        os.unlink('foobar')
        all = bucket.get_all_keys()
        assert len(all) == 6
        rs = bucket.get_all_keys(prefix='foo')
        assert len(rs) == 3
        rs = bucket.get_all_keys(prefix='', delimiter='/')
        assert len(rs) == 2
        rs = bucket.get_all_keys(maxkeys=5)
        assert len(rs) == 5
        # test the lookup method
        k = bucket.lookup('foo/bar')
        assert isinstance(k, bucket.key_class)
        assert k.content_type == phony_mimetype
        k = bucket.lookup('notthere')
        assert k == None
        # try some metadata stuff
        key_name = 'has_metadata'
        k = bucket.new_key(key_name)
        mdkey1 = 'meta1'
        mdval1 = 'This is the first metadata value'
        k.set_metadata(mdkey1, mdval1)
        mdkey2 = 'meta2'
        mdval2 = 'This is the second metadata value'
        k.set_metadata(mdkey2, mdval2)
        # try a unicode metadata value

        mdval3 = u'föö'
        mdkey3 = 'meta3'
        k.set_metadata(mdkey3, mdval3)
        k.set_contents_from_string(s1)

        k = bucket.lookup(key_name)
        assert k.get_metadata(mdkey1) == mdval1
        assert k.get_metadata(mdkey2) == mdval2
        assert k.get_metadata(mdkey3) == mdval3
        k = bucket.new_key(key_name)
        k.get_contents_as_string()
        assert k.get_metadata(mdkey1) == mdval1
        assert k.get_metadata(mdkey2) == mdval2
        assert k.get_metadata(mdkey3) == mdval3
        bucket.delete_key(k)
        # test list and iterator
        rs1 = bucket.list()
        num_iter = 0
        for r in rs1:
            num_iter = num_iter + 1
        rs = bucket.get_all_keys()
        num_keys = len(rs)
        assert num_iter == num_keys
        # try some acl stuff
        bucket.set_acl('public-read')
        acl = bucket.get_acl()
        assert len(acl.entries.entry_list) == 2
        bucket.set_acl('private')
        acl = bucket.get_acl()
        assert len(acl.entries.entry_list) == 1
        k = bucket.lookup('foo/bar')
        k.set_acl('public-read')
        acl = k.get_acl()
        assert len(acl.entries.entry_list) == 2
        k.set_acl('private')
        acl = k.get_acl()
        assert len(acl.entries.entry_list) == 1
        #
        # Test case-insensitivity of XML ACL parsing.
        acl_xml = (
            '<ACCESSControlList><EntrIes><Entry>' +
            '<Scope type="AllUsers"></Scope><Permission>READ</Permission>' +
            '</Entry></EntrIes></ACCESSControlList>')
        acl = boto.gs.acl.ACL()
        h = handler.XmlHandler(acl, bucket)
        xml.sax.parseString(acl_xml, h)
        bucket.set_acl(acl)
        assert len(acl.entries.entry_list) == 1
        #
        # try set/get raw logging subresource
        empty_logging_str = "<?xml version='1.0' encoding='UTF-8'?><Logging/>"
        logging_str = ("<?xml version='1.0' encoding='UTF-8'?><Logging>"
                       "<LogBucket>log-bucket</LogBucket>" +
                       "<LogObjectPrefix>example</LogObjectPrefix>" +
                       "</Logging>")
        bucket.set_subresource('logging', logging_str)
        assert bucket.get_subresource('logging') == logging_str
        # try disable/enable logging
        bucket.disable_logging()
        assert bucket.get_subresource('logging') == empty_logging_str
        bucket.enable_logging('log-bucket', 'example')
        assert bucket.get_subresource('logging') == logging_str
        # now delete all keys in bucket
        for k in bucket:
            bucket.delete_key(k)
        # now delete bucket
        time.sleep(5)
        c.delete_bucket(bucket)