todo

突破SAE curl / fetchurl 8MB限制,分段下载文件,

up:2016-01-26 13:36:04 edit:2016-01-26 13:36:04 view:3854

sae的网络请求有限制,超过8MB的文件只能返回8MB的内容,为了下载大文件,需要分段下载,

附上源码抛砖引玉.此代码用KV缓存已经下载过的文件,下载的文件会保存到domin中.

<?php
use sinacloud\sae\Storage as Storage;


function responsefilecontents($contents,$filenm=NULL){
	$rst=$contents;
	if(is_null($filenm)){
		$filenm="downloadfile";
	}
    Header("Content-type: application/octet-stream");
    Header("Accept-Ranges: bytes");
    Header("Accept-Length: ".strlen("$rst"));
    Header("Content-Disposition: attachment; filename=\"".$filenm."\""); 
    echo $rst;
    exit ;
}

function r404(){

    header('HTTP/1.1 404 Not Found');
    header("status: 404 Not Found"); 
    echo "not found";
    die();
}

function geturl_sina($url){
    $ch = curl_init();
    curl_setopt( $ch, CURLOPT_URL, $url );
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_exec( $ch );
    $response = curl_getinfo( $ch );
    $length=$response["download_content_length"];
    
    curl_close ( $ch );
    //echo "totle $length ";
    
    
    $rst=array();
    $maxfetch=7<<20;//8MB but here use 7MB
    
    //$maxfetch=100<<10; //for test 100KB
    $start=0;
    while(true){
	   $ch=curl_init();
	    curl_setopt( $ch, CURLOPT_URL, $url );
	    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
	    if($start+$maxfetch>=$length){
		curl_setopt( $ch, CURLOPT_RANGE, "$start-" );
		//echo "option $start- ";
		$contents =  curl_exec( $ch );
		array_push($rst,$contents);
		curl_close ( $ch );
		break;
	    }
	    else {
		  $end=$start+$maxfetch-1;
		  curl_setopt( $ch, CURLOPT_RANGE, "$start-$end" );
		  //echo "option $start-$end ";
		  $start=$end+1;
		  $contents =  curl_exec( $ch );
		  array_push($rst,$contents);
		  curl_close ( $ch );
	    }
	    
	    
	    
// 	       $response = curl_getinfo( $ch );
// 		var_dump($response);
// 		var_dump($contents);
// 		die();
    
	    
	    
	    
	  
    }
    
//      echo "pices:".count($rst)." ";
//      
//      echo substr($rst[0],0,10);
//      echo substr($rst[0],strlen($rst[0])-10,10);
//      echo "------";
//      echo substr($rst[1],0,10);
     
     
     $rst_f=implode('',$rst);
     
     return $rst_f;
     //die();

}

if(($url=$_GET["url"])==""){
    r404();
}
else{
      //echo "$url";
     //"http://down.newly-tech.com/brushlattest.apk"
      
     // $url="http://down.newly-tech.com/tb.zip";
	  
	  $kv = new SaeKV();
		// 初始化KVClient对象
		$ret = $kv->init();
		$k_rst=$kv->get($url);
		$s = new Storage();
		$domin="cache";
		
		$gi=strrpos($url,"/")+1;
		$fn=substr($url,$gi,strlen("$url")-$gi);
		//die($fn);
		if($k_rst &&  !$_GET["update"]){
			$rst=$s->getObject($domin, "$url");
			$rst=$rst->body;
			//var_dump($rst);
			//echo $rst->body;
			
			responsefilecontents($rst,"$fn");
		}
		else {
			//@ $rst=file_get_contents("$url");
			
// 			     $f=new SaeFetchurl();
// 			      @ $rst=$f->fetch("$url");

			$rst=geturl_sina($url);
			
			if($rst=="")  {
			//echo $f->errmsg();
			r404();
			}
			
			// 上传一个字符串到test这个Bucket中,设置此Object名为string.txt,并且设置其Content-type
			$s->putObject("$rst", "cache", "$url");
			$kv->set($url,time());
			
			responsefilecontents($rst,"$fn");
		}
      //test k if not have
      //save k-v fetch url 
      //return file
      
      //echo strlen($rst);
}



not in sinaapp