s3_get_object Function

public function s3_get_object(key, content) result(success)

Download an object from S3 and return its content.

Downloads the specified object from S3 using an HTTP GET request via curl. The content is returned as an allocatable string. Works with both public and authenticated buckets.

@param[in] key The S3 object key (path within the bucket) @param[out] content The downloaded content as an allocatable string @return .true. if download succeeded, .false. on error

Note

The module must be initialized with s3_init() before calling this function.

Warning

Returns .false. if the module is not initialized or if the download fails.

Example

character(len=:), allocatable :: content
logical :: success

success = s3_get_object('data/input.txt', content)
if (success) then
    print *, 'Downloaded: ', len(content), ' bytes'
    print *, content
else
    print *, 'Download failed'
end if

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: key
character(len=:), intent(out), allocatable :: content

Return Value logical


Source Code

    function s3_get_object(key, content) result(success)
        character(len=*), intent(in) :: key
        character(len=:), allocatable, intent(out) :: content
        logical :: success
        character(len=2048) :: url
        character(len=4096) :: cmd
        integer :: exit_status
        character(len=2048) :: msg

        success = .false.
        if (.not. initialized) then
            call s3_log_error('s3_get_object called before s3_init()')
            return
        end if

        ! Log key (truncated if too long for buffer)
        if (len_trim(key) <= 2030) then  ! "Getting object: " is 17 chars
            write(msg, '(A,A)') 'Getting object: ', trim(key)
        else
            write(msg, '(A,A,A)') 'Getting object: ', key(1:2020), '...'
        end if
        call s3_log_info(trim(msg))

        ! Build URL
        if (current_config%use_https) then
            write(url, '(A,A,A,A,A,A)') 'https://', &
                trim(current_config%bucket), '.', &
                trim(current_config%endpoint), '/', &
                trim(key)
        else
            write(url, '(A,A,A,A,A,A)') 'http://', &
                trim(current_config%bucket), '.', &
                trim(current_config%endpoint), '/', &
                trim(key)
        end if

        write(msg, '(A,A)') 'URL: ', trim(url)
        call s3_log_debug(trim(msg))

        ! Build curl command
        write(cmd, '(A,A,A)') 'curl -s "', trim(url), '"'
        write(msg, '(A,A)') 'Command: ', trim(cmd)
        call s3_log_trace(trim(msg))

        ! Try streaming first (if available), fall back to temp file
        if (is_streaming_available()) then
            call s3_log_debug('Attempting direct streaming')
            ! Use direct streaming (no disk I/O)
            success = stream_command_output(trim(cmd), content, exit_status)
            if (success .and. exit_status == 0) then
                write(msg, '(A,I0,A)') 'Streaming successful, received ', len(content), ' bytes'
                call s3_log_debug(trim(msg))
                ! Check for S3 error in response
                if (index(content, '<Error>') > 0) then
                    call s3_log_error('S3 error detected in response')
                    if (len(content) < 500) then
                        call s3_log_debug('Response: ' // content)
                    else
                        call s3_log_debug('Response (first 500 chars): ' // content(1:500))
                    end if
                    success = .false.
                end if
                return
            else
                write(msg, '(A,I0)') 'Streaming failed with exit status: ', exit_status
                call s3_log_warn(trim(msg))
            end if
        else
            call s3_log_info('Streaming not available, using temp file method')
        end if

        ! Fallback to temp file method (for Windows or if streaming fails)
        call s3_log_debug('Falling back to temp file method')
        success = s3_get_object_fallback(key, content)

    end function s3_get_object