0

I have user can download file from other server/URL. This is sample code but resumable download not work and when try download begin from start

<?php
$url = "http://download.windowsupdate.com/c/msdownload/update/software/secu/2017/03/windows10.0-kb4012606-x64_e805b81ee08c3bb0a8ab2c5ce6be5b35127f8773.msu";
dl_file_resumable( $url );

function dl_file_resumable( $file, $is_resume = true ) {
    //Gather relevent info about file
    $size     = remotefilesize( $file );
    $fileinfo = pathinfo( $file );

    //workaround for IE filename bug with multiple periods / multiple dots in filename
    //that adds square brackets to filename - eg. setup.abc.exe becomes setup[1].abc.exe
    $filename = ( strstr( $_SERVER['HTTP_USER_AGENT'], 'MSIE' ) ) ?
        preg_replace( '/\./', '%2e', $fileinfo['basename'], substr_count( $fileinfo
                                                                          == [ 'basename' ], '.' ) - 1 ) : $fileinfo['basename'];

    $file_extension = strtolower( $fileinfo['extension'] );

    //This will set the Content-Type to the appropriate setting for the file
    switch ( $file_extension ) {
        case 'exe':
            $ctype = 'application/octet-stream';
            break;
        case 'zip':
            $ctype = 'application/zip';
            break;
        case 'rar':
            $ctype = 'application/x-rar-compressed';
            break;
        case 'mp3':
            $ctype = 'audio/mpeg';
            break;
        case 'mpg':
            $ctype = 'video/mpeg';
            break;
        case 'avi':
            $ctype = 'video/x-msvideo';
            break;
        default:
            $ctype = 'application/force-download';
    }

    //check if http_range is sent by browser (or download manager)
    if ( $is_resume && isset( $_SERVER['HTTP_RANGE'] ) ) {
        list( $size_unit, $range_orig ) = explode( '=', $_SERVER['HTTP_RANGE'], 2 );

        if ( $size_unit == 'bytes' ) {
            //multiple ranges could be specified at the same time, but for simplicity only serve the first range
            //http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt
            list( $range, $extra_ranges ) = explode( ',', $range_orig, 2 );
        } else {
            $range = '';
        }
    } else {
        $range = '';
    }

    //figure out download piece from range (if set)
    list( $seek_start, $seek_end ) = explode( '-', $range, 2 );

    //set start and end based on range (if set), else set defaults
    //also check for invalid ranges.
    $seek_end   = ( empty( $seek_end ) ) ? ( $size - 1 ) : min( abs( intval( $seek_end ) ), ( $size - 1 ) );
    $seek_start = ( empty( $seek_start ) || $seek_end < abs( intval( $seek_start ) ) ) ? 0 : max( abs( intval( $seek_start ) ), 0 );

    //add headers if resumable
    if ( $seek_start > 0 || $seek_end < ( $size - 1 ) ) {
        header( 'HTTP/1.1 206 Partial Content' );
        header( 'Content-Range: bytes ' . $seek_start . '-' . $seek_end . '/' . $size );
        header( 'Content-Length: ' . ( $seek_end - $seek_start + 1 ) );
    } else {

        header( "Content-Length: $size" );
    }

    header( 'Accept-Ranges: bytes' );

    //headers for IE Bugs (is this necessary?)
    //header("Cache-Control: cache, must-revalidate");
    //header("Pragma: public");

    header( 'Content-Type: ' . $ctype );
    header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
    header( "Pragma: public" );
    header( "Expires: -1" );
    header( "Cache-Control: public, must-revalidate, post-check=0, pre-check=0" );
    header( "Content-Disposition: attachment; filename=\"$filename\"" );

    //open the file
    $fp = fopen( $file, 'rb' );
    //seek to start of missing part
    fseek( $fp, $seek_start );

    //start buffered download
    while ( ! feof( $fp ) ) {
        //reset time limit for big files
        set_time_limit( 0 );
        print( fread( $fp, 1024 * 8 ) );
        flush();
        ob_flush();
        usleep(50000);
        if ( connection_status() != 0 ) {
            @fclose( $file );
            exit;
        }
    }

    fclose( $fp );
    exit;
}

function remotefilesize( $url, $user = "", $pw = "" ) {
    ob_start();
    $ch = curl_init( $url );
    curl_setopt( $ch, CURLOPT_HEADER, 1 );
    curl_setopt( $ch, CURLOPT_NOBODY, 1 );

    if ( ! empty( $user ) && ! empty( $pw ) ) {
        $headers = array( 'Authorization: Basic ' . base64_encode( "$user:$pw" ) );
        curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
    }

    $ok = curl_exec( $ch );
    curl_close( $ch );
    $head = ob_get_contents();
    ob_end_clean();

    $regex = '/Content-Length:\s([0-9].+?)\s/';
    $count = preg_match( $regex, $head, $matches );

    return isset( $matches[1] ) ? $matches[1] : "unknown";
}

I tested some code but similar behavior

Download with resume

http://www.media-division.com/php-download-script-with-resume-option/

Parsa
  • 596
  • 1
  • 5
  • 15
  • What have you done to debug this? For example did you use echo statements that listed the existing partial download size to make sure it is detected correctly? If the existing size is detected as 0 bytes it will always start over. – Dave S May 26 '17 at 20:28
  • I echo $_SERVER['HTTP_RANGE'] after first request , notice for Undefined index: HTTP_RANGE – Parsa May 26 '17 at 21:12

0 Answers0