s3_get_object_fallback Function

private function s3_get_object_fallback(key, content) result(success)

Fallback implementation using temporary files.

Used on platforms without popen support (Windows) or if streaming fails.

@param[in] key The S3 object key @param[out] content The downloaded content @return .true. if successful, .false. otherwise

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_fallback(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
        character(len=256) :: tmpfile
        integer :: unit, ios, filesize
        character(len=1) :: byte
        integer :: i

        success = .false.

        ! 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

        ! Create temp file name
        write(tmpfile, '(A,I0,A)') '/tmp/s3_get_', getpid(), '.tmp'

        ! Build curl command
        write(cmd, '(A,A,A,A,A)') 'curl -s -o ', trim(tmpfile), ' "', trim(url), '"'

        ! Execute curl
        call execute_command_line(cmd, exitstat=ios)
        if (ios /= 0) return

        ! Read the downloaded file
        inquire(file=tmpfile, size=filesize, iostat=ios)
        if (ios /= 0) return

        allocate(character(len=filesize) :: content)

        open(newunit=unit, file=tmpfile, access='stream', &
             form='unformatted', status='old', iostat=ios)
        if (ios /= 0) then
            deallocate(content)
            return
        end if

        do i = 1, filesize
            read(unit, iostat=ios) byte
            if (ios /= 0) exit
            content(i:i) = byte
        end do

        close(unit)

        ! Clean up temp file
        write(cmd, '(A,A)') 'rm -f ', trim(tmpfile)
        call execute_command_line(cmd)

        success = (ios == 0 .and. index(content, '<Error>') == 0)
    end function s3_get_object_fallback