Exemplo n.º 1
0
    def new_http_connection(self, host, port, is_secure):
        if host is None:
            host = self.server_name()

        # Make sure the host is really just the host, not including
        # the port number
        host = host.split(':', 1)[0]

        http_connection_kwargs = self.http_connection_kwargs.copy()

        # Connection factories below expect a port keyword argument
        http_connection_kwargs['port'] = port

        # Override host with proxy settings if needed
        if self.use_proxy and not is_secure and \
                not self.skip_proxy(host):
            host = self.proxy
            http_connection_kwargs['port'] = int(self.proxy_port)

        if is_secure:
            boto.log.debug(
                    'establishing HTTPS connection: host=%s, kwargs=%s',
                    host, http_connection_kwargs)
            if self.use_proxy and not self.skip_proxy(host):
                connection = self.proxy_ssl(host, is_secure and 443 or 80)
            elif self.https_connection_factory:
                connection = self.https_connection_factory(host)
            elif self.https_validate_certificates and HAVE_HTTPS_CONNECTION:
                connection = https_connection.CertValidatingHTTPSConnection(
                        host, ca_certs=self.ca_certificates_file,
                        **http_connection_kwargs)
            else:
                connection = http_client.HTTPSConnection(host,
                        **http_connection_kwargs)
        else:
            boto.log.debug('establishing HTTP connection: kwargs=%s' %
                    http_connection_kwargs)
            if self.https_connection_factory:
                # even though the factory says https, this is too handy
                # to not be able to allow overriding for http also.
                connection = self.https_connection_factory(host,
                    **http_connection_kwargs)
            else:
                connection = http_client.HTTPConnection(host,
                    **http_connection_kwargs)
        if self.debug > 1:
            connection.set_debuglevel(self.debug)
        # self.connection must be maintained for backwards-compatibility
        # however, it must be dynamically pulled from the connection pool
        # set a private variable which will enable that
        if host.split(':')[0] == self.host and is_secure == self.is_secure:
            self._connection = (host, port, is_secure)
        # Set the response class of the http connection to use our custom
        # class.
        connection.response_class = HTTPResponse
        return connection
Exemplo n.º 2
0
    def proxy_ssl(self, host=None, port=None):
        if host and port:
            host = '%s:%d' % (host, port)
        else:
            host = '%s:%d' % (self.host, self.port)
        # Seems properly to use timeout for connect too
        timeout = self.http_connection_kwargs.get("timeout")
        if timeout is not None:
            sock = socket.create_connection((self.proxy,
                                             int(self.proxy_port)), timeout)
        else:
            sock = socket.create_connection((self.proxy, int(self.proxy_port)))
        boto.log.debug("Proxy connection: CONNECT %s HTTP/1.0\r\n", host)
        sock.sendall("CONNECT %s HTTP/1.0\r\n" % host)
        sock.sendall("User-Agent: %s\r\n" % UserAgent)
        if self.proxy_user and self.proxy_pass:
            for k, v in self.get_proxy_auth_header().items():
                sock.sendall("%s: %s\r\n" % (k, v))
            # See discussion about this config option at
            # https://groups.google.com/forum/?fromgroups#!topic/boto-dev/teenFvOq2Cc
            if config.getbool('Boto', 'send_crlf_after_proxy_auth_headers', False):
                sock.sendall("\r\n")
        else:
            sock.sendall("\r\n")
        resp = http_client.HTTPResponse(sock, strict=True, debuglevel=self.debug)
        resp.begin()

        if resp.status != 200:
            # Fake a socket error, use a code that make it obvious it hasn't
            # been generated by the socket library
            raise socket.error(-71,
                               "Error talking to HTTP proxy %s:%s: %s (%s)" %
                               (self.proxy, self.proxy_port,
                                resp.status, resp.reason))

        # We can safely close the response, it duped the original socket
        resp.close()

        h = http_client.HTTPConnection(host)

        if self.https_validate_certificates and HAVE_HTTPS_CONNECTION:
            msg = "wrapping ssl socket for proxied connection; "
            if self.ca_certificates_file:
                msg += "CA certificate file=%s" %self.ca_certificates_file
            else:
                msg += "using system provided SSL certs"
            boto.log.debug(msg)
            key_file = self.http_connection_kwargs.get('key_file', None)
            cert_file = self.http_connection_kwargs.get('cert_file', None)
            sslSock = ssl.wrap_socket(sock, keyfile=key_file,
                                      certfile=cert_file,
                                      cert_reqs=ssl.CERT_REQUIRED,
                                      ca_certs=self.ca_certificates_file)
            cert = sslSock.getpeercert()
            hostname = self.host.split(':', 0)[0]
            if not https_connection.ValidateCertificateHostname(cert, hostname):
                raise https_connection.InvalidCertificateException(
                        hostname, cert, 'hostname mismatch')
        else:
            # Fallback for old Python without ssl.wrap_socket
            if hasattr(http_client, 'ssl'):
                sslSock = http_client.ssl.SSLSocket(sock)
            else:
                sslSock = socket.ssl(sock, None, None)
                sslSock = http_client.FakeSocket(sock, sslSock)

        # This is a bit unclean
        h.sock = sslSock
        return h
