def _establish_tunnel(self, connection, address):
        '''Establish a TCP tunnel.

        Coroutine.
        '''
        host = '[{}]'.format(address[0]) if ':' in address[0] else address[0]
        port = address[1]
        request = RawRequest('CONNECT', '{0}:{1}'.format(host, port))

        self.add_auth_header(request)

        stream = Stream(connection, keep_alive=True)

        _logger.debug('Sending Connect.')
        yield from stream.write_request(request)

        _logger.debug('Read proxy response.')
        response = yield from stream.read_response()

        if response.status_code != 200:
            debug_file = io.BytesIO()
            _logger.debug('Read proxy response body.')
            yield from stream.read_body(request, response, file=debug_file)

            debug_file.seek(0)
            _logger.debug(ascii(debug_file.read()))

        if response.status_code == 200:
            connection.tunneled = True
        else:
            raise NetworkError(
                'Proxy does not support CONNECT: {} {}'
                .format(response.status_code,
                        wpull.string.printable_str(response.reason))
            )
Establish a TCP tunnel.

        Coroutine.