Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions qiniu/io.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Qiniu_PutExtra
public $CheckCrc = 0;
}

function Qiniu_Put($upToken, $key, $body, $putExtra) // => ($data, $err)
function Qiniu_Put($upToken, $key, $body, $putExtra) // => ($putRet, $err)
{
global $QINIU_UP_HOST;

Expand All @@ -39,7 +39,7 @@ function Qiniu_Put($upToken, $key, $body, $putExtra) // => ($data, $err)
return Qiniu_Client_CallWithMultipartForm($client, $QINIU_UP_HOST, $fields, $files);
}

function Qiniu_PutFile($upToken, $key, $localFile, $putExtra) // => ($data, $err)
function Qiniu_PutFile($upToken, $key, $localFile, $putExtra) // => ($putRet, $err)
{
global $QINIU_UP_HOST;

Expand Down Expand Up @@ -67,3 +67,5 @@ function Qiniu_PutFile($upToken, $key, $localFile, $putExtra) // => ($data, $err
return Qiniu_Client_CallWithForm($client, $QINIU_UP_HOST, $fields, 'multipart/form-data');
}

// ----------------------------------------------------------

143 changes: 143 additions & 0 deletions qiniu/resumable_io.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<?php

require_once("http.php");
require_once("auth_digest.php");

// ----------------------------------------------------------
// class Qiniu_Rio_PutExtra

class Qiniu_Rio_PutExtra
{
public $Bucket = null; // 必选(未来会没有这个字段)。
public $Params = null;
public $MimeType = null;
public $ChunkSize = 0; // 可选。每次上传的Chunk大小
public $TryTimes = 0; // 可选。尝试次数
public $Progresses = null; // 可选。上传进度:[]BlkputRet
public $Notify = null; // 进度通知:func(blkIdx int, blkSize int, ret *BlkputRet)
public $NotifyErr = null; // 错误通知:func(blkIdx int, blkSize int, err error)

public function __construct($bucket = null) {
$this->Bucket = $bucket;
}
}

// ----------------------------------------------------------
// func Qiniu_Rio_BlockCount

define('QINIU_RIO_BLOCK_BITS', 22);
define('QINIU_RIO_BLOCK_SIZE', 1 << QINIU_RIO_BLOCK_BITS); // 4M

function Qiniu_Rio_BlockCount($fsize) // => $blockCnt
{
return ($fsize + (QINIU_RIO_BLOCK_SIZE - 1)) >> QINIU_RIO_BLOCK_BITS;
}

// ----------------------------------------------------------
// internal func Qiniu_Rio_Mkblock/Mkfile

function Qiniu_Rio_Mkblock($self, $host, $reader, $size) // => ($blkputRet, $err)
{
if (is_resource($reader)) {
$body = fread($reader, $size);
if ($body === false) {
$err = Qiniu_NewError(0, 'fread failed');
return array(null, $err);
}
} else {
list($body, $err) = $reader->Read($size);
if ($err !== null) {
return array(null, $err);
}
}
if (strlen($body) != $size) {
$err = Qiniu_NewError(0, 'fread failed: unexpected eof');
return array(null, $err);
}

$url = $host . '/mkblk/' . $size;
return Qiniu_Client_CallWithForm($self, $url, $body, 'application/octet-stream');
}

function Qiniu_Rio_Mkfile($self, $host, $key, $fsize, $extra) // => ($putRet, $err)
{
$entry = $extra->Bucket . ':' . $key;
$url = $host . '/rs-mkfile/' . Qiniu_Encode($entry) . '/fsize/' . $fsize;

if (!empty($extra->MimeType)) {
$url .= '/mimeType/' . Qiniu_Encode($extra->MimeType);
}

$ctxs = array();
foreach ($extra->Progresses as $prog) {
$ctxs []= $prog['ctx'];
}
$body = implode(',', $ctxs);

return Qiniu_Client_CallWithForm($self, $url, $body, 'text/plain');
}

// ----------------------------------------------------------
// class Qiniu_Rio_UploadClient

class Qiniu_Rio_UploadClient
{
public $uptoken;

public function __construct($uptoken)
{
$this->uptoken = $uptoken;
}

public function RoundTrip($req) // => ($resp, $error)
{
$token = $this->uptoken;
$req->Header['Authorization'] = "UpToken $token";
return Qiniu_Client_do($req);
}
}

// ----------------------------------------------------------
// class Qiniu_Rio_Put/PutFile

