Executes download request.

    :param request: DownloadRequest to be executed
    :type request: DownloadRequest
    :return: downloaded data or None
    :rtype: numpy array, other possible data type or None
    :raises: DownloadFailedException

def execute_download_request(request):
    """ Executes download request.

    :param request: DownloadRequest to be executed
    :type request: DownloadRequest
    :return: downloaded data or None
    :rtype: numpy array, other possible data type or None
    :raises: DownloadFailedException
    """
    if request.save_response and request.data_folder is None:
        raise ValueError('Data folder is not specified. '
                         'Please give a data folder name in the initialization of your request.')

    if not request.will_download:
        return None

    try_num = SHConfig().max_download_attempts
    response = None
    while try_num > 0:
        try:
            if request.is_aws_s3():
                response = _do_aws_request(request)
                response_content = response['Body'].read()
            else:
                response = _do_request(request)
                response.raise_for_status()
                response_content = response.content
            LOGGER.debug('Successful download from %s', request.url)
            break
        except requests.RequestException as exception:
            try_num -= 1
            if try_num > 0 and (_is_temporal_problem(exception) or
                                (isinstance(exception, requests.HTTPError) and
                                 exception.response.status_code >= requests.status_codes.codes.INTERNAL_SERVER_ERROR) or
                                _request_limit_reached(exception)):
                LOGGER.debug('Download attempt failed: %s\n%d attempts left, will retry in %ds', exception,
                             try_num, SHConfig().download_sleep_time)
                sleep_time = SHConfig().download_sleep_time
                if _request_limit_reached(exception):
                    sleep_time = max(sleep_time, 60)
                time.sleep(sleep_time)
            else:
                if request.url.startswith(SHConfig().aws_metadata_url) and \
                        isinstance(exception, requests.HTTPError) and \
                        exception.response.status_code == requests.status_codes.codes.NOT_FOUND:
                    raise AwsDownloadFailedException('File in location %s is missing' % request.url)
                raise DownloadFailedException(_create_download_failed_message(exception, request.url))

    _save_if_needed(request, response_content)

    if request.return_data:
        return decode_data(response_content, request.data_type, entire_response=response)
    return None