diff --git a/CHANGELOG.md b/CHANGELOG.md index fc6b2735..6f87dd18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ## CHANGE LOG +### v6.1.4 + +2013-10-25 issues [#52](https://github.com/qiniu/php-sdk/pull/52) + +- PutPolicy: 增加 saveKey、persistentOps/persistentNotifyUrl、fsizeLimit 等支持 + + ### v6.1.3 2013-10-09 issues [#50](https://github.com/qiniu/php-sdk/pull/50) @@ -8,6 +15,7 @@ - 修订文档 - 消除测试用例并发问题 + ### v6.1.2 2013-09-24 issue [#40](https://github.com/qiniu/php-sdk/pull/40) diff --git a/docs/README.md b/docs/README.md index 4d950e13..4744d60d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -250,6 +250,8 @@ SDK源码地址: public $AsyncOps; // 可选 public $EndUser; // 可选 public $Expires; // 可选。默认是 3600 秒 + public $PersistentOps; // 可选。 + public $PersistentNotifyUrl; // 如果设置了PersistentOps,必须同时设置此项。 } * `scope` 限定客户端的权限。如果 `scope` 是 bucket,则客户端只能新增文件到指定的 bucket,不能修改文件。如果 `scope` 为 bucket:key,则客户端可以修改指定的文件。**注意: key必须采用utf8编码,如使用非utf8编码访问七牛云存储将反馈错误** @@ -257,7 +259,9 @@ SDK源码地址: * `callbackBody` 设定业务服务器的回调信息。文件上传成功后,七牛向业务服务器的callbackUrl发送的POST请求携带的数据。支持 [魔法变量](http://docs.qiniu.com/api/put.html#MagicVariables) 和 [自定义变量](http://docs.qiniu.com/api/put.html#xVariables)。 * `returnUrl` 设置用于浏览器端文件上传成功后,浏览器执行301跳转的URL,一般为 HTML Form 上传时使用。文件上传成功后浏览器会自动跳转到 `returnUrl?upload_ret=returnBody`。 * `returnBody` 可调整返回给客户端的数据包,支持 [魔法变量](http://docs.qiniu.com/api/put.html#MagicVariables) 和 [自定义变量](http://docs.qiniu.com/api/put.html#xVariables)。`returnBody` 只在没有 `callbackUrl` 时有效(否则直接返回 `callbackUrl` 返回的结果)。不同情形下默认返回的 `returnBody` 并不相同。在一般情况下返回的是文件内容的 `hash`,也就是下载该文件时的 `etag`;但指定 `returnUrl` 时默认的 `returnBody` 会带上更多的信息。 -* `asyncOps` 可指定上传完成后,需要自动执行哪些数据处理。这是因为有些数据处理操作(比如音视频转码)比较慢,如果不进行预转可能第一次访问的时候效果不理想,预转可以很大程度改善这一点。 +* `asyncOps` 可指定上传完成后,需要自动执行哪些数据处理。这是因为有些数据处理操作(比如音视频转码)比较慢,如果不进行预转可能第一次访问的时候效果不理想,预转可以很大程度改善这一点。 +* `persistentOps` 可指定音视频文件上传完成后,需要进行的转码持久化操作。asyncOps的处理结果保存在缓存当中,有可能失效。而persistentOps的处理结果以文件形式保存在bucket中,体验更佳。[数据处理(持久化)](http://docs.qiniu.com/api/persistent-ops.html) +* `persistentNotifyUrl` 音视频转码持久化完成后,七牛的服务器会向用户发送处理结果通知。这里指定的url就是用于接收通知的接口。设置了`persistentOps`,则需要同时设置此字段。 关于上传策略更完整的说明,请参考 [uptoken](http://docs.qiniu.com/api/put.html#uploadToken)。 diff --git a/qiniu/rs.php b/qiniu/rs.php index 579c533e..db79caa3 100644 --- a/qiniu/rs.php +++ b/qiniu/rs.php @@ -41,14 +41,20 @@ function Qiniu_RS_MakeBaseUrl($domain, $key) // => $baseUrl class Qiniu_RS_PutPolicy { - public $Scope; + public $Scope; //必填 + public $Expires; //默认为3600s public $CallbackUrl; public $CallbackBody; public $ReturnUrl; public $ReturnBody; public $AsyncOps; public $EndUser; - public $Expires; + public $InsertOnly; //若非0,则任何情况下无法覆盖上传 + public $DetectMime; //若非0,则服务端根据内容自动确定MimeType + public $FsizeLimit; + public $SaveKey; + public $PersistentOps; + public $PersistentNotifyUrl; public function __construct($scope) { @@ -82,6 +88,24 @@ public function Token($mac) // => $token if (!empty($this->EndUser)) { $policy['endUser'] = $this->EndUser; } + if (!empty($this->InsertOnly)) { + $policy['exclusive'] = $this->InsertOnly; + } + if (!empty($this->DetectMime)) { + $policy['detectMime'] = $this->DetectMime; + } + if (!empty($this->FsizeLimit)) { + $policy['fsizeLimit'] = $this->FsizeLimit; + } + if (!empty($this->SaveKey)) { + $policy['saveKey'] = $this->SaveKey; + } + if (!empty($this->PersistentOps)) { + $policy['persistentOps'] = $this->PersistentOps; + } + if (!empty($this->PersistentNotifyUrl)) { + $policy['persistentNotifyUrl'] = $this->PersistentNotifyUrl; + } $b = json_encode($policy); return Qiniu_SignWithData($mac, $b); diff --git a/tests/IoTest.php b/tests/IoTest.php index 18f29065..16d04f71 100644 --- a/tests/IoTest.php +++ b/tests/IoTest.php @@ -55,5 +55,68 @@ public function testPut() $err = Qiniu_RS_Delete($this->client, $this->bucket, $key); $this->assertNull($err); } + + public function testPut_sizelimit() + { + $key = 'testPut_sizelimit' . getTid(); + $err = Qiniu_RS_Delete($this->client, $this->bucket, $key); + + $putPolicy = new Qiniu_RS_PutPolicy($this->bucket); + $putPolicy->FsizeLimit = 1; + $upToken = $putPolicy->Token(null); + list($ret, $err) = Qiniu_Put($upToken, $key, "hello world!", null); + $this->assertNull($ret); + $this->assertEquals($err->Err, 'exceed FsizeLimit'); + var_dump($err); + } + + public function testPut_mime_save() + { + $key = 'testPut_mime_save' . getTid(); + $err = Qiniu_RS_Delete($this->client, $this->bucket, $key); + + $putPolicy = new Qiniu_RS_PutPolicy($this->bucket); + $putPolicy->DetectMime = 1; + $putPolicy->SaveKey = $key; + $upToken = $putPolicy->Token(null); + $putExtra = new Qiniu_PutExtra(); + $putExtra->MimeType = 'image/jpg'; + list($ret, $err) = Qiniu_PutFile($upToken, null, __file__, $putExtra); + $this->assertNull($err); + + list($ret, $err) = Qiniu_RS_Stat($this->client, $this->bucket, $key); + $this->assertNull($err); + $this->assertEquals($ret['mimeType'], 'application/x-httpd-php'); + var_dump($ret); + + $err = Qiniu_RS_Delete($this->client, $this->bucket, $key); + $this->assertNull($err); + } + + public function testPut_exclusive() + { + $key = 'testPut_exclusive' . getTid(); + $scope = $this->bucket . ':' . $key; + $err = Qiniu_RS_Delete($this->client, $this->bucket, $key); + + $putPolicy = new Qiniu_RS_PutPolicy($scope); + $putPolicy->InsertOnly = 1; + $upToken = $putPolicy->Token(null); + + list($ret, $err) = Qiniu_Put($upToken, $key, "hello world!", null); + $this->assertNull($err); + list($ret, $err) = Qiniu_PutFile($upToken, $key, __file__, null); + $this->assertNull($ret); + $this->assertEquals($err->Err, 'file exists'); + var_dump($err); + + list($ret, $err) = Qiniu_RS_Stat($this->client, $this->bucket, $key); + $this->assertNull($err); + $this->assertEquals($ret['mimeType'], 'application/octet-stream'); + var_dump($ret); + + $err = Qiniu_RS_Delete($this->client, $this->bucket, $key); + $this->assertNull($err); + } } diff --git a/tests/PersistentTest.php b/tests/PersistentTest.php new file mode 100644 index 00000000..0f4e2beb --- /dev/null +++ b/tests/PersistentTest.php @@ -0,0 +1,65 @@ +client = new Qiniu_MacHttpClient(null); + $this->bucket = getenv("QINIU_BUCKET_NAME"); + } + + public function testPutFileWithPersistentOps() + { + $key = 'testPutFileWithPersistentOps' . getTid(); + $err = Qiniu_RS_Delete($this->client, $this->bucket, $key); + + $putPolicy = new Qiniu_RS_PutPolicy($this->bucket); + $putPolicy->PersistentOps = 'avthumb/mp3'; + $putPolicy->PersistentNotifyUrl = 'http://someurl/abc'; + $upToken = $putPolicy->Token(null); + $putExtra = new Qiniu_PutExtra(); + $putExtra->CheckCrc = 1; + list($ret, $err) = Qiniu_PutFile($upToken, $key, __file__, $putExtra); + $this->assertNull($err); + $this->assertArrayHasKey('hash', $ret); + $this->assertArrayHasKey('persistentId', $ret); + 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 testPutWithPersistentOps() + { + $key = 'testPutWithPersistentOps' . getTid(); + $err = Qiniu_RS_Delete($this->client, $this->bucket, $key); + + $putPolicy = new Qiniu_RS_PutPolicy($this->bucket); + $putPolicy->PersistentOps = 'avthumb/mp3'; + $putPolicy->PersistentNotifyUrl = 'http://someurl/abc'; + $upToken = $putPolicy->Token(null); + list($ret, $err) = Qiniu_Put($upToken, $key, "hello world!", null); + $this->assertNull($err); + $this->assertArrayHasKey('hash', $ret); + $this->assertArrayHasKey('persistentId', $ret); + 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); + } +} +