function Qiniu_Rio_Put($upToken, $key, $body, $fsize, $putExtra) // => ($putRet, $err)
{
global $QINIU_UP_HOST;

$self = new Qiniu_Rio_UploadClient($upToken);

$progresses = array();
$host = $QINIU_UP_HOST;
$uploaded = 0;
while ($uploaded < $fsize) {
if ($fsize < $uploaded + QINIU_RIO_BLOCK_SIZE) {
$bsize = $fsize - $uploaded;
} else {
$bsize = QINIU_RIO_BLOCK_SIZE;
}
list($blkputRet, $err) = Qiniu_Rio_Mkblock($self, $host, $body, $bsize);
$host = $blkputRet['host'];
$uploaded += $bsize;
$progresses []= $blkputRet;
}

$putExtra->Progresses = $progresses;
return Qiniu_Rio_Mkfile($self, $host, $key, $fsize, $putExtra);
}

function Qiniu_Rio_PutFile($upToken, $key, $localFile, $putExtra) // => ($putRet, $err)
{
$fp = fopen($localFile, 'rb');
if ($fp === false) {
$err = Qiniu_NewError(0, 'fopen failed');
return array(null, $err);
}

$fi = fstat($fp);
$result = Qiniu_Rio_Put($upToken, $key, $fp, $fi['size'], $putExtra);
fclose($fp);
return $result;
}

// ----------------------------------------------------------

5 changes: 3 additions & 2 deletions qiniu/rs.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,8 @@ function Qiniu_RS_Copy($self, $bucketSrc, $keySrc, $bucketDest, $keyDest) // =>
return Qiniu_Client_CallNoRet($self, $QINIU_RS_HOST . $uri);
}


// ----------------------------------------------------------
//batch
// batch

function Qiniu_RS_Batch($self, $ops) // => ($data, $error)
{
Expand Down Expand Up @@ -222,3 +221,5 @@ function Qiniu_RS_BatchCopy($self, $entryPairs)
return Qiniu_RS_Batch($self, $params);
}

// ----------------------------------------------------------

29 changes: 27 additions & 2 deletions qiniu/rs_utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,43 @@

require_once("rs.php");
require_once("io.php");
require_once("resumable_io.php");

function Qiniu_RS_Put($self, $bucket, $key, $body, $putExtra) // => ($data, $err)
function Qiniu_RS_Put($self, $bucket, $key, $body, $putExtra) // => ($putRet, $err)
{
$putPolicy = new Qiniu_RS_PutPolicy("$bucket:$key");
$upToken = $putPolicy->Token($self->Mac);
return Qiniu_Put($upToken, $key, $body, $putExtra);
}

function Qiniu_RS_PutFile($self, $bucket, $key, $localFile, $putExtra) // => ($data, $err)
function Qiniu_RS_PutFile($self, $bucket, $key, $localFile, $putExtra) // => ($putRet, $err)
{
$putPolicy = new Qiniu_RS_PutPolicy("$bucket:$key");
$upToken = $putPolicy->Token($self->Mac);
return Qiniu_PutFile($upToken, $key, $localFile, $putExtra);
}

function Qiniu_RS_Rput($self, $bucket, $key, $body, $fsize, $putExtra) // => ($putRet, $err)
{
$putPolicy = new Qiniu_RS_PutPolicy("$bucket:$key");
$upToken = $putPolicy->Token($self->Mac);
if ($putExtra == null) {
$putExtra = new Qiniu_Rio_PutExtra($bucket);
} else {
$putExtra->Bucket = $bucket;
}
return Qiniu_Rio_Put($upToken, $key, $body, $fsize, $putExtra);
}

function Qiniu_RS_RputFile($self, $bucket, $key, $localFile, $putExtra) // => ($putRet, $err)
{
$putPolicy = new Qiniu_RS_PutPolicy("$bucket:$key");
$upToken = $putPolicy->Token($self->Mac);
if ($putExtra == null) {
$putExtra = new Qiniu_Rio_PutExtra($bucket);
} else {
$putExtra->Bucket = $bucket;
}
return Qiniu_Rio_PutFile($upToken, $key, $localFile, $putExtra);
}

71 changes: 71 additions & 0 deletions tests/RioTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

require_once("bootstrap.php");