Exemplo n.º 3
0
    def test_1_basic(self):
        print('--- running S3Connection tests ---')
        c = S3Connection()
        # 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)
        # test logging
        logging_bucket = c.create_bucket(bucket_name + '-log')
        logging_bucket.set_as_logging_target()
        bucket.enable_logging(target_bucket=logging_bucket,
                              target_prefix=bucket.name)
        bucket.disable_logging()
        c.delete_bucket(logging_bucket)
        k = bucket.new_key('foobar')
        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('foobar', 'wb')
        # now get the contents from s3 to a local file
        k.get_contents_to_file(fp)
        fp.close()
        fp = open('foobar')
        # check to make sure content read from s3 is identical to original
        assert s1 == fp.read(), 'corrupted file'
        fp.close()
        # test generated URLs
        url = k.generate_url(3600)
        file = urlopen(url)
        assert s1 == file.read().decode('utf-8'), 'invalid URL %s' % url
        url = k.generate_url(3600, force_http=True)
        file = urlopen(url)
        assert s1 == file.read().decode('utf-8'), 'invalid URL %s' % url
        url = k.generate_url(3600,
                             force_http=True,
                             headers={'x-amz-x-token': 'XYZ'})
        file = urlopen(url)
        assert s1 == file.read().decode('utf-8'), 'invalid URL %s' % url
        rh = {'response-content-disposition': 'attachment; filename="foo.txt"'}
        url = k.generate_url(60, response_headers=rh)
        file = urlopen(url)
        assert s1 == file.read().decode('utf-8'), 'invalid URL %s' % url
        #test whether amperands and to-be-escaped characters work in header filename
        rh = {
            'response-content-disposition':
            'attachment; filename="foo&z%20ar&ar&zar&bar.txt"'
        }
        url = k.generate_url(60, response_headers=rh, force_http=True)
        file = urlopen(url)
        assert s1 == file.read().decode('utf-8'), 'invalid URL %s' % url
        # overwrite foobar contents with a PUT
        url = k.generate_url(3600,
                             'PUT',
                             force_http=True,
                             policy='private',
                             reduced_redundancy=True)
        up = urlsplit(url)
        con = http_client.HTTPConnection(up.hostname, up.port)
        con.request("PUT", up.path + '?' + up.query, body="hello there")
        resp = con.getresponse()
        assert 200 == resp.status
        assert b"hello there" == k.get_contents_as_string()
        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'
        size = k.set_contents_from_filename('foobar')
        assert size == 42
        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
        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
        k = bucket.new_key('has_metadata')
        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('has_metadata')
        assert k.get_metadata(mdkey1) == mdval1
        assert k.get_metadata(mdkey2) == mdval2
        assert k.get_metadata(mdkey3) == mdval3
        k = bucket.new_key('has_metadata')
        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 a key with a funny character
        k = bucket.new_key('testnewline\n')
        k.set_contents_from_string('This is a test')
        rs = bucket.get_all_keys()
        assert len(rs) == num_keys + 1
        bucket.delete_key(k)
        rs = bucket.get_all_keys()
        assert len(rs) == num_keys
        # try some acl stuff
        bucket.set_acl('public-read')
        policy = bucket.get_acl()
        assert len(policy.acl.grants) == 2
        bucket.set_acl('private')
        policy = bucket.get_acl()
        assert len(policy.acl.grants) == 1
        k = bucket.lookup('foo/bar')
        k.set_acl('public-read')
        policy = k.get_acl()
        assert len(policy.acl.grants) == 2
        k.set_acl('private')
        policy = k.get_acl()
        assert len(policy.acl.grants) == 1
        # try the convenience methods for grants
        bucket.add_user_grant(
            'FULL_CONTROL',
            'c1e724fbfa0979a4448393c59a8c055011f739b6d102fb37a65f26414653cd67')
        try:
            bucket.add_email_grant('foobar', '*****@*****.**')
        except S3PermissionsError:
            pass
        # now try to create an RRS key
        k = bucket.new_key('reduced_redundancy')
        k.set_contents_from_string('This key has reduced redundancy',
                                   reduced_redundancy=True)

        # now try to inject a response header
        data = k.get_contents_as_string(
            response_headers={'response-content-type': 'foo/bar'})
        assert k.content_type == 'foo/bar'

        # now delete all keys in bucket
        for k in bucket:
            if k.name == 'reduced_redundancy':
                assert k.storage_class == 'REDUCED_REDUNDANCY'
            bucket.delete_key(k)
        # now delete bucket
        time.sleep(5)
        c.delete_bucket(bucket)
        print('--- tests completed ---')