class RioTest extends PHPUnit_Framework_TestCase
{
public $bucket;
public $client;

public function setUp()
{
initKeys();
$this->client = new Qiniu_MacHttpClient(null);
$this->bucket = getenv("QINIU_BUCKET_NAME");
}

public function testMockReader()
{
$reader = new MockReader;
list($data) = $reader->Read(5);
$this->assertEquals($data, "ABCDE");

list($data) = $reader->Read(27);
$this->assertEquals($data, "FGHIJKLMNOPQRSTUVWXYZABCDEF");
}

public function testPut()
{
$key = 'testRioPut' . getTid();
$err = Qiniu_RS_Delete($this->client, $this->bucket, $key);

$putPolicy = new Qiniu_RS_PutPolicy($this->bucket);
$upToken = $putPolicy->Token(null);
$putExtra = new Qiniu_Rio_PutExtra($this->bucket);
$reader = new MockReader;
list($ret, $err) = Qiniu_Rio_Put($upToken, $key, $reader, 5, $putExtra);
$this->assertNull($err);
$this->assertEquals($ret['hash'], "Fnvgeq9GDVk6Mj0Nsz2gW2S_3LOl");
var_dump($ret);

list($ret, $err) = Qiniu_RS_Stat($this->client, $this->bucket, $key);
$this->assertNull($err);
var_dump($ret);

$err = Qiniu_RS_Delete($this->client, $this->bucket, $key);
$this->assertNull($err);
}

public function testLargePut()
{
$key = 'testRioLargePut' . getTid();
$err = Qiniu_RS_Delete($this->client, $this->bucket, $key);

$putPolicy = new Qiniu_RS_PutPolicy($this->bucket);
$upToken = $putPolicy->Token(null);
$putExtra = new Qiniu_Rio_PutExtra($this->bucket);
$reader = new MockReader;
list($ret, $err) = Qiniu_Rio_Put($upToken, $key, $reader, QINIU_RIO_BLOCK_SIZE + 5, $putExtra);
$this->assertNull($err);
$this->assertEquals($ret['hash'], "lgQEOCZ8Ievliq8XOfZmWTndgOll");
var_dump($ret);

list($ret, $err) = Qiniu_RS_Stat($this->client, $this->bucket, $key);
$this->assertNull($err);
var_dump($ret);

$err = Qiniu_RS_Delete($this->client, $this->bucket, $key);
$this->assertNull($err);
}
}

39 changes: 38 additions & 1 deletion tests/RsUtilsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,43 @@ public function setUp()
$this->bucket = getenv("QINIU_BUCKET_NAME");
}

public function testRput()
{
$key = 'tmp/testRput' . getTid();
$err = Qiniu_RS_Delete($this->client, $this->bucket, $key);

$reader = new MockReader;
list($ret, $err) = Qiniu_RS_Rput($this->client, $this->bucket, $key, $reader, 5, null);
$this->assertNull($err);
var_dump($ret);
$this->assertEquals($ret['hash'], "Fnvgeq9GDVk6Mj0Nsz2gW2S_3LOl");

list($ret, $err) = Qiniu_RS_Stat($this->client, $this->bucket, $key);
$this->assertNull($err);
var_dump($ret);

$err = Qiniu_RS_Delete($this->client, $this->bucket, $key);
$this->assertNull($err);
}

public function testRputFile()
{
$key = 'tmp/testRputFile' . getTid();
$err = Qiniu_RS_Delete($this->client, $this->bucket, $key);

list($ret, $err) = Qiniu_RS_RputFile($this->client, $this->bucket, $key, __file__, null);
$this->assertNull($err);
var_dump($ret);
$this->assertArrayHasKey('hash', $ret);

list($ret, $err) = Qiniu_RS_Stat($this->client, $this->bucket, $key);
$this->assertNull($err);
var_dump($ret);

$err = Qiniu_RS_Delete($this->client, $this->bucket, $key);
$this->assertNull($err);
}

public function testPutFile()
{
$key = 'tmp/testPutFile' . getTid();
Expand All @@ -39,7 +76,7 @@ public function testPut()
$key = 'tmp/testPut' . getTid();
$err = Qiniu_RS_Delete($this->client, $this->bucket, $key);

list($ret, $err) = Qiniu_RS_Put($this->client, $this->bucket, $key, "hello world!", null);
list($ret, $err) = Qiniu_RS_Put($this->client, $this->bucket, $key, 'hello world!', null);
$this->assertNull($err);
$this->assertArrayHasKey('hash', $ret);
var_dump($ret);
Expand Down
22 changes: 22 additions & 0 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,25 @@ function getTid() {
return $tid;
}

class MockReader
{
private $off = 0;

public function __construct($off = 0)
{
$this->off = $off;
}

public function Read($bytes) // => ($data, $err)
{
$off = $this->off;
$data = '';
for ($i = 0; $i < $bytes; $i++) {
$data .= chr(65 + ($off % 26)); // ord('A') = 65
$off++;
}
$this->off = $off;
return array($data, null);
}
}