diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..b4ad3203 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +*.phar +*.zip +build/artifacts +phpunit.xml +phpunit.functional.xml +.DS_Store +.swp +.build +composer.lock +vendor +src/package.xml diff --git a/.scrutinizer.yml b/.scrutinizer.yml new file mode 100644 index 00000000..cf46d83b --- /dev/null +++ b/.scrutinizer.yml @@ -0,0 +1,35 @@ +filter: + excluded_paths: [tests/*] +checks: + php: + code_rating: true + remove_extra_empty_lines: true + remove_php_closing_tag: true + remove_trailing_whitespace: true + fix_use_statements: + remove_unused: true + preserve_multiple: false + preserve_blanklines: true + order_alphabetically: true + fix_php_opening_tag: true + fix_linefeed: true + fix_line_ending: true + fix_identation_4spaces: true + fix_doc_comments: true +tools: + external_code_coverage: + timeout: 600 + runs: 3 + php_analyzer: true + php_code_coverage: false + php_code_sniffer: + config: + standard: PSR2 + filter: + paths: ['src'] + php_loc: + enabled: true + excluded_dirs: [vendor, tests] + php_cpd: + enabled: true + excluded_dirs: [vendor, tests] diff --git a/.travis.yml b/.travis.yml index bbdbf105..07659be4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,20 @@ +# using docker container +sudo: false + language: php php: - - 5.2 - 5.3 - 5.4 - 5.5 - 5.6 before_script: - - export QINIU_ACCESS_KEY="Vhiv6a22kVN_zhtetbPNeG9sY3JUL1HG597EmBwQ" - - export QINIU_SECRET_KEY="b5b5vNg5nnkwkPfW5ayicPE_pj6hqgKMQEaWQ6JD" + - export QINIU_ACCESS_KEY="QWYn5TFQsLLU1pL5MFEmX3s5DmHdUThav9WyOWOm" + - export QINIU_SECRET_KEY="Bxckh6FA-Fbs9Yt3i3cbKVK22UPBmAOHJcL95pGz" - export QINIU_BUCKET_NAME="phpsdk" - - export QINIU_KEY_NAME="file_name" + - export QINIU_KEY_NAME="php-logo.png" - export QINIU_TEST_ENV="travis" + - composer install --prefer-source script: - - cd tests; phpunit . + - ./vendor/bin/phpcs --standard=PSR2 src + - ./vendor/bin/phpcs --standard=PSR2 tests + - ./vendor/bin/phpunit tests/Qiniu/Tests/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 42b55da8..322536b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,103 +1,12 @@ -## CHANGE LOG - -### v6.1.9 - -2014-4-8 issues [#75](https://github.com/qiniu/php-sdk/pull/75) - -- [#69] 增加User Agent以方便日志查询。 -- [#70] 增加Reqid信息以方便错误追溯。 -- [#71] Qiniu_RS_Stat返回411问题。 - -### v6.1.8 - -2014-4-6 issues [#68](https://github.com/qiniu/php-sdk/pull/68) - -- [#66]上传策略[支持mimeLimit字段](http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html#put-policy-mime-limit),用于限定上传文件的mimeType。 -- [#67] 新增接口的调用范例 - -### v6.1.7 - -2014-2-19 issues [#64](https://github.com/qiniu/php-sdk/pull/64) - -- 修复 PutExtra.Params 无效的问题 - -### v6.1.6 - -2014-2-17 issues [#62](https://github.com/qiniu/php-sdk/pull/62) - -- 上传策略[支持transform/fopTimeout字段](http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html#put-policy-transform),用于支持对上传内容做一次同步的数据处理,并将结果作为最终资源保存 - - -### v6.1.5 - -2014-2-13 issues [#59](https://github.com/qiniu/php-sdk/pull/59) - -- 修复 PutExtra.MimeType 无效的问题 - - -### 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) - -- 断点续上传使用mkfile -- 修订文档 -- 消除测试用例并发问题 - - -### v6.1.2 - -2013-09-24 issue [#40](https://github.com/qiniu/php-sdk/pull/40) - -- 解决与某些 PHP 框架不兼容问题(主要是全局变量的定义) -- 改善 `json_decode` 的错误提示(有可能 `json_last_error_msg` 函数不存在) - - -### v6.1.1 - -2013-07-04 issue [#24](https://github.com/qiniu/php-sdk/pull/24) - -- 支持断点续上传(`Qiniu_RS_Rput`, `Qiniu_RS_RputFile`) - - -### v6.1.0 - -2013-07-04 issue [#22](https://github.com/qiniu/php-sdk/pull/22) - -- hotfix: 修复上传的时候 key 中不能出现 '/' 的错误 - - -### v6.0.2 - -2013-07-04 issue [#20](https://github.com/qiniu/php-sdk/pull/20) - -- 增加 rsf, batch 支持 -- 初步补充文档 - - -### v6.0.1 - -2013-07-03 issue [#10](https://github.com/qiniu/php-sdk/pull/10) - -- new Qiniu_RS_GetPolicy($expires = 0); -- new Qiniu_RS_PutPolicy($scope, $expires = 0); - - -### v6.0.0 - -2013-07-02 issue [#9](https://github.com/qiniu/php-sdk/pull/9) - -- 遵循 [sdkspec v6.0.2](https://github.com/qiniu/sdkspec/tree/v6.0.2) - - `Qiniu_Put/PutFile` 调整为基于 up.qiniu.com 的协议,extra *PutExtra 参数可以为 nil - - `Qiniu_Put/PutFile` 支持支持 key = null (UNDEFINED_KEY),这样服务端将自动生成 key 并返回 - - `Qiniu_Put/PutFile` 支持自定义的 "x:" 参数(io.PutExtra.Params)、支持 Crc 检查 - - 待增加:rsf, batch, resumable io 的支持 -- bugfix: 修复 crc32 为负数的错误 -- 增加 `Qiniu_RS_Put/PutFile` 辅助函数,用于服务端上传 - +#Changelog + +## 7.0.0 (2015-02-03) + +### 增加 +* 简化上传接口 +* 自动选择断点续上传还是直传 +* 重构代码,接口和内部结构更清晰 +* 改变mime +* 代码覆盖度报告 +* policy改为array, 便于灵活增加,并加入过期字段检查 +* 文件列表支持目录形式 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..0466bf97 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,30 @@ +# 贡献代码指南 + +我们非常欢迎大家来贡献代码,我们会向贡献者致以最诚挚的敬意。 + +一般可以通过在Github上提交[Pull Request](https://github.com/qiniu/php-sdk)来贡献代码。 + +## Pull Request要求 + +- **[PSR-2 编码风格标准](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** 。要通过项目中的code sniffer检查。 + +- **代码格式** 提交前 请按 ./vendor/bin/phpcbf --standard=PSR2 进行格式化。 + +- **必须添加测试!** - 如果没有测试(单元测试、集成测试都可以),那么提交的补丁是不会通过的。 + +- **记得更新文档** - 保证`README.md`以及其他相关文档及时更新,和代码的变更保持一致性。 + +- **考虑我们的发布周期** - 我们的版本号会服从[SemVer v2.0.0](http://semver.org/),我们绝对不会随意变更对外的API。 + +- **创建feature分支** - 最好不要从你的master分支提交 pull request。 + +- **一个feature提交一个pull请求** - 如果你的代码变更了多个操作,那就提交多个pull请求吧。 + +- **清晰的commit历史** - 保证你的pull请求的每次commit操作都是有意义的。如果你开发中需要执行多次的即时commit操作,那么请把它们放到一起再提交pull请求。 + +## 运行测试 + +``` bash +./vendor/bin/phpunit tests/Qiniu/Tests/ + +``` diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..0e269a9f --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 Qiniu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/Makefile b/Makefile deleted file mode 100644 index 91cc329a..00000000 --- a/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -all: - @echo - -install: - @echo - -test: - cd tests; phpunit . - diff --git a/README.md b/README.md index 0c7ecb1c..97d7ae7c 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,69 @@ # Qiniu Resource Storage SDK for PHP +[![@qiniu on weibo](http://img.shields.io/badge/weibo-%40qiniutek-blue.svg)](http://weibo.com/qiniutek) +[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE) +[![Build Status](https://travis-ci.org/qiniu/php-sdk.svg)](https://travis-ci.org/qiniu/php-sdk) +[![Latest Stable Version](https://img.shields.io/packagist/v/qiniu/php-sdk.svg)](https://packagist.org/packages/qiniu/php-sdk) +[![Total Downloads](https://img.shields.io/packagist/dt/qiniu/php-sdk.svg)](https://packagist.org/packages/qiniu/php-sdk) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/qiniu/php-sdk/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/qiniu/php-sdk/?branch=master) +[![Code Coverage](https://scrutinizer-ci.com/g/qiniu/php-sdk/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/qiniu/php-sdk/?branch=master) +## 安装 -[![Build Status](https://api.travis-ci.org/qiniu/php-sdk.png?branch=master)](https://travis-ci.org/qiniu/php-sdk) +1. 通过composer +```bash +$ composer require qiniu/php-sdk +``` +2. 直接下载安装,SDK 没有依赖其他第三方库,但需要使用composer的autoload -[![Qiniu Logo](http://qiniu-brand.qiniudn.com/5/logo-white-195x105.png)](http://www.qiniu.com/) +## 运行环境 +| Qiniu SDK版本 | PHP 版本 | +|:--------------------:|:---------------------------:| +| 7.x | cURL extension, 5.3 - 5.6 | +| 6.x | cURL extension, 5.2 - 5.6 | -## 下载 +## 使用方法 -### 从 release 版本下载 +### 上传 +```php +use Qiniu\Storage\UploadManager; +use Qiniu\Auth; +... + $upManager = new UploadManager(); + $auth = new Auth($accessKey, $secretKey); + $token = $auth->uploadToken($bucketName); + list($ret, $error) = $upManager->put($token, 'formput', 'hello world'); +... +``` -下载地址:https://github.com/qiniu/php-sdk/releases +## 测试 -这是我们建议的方式,release 版本有版本号,有 [CHANGELOG](https://github.com/qiniu/php-sdk/blob/develop/CHANGELOG.md),使用规格也会比较稳定。 +``` bash +$ ./vendor/bin/phpunit tests/Qiniu/Tests/ +``` -### 从 git 库下载 +## 常见问题 -你可以直接用 git clone 下载源代码来使用。但是请注意非 master 分支的代码在规格上可能承受变更,应谨慎使用。 +- $error保留了请求响应的信息,失败情况下ret 为none, 将$error可以打印出来,提交给我们。 +- API 的使用 demo 可以参考 [单元测试](https://github.com/qiniu/php-sdk/blob/master/tests)。 +## 代码贡献 -## 使用 +详情参考[代码提交指南](https://github.com/qiniu/php-sdk/blob/master/CONTRIBUTING.md)。 -参考文档:[七牛云存储 PHP SDK 使用指南](https://github.com/qiniu/php-sdk/tree/develop/docs) +## 贡献记录 +- [所有贡献者](https://github.com/qiniu/php-sdk/contributors) -## 贡献代码 +## 联系我们 -1. Fork -2. 创建您的特性分支 (`git checkout -b my-new-feature`) -3. 提交您的改动 (`git commit -am 'Added some feature'`) -4. 将您的修改记录提交到远程 `git` 仓库 (`git push origin my-new-feature`) -5. 然后到 github 网站的该 `git` 远程仓库的 `my-new-feature` 分支下发起 Pull Request +- 如果需要帮助,请提交工单(在portal右侧点击咨询和建议提交工单,或者直接向 support@qiniu.com 发送邮件) +- 如果有什么问题,可以到问答社区提问,[问答社区](http://qiniu.segmentfault.com/) +- 更详细的文档,见[官方文档站](http://developer.qiniu.com/) +- 如果发现了bug, 欢迎提交 [issue](https://github.com/qiniu/php-sdk/issues) +- 如果有功能需求,欢迎提交 [issue](https://github.com/qiniu/php-sdk/issues) +- 如果要提交代码,欢迎提交 pull request +- 欢迎关注我们的[微信](http://www.qiniu.com/#weixin) [微博](http://weibo.com/qiniutek),及时获取动态信息。 +## 代码许可 -## 许可证 - -Copyright (c) 2012-2014 qiniu.com - -基于 MIT 协议发布: - -* [www.opensource.org/licenses/MIT](http://www.opensource.org/licenses/MIT) +The MIT License (MIT).详情见 [License文件](https://github.com/qiniu/php-sdk/blob/master/LICENSE). diff --git a/composer.json b/composer.json index 8e8aa9f7..2e9dfd4b 100644 --- a/composer.json +++ b/composer.json @@ -2,13 +2,25 @@ "name": "qiniu/php-sdk", "type": "library", "description": "Qiniu Resource (Cloud) Storage SDK for PHP", - "keywords": ["qiniu","storage","CDN","sdk"], - "homepage": "http://www.qiniu.com/", + "keywords": ["qiniu", "storage", "sdk", "cloud"], + "homepage": "http://developer.qiniu.com/", "license": "MIT", + "authors": [ + { + "name": "Qiniu", + "email": "sdk@qiniu.com", + "homepage": "http://www.qiniu.com" + } + ], "require": { - "php": ">=5.2.4" + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" }, "autoload": { - "files": ["qiniu/rs_utils.php"] + "psr-4": {"Qiniu\\": "src/Qiniu"}, + "files": ["src/Qiniu/functions.php"] } } diff --git a/demo/fetch.php b/demo/fetch.php deleted file mode 100644 index 46e903dd..00000000 --- a/demo/fetch.php +++ /dev/null @@ -1,11 +0,0 @@ -MakeRequest($url, null); - -echo "\n"; -$url = 'http://sslayer.qiniudn.com/dive-into-golang.pptx?odconv/pdf'; -echo $gpy->MakeRequest($url, null); - -echo "\n"; -$url = 'http://sslayer.qiniug.com/2.m3u8'; -echo $gpy->MakeRequest($url, null); diff --git a/demo/pfop.php b/demo/pfop.php deleted file mode 100644 index 3afdcfed..00000000 --- a/demo/pfop.php +++ /dev/null @@ -1,22 +0,0 @@ -Bucket = 'rwxf'; -$pfop->Key = '1.mp4'; - -$savedKey = 'qiniu.jpg'; -$entry = Qiniu_Encode("$pfop->Bucket:$savedKey"); -$pfop->Fops = "vframe/jpg/offset/180/w/1000/h/1000/rotate/90|saveas/$entry"; - -list($ret, $err) = $pfop->MakeRequest($client); -echo "\n\n====> pfop result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} diff --git a/demo/sign_req.php b/demo/sign_req.php deleted file mode 100644 index a57dbef8..00000000 --- a/demo/sign_req.php +++ /dev/null @@ -1,10 +0,0 @@ - $url); -$req = new Qiniu_Request($u, ''); -$mac = Qiniu_RequireMac(null); - -echo $mac->SignRequest($req, true); diff --git a/demo/up.php b/demo/up.php deleted file mode 100644 index 1b7b2fab..00000000 --- a/demo/up.php +++ /dev/null @@ -1,27 +0,0 @@ -; - - -$client = new Qiniu_MacHttpClient(null); -$putPolicy = new Qiniu_RS_PutPolicy("$bucket:$key"); -$putPolicy->CallbackUrl = 'https://10fd05306325.a.passageway.io'; -$putPolicy->CallbackBody = 'key=$(key)&hash=$(etag)'; -$upToken = $putPolicy->Token(null); - -$putExtra = new Qiniu_PutExtra(); -$s = time(); -list($ret, $err) = Qiniu_PutFile($upToken, $key, $file, $putExtra); -echo "time elapse:". (time() - $s) . "\n"; -echo "====> Qiniu_PutFile result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} - diff --git a/docs/README.gist.md b/docs/README.gist.md deleted file mode 100644 index dc582fac..00000000 --- a/docs/README.gist.md +++ /dev/null @@ -1,481 +0,0 @@ ---- -title: PHP SDK ---- - -# PHP SDK 使用指南 - -此 SDK 适用于 PHP 5.1.0 及其以上版本。基于 [七牛云存储官方API](http://docs.qiniu.com) 构建。使用此 SDK 构建您的网络应用程序,能让您以非常便捷地方式将数据安全地存储到七牛云存储上。无论您的网络应用是一个网站程序,还是包括从云端(服务端程序)到终端(手持设备应用)的架构的服务或应用,通过七牛云存储及其 SDK,都能让您应用程序的终端用户高速上传和下载,同时也让您的服务端更加轻盈。 - -SDK源码地址: - - -- [应用接入](#install) - - [获取Access Key 和 Secret Key](#acc-appkey) -- [资源管理接口](#rs-api) - - [1 查看单个文件属性信息](#rs-stat) - - [2 复制单个文件](#rs-copy) - - [3 移动单个文件](#rs-move) - - [4 删除单个文件](#rs-delete) - - [5 批量操作](#batch) - - [5.1 批量获取文件信息](#batch_stat) - - [5.2 批量复制文件](#batch_copy) - - [5.3 批量删除文件](#batch_delete) - - [5.4 批量移动文件](#batch_move) -- [上传下载接口](#get-and-put-api) - - [1 文件上传](#upload) - - [1.1 上传流程](#io-put-flow) - - [1.2 上传策略](#io-put-policy) - - [1.3 断点续上传](#rio-putfile) - - [2 文件下载](#io-download) - - [2.1 公有资源下载](#public-download) - - [2.2 私有资源下载](#private-download) -- [数据处理接口](#fop-api) - - [1 图像](#fop-image) - - [1.1 查看图像属性](#fop-image-info) - - [1.2 查看图片EXIF信息](#fop-exif) - - [1.3 生成图片预览](#fop-image-view) -- [贡献代码](#contribution) -- [许可证](#license) - - - - -## 应用接入 - - - -### 1. 获取Access Key 和 Secret Key - -要接入七牛云存储,您需要拥有一对有效的 Access Key 和 Secret Key 用来进行签名认证。可以通过如下步骤获得: - -1. [开通七牛开发者帐号](https://portal.qiniu.com/signup) -2. [登录七牛开发者自助平台,查看 Access Key 和 Secret Key](https://portal.qiniu.com/setting/key) 。 - - -## 资源管理接口 - - -### 1.查看单个文件属性信息 - -示例代码如下: - -``` -{php} - -@gist(gist/demo.php#require_rs) - -@gist(gist/demo.php#bucket) -@gist(gist/demo.php#key1) - -@gist(gist/demo.php#set_keys) - -@gist(gist/demo.php#mac_client) -@gist(gist/demo.php#stat) -``` - -### 2. 复制单个文件 - -示例代码如下: - -``` -{php} - -@gist(gist/demo.php#require_rs) - -@gist(gist/demo.php#bucket) -@gist(gist/demo.php#key1) -@gist(gist/demo.php#key2) - -@gist(gist/demo.php#set_keys) - -@gist(gist/demo.php#mac_client) -@gist(gist/demo.php#copy) -``` - -### 3. 移动单个文件 - -示例代码如下: - -``` -{php} - -@gist(gist/demo.php#require_rs) - -@gist(gist/demo.php#bucket) -@gist(gist/demo.php#key1) -@gist(gist/demo.php#key2) - -@gist(gist/demo.php#set_keys) - -@gist(gist/demo.php#mac_client) -@gist(gist/demo.php#move) -``` - -### 4. 删除单个文件 - -示例代码如下: - -``` -{php} - -@gist(gist/demo.php#require_rs) - -@gist(gist/demo.php#bucket) -@gist(gist/demo.php#key1) - -@gist(gist/demo.php#set_keys) - -@gist(gist/demo.php#mac_client) -@gist(gist/demo.php#delete) -``` - -### 5.批量操作 -当您需要一次性进行多个操作时,可以使用批量操作。 - -#### 5.1 批量获取文件属性信息 -示例代码如下: - -``` -{php} - -@gist(gist/demo.php#require_rs) - -@gist(gist/demo.php#bucket) -@gist(gist/demo.php#key1) -@gist(gist/demo.php#key2) - -@gist(gist/demo.php#set_keys) - -@gist(gist/demo.php#entrypath1) -@gist(gist/demo.php#entrypath2) -@gist(gist/demo.php#mac_client) -@gist(gist/demo.php#batch_stat) -``` - -#### 5.2 批量复制文件 -示例代码如下: - -``` -{php} - -@gist(gist/demo.php#require_rs) - -@gist(gist/demo.php#bucket) -@gist(gist/demo.php#key1) -@gist(gist/demo.php#key2) - -@gist(gist/demo.php#set_keys) - -@gist(gist/demo.php#entrypath1) -@gist(gist/demo.php#entrypath2) -@gist(gist/demo.php#entrypath3) -@gist(gist/demo.php#mac_client) -@gist(gist/demo.php#batch_copy) -``` - -#### 5.3 批量删除文件 -示例代码如下: - -``` -{php} - -@gist(gist/demo.php#require_rs) - -@gist(gist/demo.php#bucket) -@gist(gist/demo.php#key1) -@gist(gist/demo.php#key2) - -@gist(gist/demo.php#set_keys) - -@gist(gist/demo.php#entrypath1) -@gist(gist/demo.php#entrypath2) -@gist(gist/demo.php#mac_client) -@gist(gist/demo.php#batch_delete) - -``` - -#### 5.4 批量移动文件 -示例代码如下: - -``` -{php} - -@gist(gist/demo.php#require_rs) - -@gist(gist/demo.php#bucket) -@gist(gist/demo.php#key1) - -@gist(gist/demo.php#set_keys) - -@gist(gist/demo.php#entrypath1) -@gist(gist/demo.php#entrypath3) -@gist(gist/demo.php#mac_client) -@gist(gist/demo.php#batch_move) - -``` - -## 上传下载接口 - - -### 1. 文件上传 - -为了尽可能地改善终端用户的上传体验,七牛云存储首创了客户端直传功能。一般云存储的上传流程是: - - 客户端(终端用户) => 业务服务器 => 云存储服务 - -这样多了一次上传的流程,和本地存储相比,会相对慢一些。但七牛引入了客户端直传,将整个上传过程调整为: - - 客户端(终端用户) => 七牛 => 业务服务器 - -客户端(终端用户)直接上传到七牛的服务器,通过DNS智能解析,七牛会选择到离终端用户最近的ISP服务商节点,速度会比本地存储快很多。文件上传成功以后,七牛的服务器使用回调功能,只需要将非常少的数据(比如Key)传给应用服务器,应用服务器进行保存即可。 - - -#### 1.1上传流程 - -在七牛云存储中,整个上传流程大体分为这样几步: - -1. 业务服务器颁发 [uptoken(上传授权凭证)](http://docs.qiniu.com/api/put.html#uploadToken)给客户端(终端用户) -2. 客户端凭借 [uptoken](http://docs.qiniu.com/api/put.html#uploadToken) 上传文件到七牛 -3. 在七牛获得完整数据后,发起一个 HTTP 请求回调到业务服务器 -4. 业务服务器保存相关信息,并返回一些信息给七牛 -5. 七牛原封不动地将这些信息转发给客户端(终端用户) - -需要注意的是,回调到业务服务器的过程是可选的,它取决于业务服务器颁发的 [uptoken](http://docs.qiniu.com/api/put.html#uploadToken)。如果没有回调,七牛会返回一些标准的信息(比如文件的 hash)给客户端。如果上传发生在业务服务器,以上流程可以自然简化为: - -1. 业务服务器生成 uptoken(不设置回调,自己回调到自己这里没有意义) -2. 凭借 [uptoken](http://docs.qiniu.com/api/put.html#uploadToken) 上传文件到七牛 -3. 善后工作,比如保存相关的一些信息 - -服务端生成 [uptoken](http://docs.qiniu.com/api/put.html#uploadToken) 代码如下: - -``` -{php} - -@gist(gist/demo.php#require_rs) - -@gist(gist/demo.php#set_keys) -@gist(gist/demo.php#bucket) -@gist(gist/demo.php#putpolicy) - -``` -上传文件到七牛(通常是客户端完成,但也可以发生在服务端): - - -上传字符串 - -``` -{php} - -@gist(gist/demo.php#require_rs) -@gist(gist/demo.php#require_io) - -@gist(gist/demo.php#bucket) -@gist(gist/demo.php#key1) - -@gist(gist/demo.php#set_keys) - -@gist(gist/demo.php#putpolicy) -@gist(gist/demo.php#put) -``` - -上传本地文件 - -``` -{php} - -@gist(gist/demo.php#require_rs) -@gist(gist/demo.php#require_io) - -@gist(gist/demo.php#bucket) -@gist(gist/demo.php#key1) -@gist(gist/demo.php#file) - -@gist(gist/demo.php#set_keys) - -@gist(gist/demo.php#putpolicy) -@gist(gist/demo.php#putfile) -``` - -### 1.2 上传策略 - -[uptoken](http://docs.qiniu.com/api/put.html#uploadToken) 实际上是用 AccessKey/SecretKey 进行数字签名的上传策略(`Qiniu_RS_PutPolicy`),它控制则整个上传流程的行为。让我们快速过一遍你都能够决策啥: - - class Qiniu_RS_PutPolicy - { - public $Scope; // 必选项。可以是 bucketName 或者 bucketName:key - public $CallbackUrl; // 可选 - public $CallbackBody; // 可选 - public $ReturnUrl; // 可选, 更贴切的名字是 redirectUrl。 - public $ReturnBody; // 可选 - public $AsyncOps; // 可选 - public $EndUser; // 可选 - public $Expires; // 可选。默认是 3600 秒 - public $PersistentOps; // 可选。 - public $PersistentNotifyUrl; // 如果设置了PersistentOps,必须同时设置此项。 - public $InsertOnly; // 可选。如果设置为非0值,则无论scope设置为何种形式,都只能以`新增`方式上传,不能覆盖。 - public $DetectMime; // 可选。如果设为非0值,则忽略上传端传递的文件MimeType信息,使用七牛服务器侦测内容后的判断结果。 - public $FsizeLimit; // 可选。int类型,超过限制大小的上传内容会被判为上传失败,返回413状态码。 - public $SaveKey; // 可选。自定义资源名格式。 - public $MimeLimit; // 可选。限定上传的文件类型。 - } - -* `scope` 限定客户端的权限。如果 `scope` 是 bucket,则客户端只能新增文件到指定的 bucket,不能修改文件。如果 `scope` 为 bucket:key,则客户端可以修改指定的文件。**注意: key必须采用utf8编码,如使用非utf8编码访问七牛云存储将反馈错误** -* `callbackUrl` 设定业务服务器的回调地址,这样业务服务器才能感知到上传行为的发生。 -* `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` 可指定上传完成后,需要自动执行哪些数据处理。这是因为有些数据处理操作(比如音视频转码)比较慢,如果不进行预转可能第一次访问的时候效果不理想,预转可以很大程度改善这一点。 -* `persistentOps` 可指定音视频文件上传完成后,需要进行的转码持久化操作。asyncOps的处理结果保存在缓存当中,有可能失效。而persistentOps的处理结果以文件形式保存在bucket中,体验更佳。[数据处理(持久化)](http://docs.qiniu.com/api/persistent-ops.html) -* `persistentNotifyUrl` 音视频转码持久化完成后,七牛的服务器会向用户发送处理结果通知。这里指定的url就是用于接收通知的接口。设置了`persistentOps`,则需要同时设置此字段。 - -关于上传策略更完整的说明,请参考 [uptoken](http://docs.qiniu.com/api/put.html#uploadToken)。 - - -### 1.3 断点续上传 -示例代码如下 - -``` -{php} - -@gist(gist/demo.php#require_rs) -@gist(gist/demo.php#require_rio) - -@gist(gist/demo.php#bucket) -@gist(gist/demo.php#key1) -@gist(gist/demo.php#file) - -@gist(gist/demo.php#set_keys) - -@gist(gist/demo.php#putpolicy) -@gist(gist/demo.php#rio_putfile) -``` - - -### 2. 文件下载 -七牛云存储上的资源下载分为 公有资源下载 和 私有资源下载 。 - -私有(private)是 Bucket(空间)的一个属性,一个私有 Bucket 中的资源为私有资源,私有资源不可匿名下载。 - -新创建的空间(Bucket)缺省为私有,也可以将某个 Bucket 设为公有,公有 Bucket 中的资源为公有资源,公有资源可以匿名下载。 - - -#### 2.1 公有资源下载 -如果在给bucket绑定了域名的话,可以通过以下地址访问。 - - [GET] http:/// - -示例代码: - - @gist(gist/demo.php#key1) - @gist(gist/demo.php#domain) - @gist(gist/demo.php#base_url) - -其中\是bucket所对应的域名。七牛云存储为每一个bucket提供一个默认域名。默认域名可以到[七牛云存储开发者平台](https://portal.qiniu.com/)中,空间设置的域名设置一节查询。用户也可以将自有的域名绑定到bucket上,通过自有域名访问七牛云存储。 - -**注意: key必须采用utf8编码,如使用非utf8编码访问七牛云存储将反馈错误** - - -#### 2.2 私有资源下载 -私有资源必须通过临时下载授权凭证(downloadToken)下载,如下: - - [GET] http:///?e=&token= - -注意,尖括号不是必需,代表替换项。 -私有下载链接可以使用 SDK 提供的如下方法生成: - -``` -{php} - -@gist(gist/demo.php#require_rs) - -@gist(gist/demo.php#key1) -@gist(gist/demo.php#domain) - -@gist(gist/demo.php#set_keys) -@gist(gist/demo.php#base_url) -@gist(gist/demo.php#getpolicy) - -``` - - -## 数据处理接口 -七牛支持在云端对图像, 视频, 音频等富媒体进行个性化处理 - - -### 1. 图像 - -#### 1.1 查看图像属性 - -``` -{php} - -@gist(gist/demo.php#require_rs) -@gist(gist/demo.php#require_fop) - -@gist(gist/demo.php#key1) -@gist(gist/demo.php#domain) - -@gist(gist/demo.php#set_keys) - -@gist(gist/demo.php#base_url) -@gist(gist/demo.php#image_info) -``` - -将`$imgInfoPrivateUrl`粘贴到浏览器地址栏中就可以查看该图像的信息了。 - - -#### 1.2 查看图片EXIF信息 - -``` -{php} - -@gist(gist/demo.php#require_rs) -@gist(gist/demo.php#require_fop) - -@gist(gist/demo.php#key1) -@gist(gist/demo.php#domain) - -@gist(gist/demo.php#set_keys) - -@gist(gist/demo.php#base_url) -@gist(gist/demo.php#image_exif) -``` - - -#### 1.3 生成图片预览 - -``` -{php} - -@gist(gist/demo.php#require_rs) -@gist(gist/demo.php#require_fop) - -@gist(gist/demo.php#key1) -@gist(gist/demo.php#domain) - -@gist(gist/demo.php#set_keys) - -@gist(gist/demo.php#base_url) -@gist(gist/demo.php#image_view) -``` - - -## 贡献代码 - -1. Fork -2. 创建您的特性分支 (`git checkout -b my-new-feature`) -3. 提交您的改动 (`git commit -am 'Added some feature'`) -4. 将您的修改记录提交到远程 `git` 仓库 (`git push origin my-new-feature`) -5. 然后到 github 网站的该 `git` 远程仓库的 `my-new-feature` 分支下发起 Pull Request - - - -## 许可证 - -Copyright (c) 2013 qiniu.com - -基于 MIT 协议发布: - -* [www.opensource.org/licenses/MIT](http://www.opensource.org/licenses/MIT) - - diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index ea2a4a7d..00000000 --- a/docs/README.md +++ /dev/null @@ -1,619 +0,0 @@ ---- -title: PHP SDK ---- - -# PHP SDK 使用指南 - -此 SDK 适用于 PHP 5.1.0 及其以上版本。基于 [七牛云存储官方API](http://docs.qiniu.com) 构建。使用此 SDK 构建您的网络应用程序,能让您以非常便捷地方式将数据安全地存储到七牛云存储上。无论您的网络应用是一个网站程序,还是包括从云端(服务端程序)到终端(手持设备应用)的架构的服务或应用,通过七牛云存储及其 SDK,都能让您应用程序的终端用户高速上传和下载,同时也让您的服务端更加轻盈。 - -SDK源码地址: - - -- [应用接入](#install) - - [获取Access Key 和 Secret Key](#acc-appkey) -- [资源管理接口](#rs-api) - - [1 查看单个文件属性信息](#rs-stat) - - [2 复制单个文件](#rs-copy) - - [3 移动单个文件](#rs-move) - - [4 删除单个文件](#rs-delete) - - [5 批量操作](#batch) - - [5.1 批量获取文件信息](#batch_stat) - - [5.2 批量复制文件](#batch_copy) - - [5.3 批量删除文件](#batch_delete) - - [5.4 批量移动文件](#batch_move) -- [上传下载接口](#get-and-put-api) - - [1 文件上传](#upload) - - [1.1 上传流程](#io-put-flow) - - [1.2 上传策略](#io-put-policy) - - [1.3 断点续上传](#rio-putfile) - - [2 文件下载](#io-download) - - [2.1 公有资源下载](#public-download) - - [2.2 私有资源下载](#private-download) -- [数据处理接口](#fop-api) - - [1 图像](#fop-image) - - [1.1 查看图像属性](#fop-image-info) - - [1.2 查看图片EXIF信息](#fop-exif) - - [1.3 生成图片预览](#fop-image-view) -- [贡献代码](#contribution) -- [许可证](#license) - - - - -## 应用接入 - - - -### 1. 获取Access Key 和 Secret Key - -要接入七牛云存储,您需要拥有一对有效的 Access Key 和 Secret Key 用来进行签名认证。可以通过如下步骤获得: - -1. [开通七牛开发者帐号](https://portal.qiniu.com/signup) -2. [登录七牛开发者自助平台,查看 Access Key 和 Secret Key](https://portal.qiniu.com/setting/key) 。 - - -## 资源管理接口 - - -### 1.查看单个文件属性信息 - -示例代码如下: - -```php - -require_once('qiniu/rs.php'); - -$bucket = 'phpsdk'; -$key1 = 'file_name_1'; - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); - -$client = new Qiniu_MacHttpClient(null); -list($ret, $err) = Qiniu_RS_Stat($client, $bucket, $key1); -echo "\n\n====> Qiniu_RS_Stat result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} -``` - -### 2. 复制单个文件 - -示例代码如下: - -```php - -require_once('qiniu/rs.php'); - -$bucket = 'phpsdk'; -$key1 = 'file_name_1'; -$key2 = 'file_name_2'; - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); - -$client = new Qiniu_MacHttpClient(null); -$err = Qiniu_RS_Copy($client, $bucket, $key1, $bucket, $key2); -echo "\n\n====> Qiniu_RS_Copy result: \n"; -if ($err !== null) { - var_dump($err); -} else { - echo "Success! \n"; -} -``` - -### 3. 移动单个文件 - -示例代码如下: - -```php - -require_once('qiniu/rs.php'); - -$bucket = 'phpsdk'; -$key1 = 'file_name_1'; -$key2 = 'file_name_2'; - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); - -$client = new Qiniu_MacHttpClient(null); -$err = Qiniu_RS_Move($client, $bucket, $key2, $bucket, $key1); -echo "\n\n====> Qiniu_RS_Move result: \n"; -if ($err !== null) { - var_dump($err); -} else { - echo "Success! \n"; -} -``` - -### 4. 删除单个文件 - -示例代码如下: - -```php - -require_once('qiniu/rs.php'); - -$bucket = 'phpsdk'; -$key1 = 'file_name_1'; - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); - -$client = new Qiniu_MacHttpClient(null); -$err = Qiniu_RS_Delete($client, $bucket, $key1); -echo "\n\n====> Qiniu_RS_Delete result: \n"; -if ($err !== null) { - var_dump($err); -} else { - echo "Success! \n"; -} -``` - -### 5.批量操作 -当您需要一次性进行多个操作时,可以使用批量操作。 - -#### 5.1 批量获取文件属性信息 -示例代码如下: - -```php - -require_once('qiniu/rs.php'); - -$bucket = 'phpsdk'; -$key1 = 'file_name_1'; -$key2 = 'file_name_2'; - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); - -$e1 = new Qiniu_RS_EntryPath($bucket, $key1); -$e2 = new Qiniu_RS_EntryPath($bucket, $key2); -$client = new Qiniu_MacHttpClient(null); -$entries = array($e1, $e2); -list($ret, $err) = Qiniu_RS_BatchStat($client, $entries); -echo "\n\n====> Qiniu_RS_BatchStat result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} -``` - -#### 5.2 批量复制文件 -示例代码如下: - -```php - -require_once('qiniu/rs.php'); - -$bucket = 'phpsdk'; -$key1 = 'file_name_1'; -$key2 = 'file_name_2'; - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); - -$e1 = new Qiniu_RS_EntryPath($bucket, $key1); -$e2 = new Qiniu_RS_EntryPath($bucket, $key2); -$key3 = $key1 . '3'; -$e3 = new Qiniu_RS_EntryPath($bucket, $key3); -$client = new Qiniu_MacHttpClient(null); -$entryPairs = array(new Qiniu_RS_EntryPathPair($e1, $e2), new Qiniu_RS_EntryPathPair($e1, $e3)); -list($ret, $err) = Qiniu_RS_BatchCopy($client, $entryPairs); -echo "\n\n====> Qiniu_RS_BatchCopy result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} -``` - -#### 5.3 批量删除文件 -示例代码如下: - -```php - -require_once('qiniu/rs.php'); - -$bucket = 'phpsdk'; -$key1 = 'file_name_1'; -$key2 = 'file_name_2'; - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); - -$e1 = new Qiniu_RS_EntryPath($bucket, $key1); -$e2 = new Qiniu_RS_EntryPath($bucket, $key2); -$client = new Qiniu_MacHttpClient(null); -$entries = array($e1, $e2); -list($ret, $err) = Qiniu_RS_BatchDelete($client, $entries); -echo "\n\n====> Qiniu_RS_BatchDelete result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} - -``` - -#### 5.4 批量移动文件 -示例代码如下: - -```php - -require_once('qiniu/rs.php'); - -$bucket = 'phpsdk'; -$key1 = 'file_name_1'; - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); - -$e1 = new Qiniu_RS_EntryPath($bucket, $key1); -$key3 = $key1 . '3'; -$e3 = new Qiniu_RS_EntryPath($bucket, $key3); -$client = new Qiniu_MacHttpClient(null); -$entryPairs = array(new Qiniu_RS_EntryPathPair($e3, $e1)); -list($ret, $err) = Qiniu_RS_BatchMove($client, $entryPairs); -echo "\n\n====> Qiniu_RS_BatchMove result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} - -``` - -## 上传下载接口 - - -### 1. 文件上传 - -为了尽可能地改善终端用户的上传体验,七牛云存储首创了客户端直传功能。一般云存储的上传流程是: - - 客户端(终端用户) => 业务服务器 => 云存储服务 - -这样多了一次上传的流程,和本地存储相比,会相对慢一些。但七牛引入了客户端直传,将整个上传过程调整为: - - 客户端(终端用户) => 七牛 => 业务服务器 - -客户端(终端用户)直接上传到七牛的服务器,通过DNS智能解析,七牛会选择到离终端用户最近的ISP服务商节点,速度会比本地存储快很多。文件上传成功以后,七牛的服务器使用回调功能,只需要将非常少的数据(比如Key)传给应用服务器,应用服务器进行保存即可。 - - -#### 1.1上传流程 - -在七牛云存储中,整个上传流程大体分为这样几步: - -1. 业务服务器颁发 [uptoken(上传授权凭证)](http://docs.qiniu.com/api/put.html#uploadToken)给客户端(终端用户) -2. 客户端凭借 [uptoken](http://docs.qiniu.com/api/put.html#uploadToken) 上传文件到七牛 -3. 在七牛获得完整数据后,发起一个 HTTP 请求回调到业务服务器 -4. 业务服务器保存相关信息,并返回一些信息给七牛 -5. 七牛原封不动地将这些信息转发给客户端(终端用户) - -需要注意的是,回调到业务服务器的过程是可选的,它取决于业务服务器颁发的 [uptoken](http://docs.qiniu.com/api/put.html#uploadToken)。如果没有回调,七牛会返回一些标准的信息(比如文件的 hash)给客户端。如果上传发生在业务服务器,以上流程可以自然简化为: - -1. 业务服务器生成 uptoken(不设置回调,自己回调到自己这里没有意义) -2. 凭借 [uptoken](http://docs.qiniu.com/api/put.html#uploadToken) 上传文件到七牛 -3. 善后工作,比如保存相关的一些信息 - -服务端生成 [uptoken](http://docs.qiniu.com/api/put.html#uploadToken) 代码如下: - -```php - -require_once('qiniu/rs.php'); - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); -$bucket = 'phpsdk'; -$putPolicy = new Qiniu_RS_PutPolicy($bucket); -$upToken = $putPolicy->Token(null); - -``` -上传文件到七牛(通常是客户端完成,但也可以发生在服务端): - - -上传字符串 - -```php - -require_once('qiniu/rs.php'); -require_once('qiniu/io.php'); - -$bucket = 'phpsdk'; -$key1 = 'file_name_1'; - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); - -$putPolicy = new Qiniu_RS_PutPolicy($bucket); -$upToken = $putPolicy->Token(null); -list($ret, $err) = Qiniu_Put($upToken, $key1, 'Qiniu Storage!', null); -echo "\n\n====> Qiniu_Put result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} -``` - -上传本地文件 - -```php - -require_once('qiniu/rs.php'); -require_once('qiniu/io.php'); - -$bucket = 'phpsdk'; -$key1 = 'file_name_1'; -$file = 'docs/gist/logo.jpg'; - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); - -$putPolicy = new Qiniu_RS_PutPolicy($bucket); -$upToken = $putPolicy->Token(null); -$putExtra = new Qiniu_PutExtra(); -$putExtra->Crc32 = 1; -list($ret, $err) = Qiniu_PutFile($upToken, $key1, $file, $putExtra); -echo "\n\n====> Qiniu_PutFile result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} -``` - -### 1.2 上传策略 - -[uptoken](http://docs.qiniu.com/api/put.html#uploadToken) 实际上是用 AccessKey/SecretKey 进行数字签名的上传策略(`Qiniu_RS_PutPolicy`),它控制则整个上传流程的行为。让我们快速过一遍你都能够决策啥: - -```php -class Qiniu_RS_PutPolicy -{ - public $Scope; // 必选项。可以是 bucketName 或者 bucketName:key - public $CallbackUrl; // 可选 - public $CallbackBody; // 可选 - public $ReturnUrl; // 可选, 更贴切的名字是 redirectUrl。 - public $ReturnBody; // 可选 - public $AsyncOps; // 可选 - public $EndUser; // 可选 - public $Expires; // 可选。默认是 3600 秒 - public $PersistentOps; // 可选。 - public $PersistentNotifyUrl; // 如果设置了PersistentOps,必须同时设置此项。 - public $InsertOnly; // 可选。如果设置为非0值,则无论scope设置为何种形式,都只能以`新增`方式上传,不能覆盖。 - public $DetectMime; // 可选。如果设为非0值,则忽略上传端传递的文件MimeType信息,使用七牛服务器侦测内容后的判断结果。 - public $FsizeLimit; // 可选。int类型,超过限制大小的上传内容会被判为上传失败,返回413状态码。 - public $SaveKey; // 可选。自定义资源名格式。 - public $MimeLimit; // 可选。限定上传的文件类型。 -} -``` - -* `scope` 限定客户端的权限。如果 `scope` 是 bucket,则客户端只能新增文件到指定的 bucket,不能修改文件。如果 `scope` 为 bucket:key,则客户端可以修改指定的文件。**注意: key必须采用utf8编码,如使用非utf8编码访问七牛云存储将反馈错误** -* `callbackUrl` 设定业务服务器的回调地址,这样业务服务器才能感知到上传行为的发生。 -* `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` 可指定上传完成后,需要自动执行哪些数据处理。这是因为有些数据处理操作(比如音视频转码)比较慢,如果不进行预转可能第一次访问的时候效果不理想,预转可以很大程度改善这一点。 -* `persistentOps` 可指定音视频文件上传完成后,需要进行的转码持久化操作。asyncOps的处理结果保存在缓存当中,有可能失效。而persistentOps的处理结果以文件形式保存在bucket中,体验更佳。[数据处理(持久化)](http://docs.qiniu.com/api/persistent-ops.html) -* `persistentNotifyUrl` 音视频转码持久化完成后,七牛的服务器会向用户发送处理结果通知。这里指定的url就是用于接收通知的接口。设置了`persistentOps`,则需要同时设置此字段。 - -关于上传策略更完整的说明,请参考 [uptoken](http://docs.qiniu.com/api/put.html#uploadToken)。 - - -### 1.3 断点续上传 -示例代码如下 - -```php - -require_once('qiniu/rs.php'); -require_once('qiniu/resumable_io.php'); - -$bucket = 'phpsdk'; -$key1 = 'file_name_1'; -$file = 'docs/gist/logo.jpg'; - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); - -$putPolicy = new Qiniu_RS_PutPolicy($bucket); -$upToken = $putPolicy->Token(null); -$putExtra = new Qiniu_Rio_PutExtra($bucket); -list($ret, $err) = Qiniu_Rio_PutFile($upToken, $key1, $file, $putExtra); -echo "\n\n====> Qiniu_Rio_PutFile result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} -``` - - -### 2. 文件下载 -七牛云存储上的资源下载分为 公有资源下载 和 私有资源下载 。 - -私有(private)是 Bucket(空间)的一个属性,一个私有 Bucket 中的资源为私有资源,私有资源不可匿名下载。 - -新创建的空间(Bucket)缺省为私有,也可以将某个 Bucket 设为公有,公有 Bucket 中的资源为公有资源,公有资源可以匿名下载。 - - -#### 2.1 公有资源下载 -如果在给bucket绑定了域名的话,可以通过以下地址访问。 - - [GET] http:/// - -示例代码: - -```php -$key1 = 'file_name_1'; -$domain = 'phpsdk.qiniudn.com'; -//$baseUrl 就是您要访问资源的地址 -$baseUrl = Qiniu_RS_MakeBaseUrl($domain, $key1); -``` - -其中\是bucket所对应的域名。七牛云存储为每一个bucket提供一个默认域名。默认域名可以到[七牛云存储开发者平台](https://portal.qiniu.com/)中,空间设置的域名设置一节查询。用户也可以将自有的域名绑定到bucket上,通过自有域名访问七牛云存储。 - -**注意: key必须采用utf8编码,如使用非utf8编码访问七牛云存储将反馈错误** - - -#### 2.2 私有资源下载 -私有资源必须通过临时下载授权凭证(downloadToken)下载,如下: - - [GET] http:///?e=&token= - -注意,尖括号不是必需,代表替换项。 -私有下载链接可以使用 SDK 提供的如下方法生成: - -```php - -require_once('qiniu/rs.php'); - -$key1 = 'file_name_1'; -$domain = 'phpsdk.qiniudn.com'; - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); -//$baseUrl 就是您要访问资源的地址 - $baseUrl = Qiniu_RS_MakeBaseUrl($domain, $key1); -$baseUrl = Qiniu_RS_MakeBaseUrl($domain, $key1); -$getPolicy = new Qiniu_RS_GetPolicy(); -$privateUrl = $getPolicy->MakeRequest($baseUrl, null); -echo "\n\n====> getPolicy result: \n"; -echo $privateUrl . "\n"; - -``` - - -## 数据处理接口 -七牛支持在云端对图像, 视频, 音频等富媒体进行个性化处理 - - -### 1. 图像 - -#### 1.1 查看图像属性 - -```php - -require_once('qiniu/rs.php'); -require_once('qiniu/fop.php'); - -$key1 = 'file_name_1'; -$domain = 'phpsdk.qiniudn.com'; - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); - -//$baseUrl 就是您要访问资源的地址 - $baseUrl = Qiniu_RS_MakeBaseUrl($domain, $key1); -$getPolicy = new Qiniu_RS_GetPolicy(); -$imgInfo = new Qiniu_ImageInfo; - -//生成fopUrl -$imgInfoUrl = $imgInfo->MakeRequest($baseUrl); - -//对fopUrl 进行签名,生成privateUrl。 公有bucket 此步可以省去。 -$imgInfoPrivateUrl = $getPolicy->MakeRequest($imgInfoUrl, null); -echo "\n\n====> imageInfo privateUrl: \n"; -echo $imgInfoPrivateUrl . "\n"; -``` - -将`$imgInfoPrivateUrl`粘贴到浏览器地址栏中就可以查看该图像的信息了。 - - -#### 1.2 查看图片EXIF信息 - -```php - -require_once('qiniu/rs.php'); -require_once('qiniu/fop.php'); - -$key1 = 'file_name_1'; -$domain = 'phpsdk.qiniudn.com'; - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); - -//$baseUrl 就是您要访问资源的地址 - $baseUrl = Qiniu_RS_MakeBaseUrl($domain, $key1); -$getPolicy = new Qiniu_RS_GetPolicy(); -$imgExif = new Qiniu_Exif; - -//生成fopUrl -$imgExifUrl = $imgExif->MakeRequest($baseUrl); -//对fopUrl 进行签名,生成privateUrl。 公有bucket 此步可以省去。 -$imgExifPrivateUrl = $getPolicy->MakeRequest($imgExifUrl, null); -echo "\n\n====> imageView privateUrl: \n"; -echo $imgExifPrivateUrl . "\n"; -``` - - -#### 1.3 生成图片预览 - -```php - -require_once('qiniu/rs.php'); -require_once('qiniu/fop.php'); - -$key1 = 'file_name_1'; -$domain = 'phpsdk.qiniudn.com'; - -$accessKey = ''; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); - -//$baseUrl 就是您要访问资源的地址 - $baseUrl = Qiniu_RS_MakeBaseUrl($domain, $key1); -$getPolicy = new Qiniu_RS_GetPolicy(); -$imgView = new Qiniu_ImageView; -$imgView->Mode = 1; -$imgView->Width = 60; -$imgView->Height = 30; - -//生成fopUrl -$imgViewUrl = $imgView->MakeRequest($baseUrl); - -//对fopUrl 进行签名,生成privateUrl。 公有bucket 此步可以省去。 -$imgViewPrivateUrl = $getPolicy->MakeRequest($imgViewUrl, null); -echo "\n\n====> imageView privateUrl: \n"; -echo $imgViewPrivateUrl . "\n"; -``` - - -## 贡献代码 - -1. Fork -2. 创建您的特性分支 (`git checkout -b my-new-feature`) -3. 提交您的改动 (`git commit -am 'Added some feature'`) -4. 将您的修改记录提交到远程 `git` 仓库 (`git push origin my-new-feature`) -5. 然后到 github 网站的该 `git` 远程仓库的 `my-new-feature` 分支下发起 Pull Request - - - -## 许可证 - -Copyright (c) 2013 qiniu.com - -基于 MIT 协议发布: - -* [www.opensource.org/licenses/MIT](http://www.opensource.org/licenses/MIT) - - - diff --git a/docs/gist.py b/docs/gist.py deleted file mode 100755 index a09520aa..00000000 --- a/docs/gist.py +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import sys -import os -import re - -re_md_gist = re.compile(r"@gist\(([^\)]+)\)") -re_strip = re.compile(r"^\n*(.*)\n\t*$", re.S) -re_indent = re.compile(r"^(\t*)[^\t\s\n\r]") -line_start = r"(?:^|\n)\s*" -re_gist_comment = dict( - c = dict( - start = re.compile(r"%s\/\*\s*@gist\s+([\w\-_]+)\s*\*/.*?\n+" % line_start), - end = re.compile(r"%s\/\*\s*@endgist\s*\*/" % line_start), - ), - bash = dict( - start = re.compile(r"%s#\s*@gist\s+([\w\-_]+).*?\n+" % line_start), - end = re.compile(r"%s#\s*@endgist" % line_start), - ), - cpp = dict( - start = re.compile(r"%s//\s*@gist\s+([\w\-_]+).*?\n+" % line_start), - end = re.compile(r"%s//\s*@endgist" % line_start) - ), - html = dict( - start = re.compile(r"%s.*?\n+" % line_start), - end = re.compile(r"%s" % line_start), - ), -) -cpath = sys.path[0] - -def openfile(path): - if not os.path.exists(path): - return None - f = open(path, "r") - body = f.read() - f.close() - return body - -def get_gist_block(path): - gists = dict() - body = openfile(path) - if body is None: - return gists - start = 0 - while True: - a = search_one_block(body[start:]) - if a is None: - break - name, content, new_start = a - start += new_start - if not name in gists: - gists[name] = content - else: - gists[name].extend(["", "...", ""]) - gists[name].extend(content) - gists[""] = body.split("\n") - return gists - -def search_one_block(body): - if len(body) == 0: - return None - for n, regs in re_gist_comment.iteritems(): - a = regs["start"].search(body) - if a is None: - continue - start = a.span()[1] - b = regs["end"].search(body[start:]) - if b is None: - continue - break - if a is None or b is None: - return None - - body = body[start: b.span()[0]+start] - body = re_strip.sub("\\1", body) - start_indent = len(re_indent.findall(body)[0]) - body = [i[start_indent:] for i in body.split("\n")] - return a.group(1), body, b.span()[1] + start - -def dirname(path): - name = os.path.dirname(path) - if name == "": - name = "." - return name - -if __name__ == "__main__": - if len(sys.argv) <= 1: - sys.stderr.write("Usage: %s GistFile > OutputFile\n" % os.path.basename(sys.argv[0])) - exit(2) - - body = openfile(sys.argv[1]) - if body is None: - sys.stderr.write("Not such File.") - exit(2) - - rpath = dirname(sys.argv[1]) - body_gist_ref = [] - ref_files = [] - for i in re_md_gist.findall(body): - file_path = i - if i.find("#") > 0: - file_path = file_path.split("#")[0] - ref_files.append("%s/%s" % (rpath, file_path)) - body_gist_ref.append(i) - ref_files = list(set(ref_files)) - - match_gists = {} - for f in ref_files: - blocks = get_gist_block(f) - for block_key in blocks: - key = "%s#%s" % (f, block_key) - if len(block_key) == 0: - key = "%s%s" % (f, block_key) - match_gists[key] = blocks[block_key] - - errors = [] - for i in body_gist_ref: - key = "%s/%s" % (rpath, i) - if key in match_gists: - match_results = re_md_gist.search(body) - if match_results is None: - continue - s = match_results.span()[0] - s = body[body[s-50: s].rfind("\n")+s-50+1: s] - content = (("\n%s" % s).join(match_gists[key])).strip() - content = content.replace("\\", "\\\\") - - body = re.sub(r"@gist\s*\(%s\)" % i, content, body) - else: - errors.append(i) - - if len(errors) > 0: - sys.stderr.write("error: No Such File or Anchor\n") - for i, error in enumerate(errors): - sys.stderr.write("%s: '%s'\n" % (i+1, error)) - exit(2) - print body diff --git a/docs/gist/demo.php b/docs/gist/demo.php deleted file mode 100644 index b72e9e2d..00000000 --- a/docs/gist/demo.php +++ /dev/null @@ -1,258 +0,0 @@ -'; -$secretKey = ''; -Qiniu_setKeys($accessKey, $secretKey); -# @endgist -# @gist mac_client -$client = new Qiniu_MacHttpClient(null); -# @endgist - -Qiniu_RS_Delete($client, $bucket, $key1); -Qiniu_RS_Delete($client, $bucket, $key2); - -//------------------------------------io----------------------------------------- -# @gist putpolicy -$putPolicy = new Qiniu_RS_PutPolicy($bucket); -$upToken = $putPolicy->Token(null); -# @endgist - -# @gist put -list($ret, $err) = Qiniu_Put($upToken, $key1, 'Qiniu Storage!', null); -echo "\n\n====> Qiniu_Put result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} -# @endgist -Qiniu_RS_Delete($client, $bucket, $key1); - -# @gist putfile -$putExtra = new Qiniu_PutExtra(); -$putExtra->Crc32 = 1; -list($ret, $err) = Qiniu_PutFile($upToken, $key1, $file, $putExtra); -echo "\n\n====> Qiniu_PutFile result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} -# @endgist -Qiniu_RS_Delete($client, $bucket, $key1); - -# @gist getpolicy -$baseUrl = Qiniu_RS_MakeBaseUrl($domain, $key1); -$getPolicy = new Qiniu_RS_GetPolicy(); -$privateUrl = $getPolicy->MakeRequest($baseUrl, null); -echo "\n\n====> getPolicy result: \n"; -echo $privateUrl . "\n"; -# @endgist - - -//------------------------------------rio----------------------------------------- -//Qiniu_Rio_PutFile($upToken, $key1, $localFile, $putExtra) // => ($putRet, $err) -# @gist rio_putfile -$putExtra = new Qiniu_Rio_PutExtra($bucket); -list($ret, $err) = Qiniu_Rio_PutFile($upToken, $key1, $file, $putExtra); -echo "\n\n====> Qiniu_Rio_PutFile result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} -# @endgist - -//------------------------------------rs----------------------------------------- -# @gist stat -list($ret, $err) = Qiniu_RS_Stat($client, $bucket, $key1); -echo "\n\n====> Qiniu_RS_Stat result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} -# @endgist - -# @gist copy -$err = Qiniu_RS_Copy($client, $bucket, $key1, $bucket, $key2); -echo "\n\n====> Qiniu_RS_Copy result: \n"; -if ($err !== null) { - var_dump($err); -} else { - echo "Success! \n"; -} -# @endgist - -# @gist delete -$err = Qiniu_RS_Delete($client, $bucket, $key1); -echo "\n\n====> Qiniu_RS_Delete result: \n"; -if ($err !== null) { - var_dump($err); -} else { - echo "Success! \n"; -} -# @endgist - -# @gist move -$err = Qiniu_RS_Move($client, $bucket, $key2, $bucket, $key1); -echo "\n\n====> Qiniu_RS_Move result: \n"; -if ($err !== null) { - var_dump($err); -} else { - echo "Success! \n"; -} -# @endgist - -# @gist entrypath1 -$e1 = new Qiniu_RS_EntryPath($bucket, $key1); -# @endgist -# @gist entrypath2 -$e2 = new Qiniu_RS_EntryPath($bucket, $key2); -# @endgist -# @gist entrypath3 -$key3 = $key1 . '3'; -$e3 = new Qiniu_RS_EntryPath($bucket, $key3); -# @endgist - -# @gist batch_stat -$entries = array($e1, $e2); -list($ret, $err) = Qiniu_RS_BatchStat($client, $entries); -echo "\n\n====> Qiniu_RS_BatchStat result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} -# @endgist - -# @gist batch_copy -$entryPairs = array(new Qiniu_RS_EntryPathPair($e1, $e2), new Qiniu_RS_EntryPathPair($e1, $e3)); -list($ret, $err) = Qiniu_RS_BatchCopy($client, $entryPairs); -echo "\n\n====> Qiniu_RS_BatchCopy result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} -# @endgist - -# @gist batch_delete -$entries = array($e1, $e2); -list($ret, $err) = Qiniu_RS_BatchDelete($client, $entries); -echo "\n\n====> Qiniu_RS_BatchDelete result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} -# @endgist - -# @gist batch_move -$entryPairs = array(new Qiniu_RS_EntryPathPair($e3, $e1)); -list($ret, $err) = Qiniu_RS_BatchMove($client, $entryPairs); -echo "\n\n====> Qiniu_RS_BatchMove result: \n"; -if ($err !== null) { - var_dump($err); -} else { - var_dump($ret); -} -# @endgist - - -//------------------------------------rsf----------------------------------------- - -list($iterms, $markerOut, $err) = Qiniu_RSF_ListPrefix($client, $bucket); -echo "\n\n====> Qiniu_RSF result: \n"; -if ($err != null) { - if ($err === Qiniu_RSF_EOF) { - var_dump($iterms); - } else { - var_dump(err); - } -} else { - var_dump($iterms); -} - - -//------------------------------------fop----------------------------------------- -# @gist base_url -//$baseUrl 就是您要访问资源的地址 -$baseUrl = Qiniu_RS_MakeBaseUrl($domain, $key1); -# @endgist - -# @gist image_info -$getPolicy = new Qiniu_RS_GetPolicy(); -$imgInfo = new Qiniu_ImageInfo; - -//生成fopUrl -$imgInfoUrl = $imgInfo->MakeRequest($baseUrl); - -//对fopUrl 进行签名,生成privateUrl。 公有bucket 此步可以省去。 -$imgInfoPrivateUrl = $getPolicy->MakeRequest($imgInfoUrl, null); -echo "\n\n====> imageInfo privateUrl: \n"; -echo $imgInfoPrivateUrl . "\n"; -# @endgist - -# @gist image_exif -$getPolicy = new Qiniu_RS_GetPolicy(); -$imgExif = new Qiniu_Exif; - -//生成fopUrl -$imgExifUrl = $imgExif->MakeRequest($baseUrl); -//对fopUrl 进行签名,生成privateUrl。 公有bucket 此步可以省去。 -$imgExifPrivateUrl = $getPolicy->MakeRequest($imgExifUrl, null); -echo "\n\n====> imageView privateUrl: \n"; -echo $imgExifPrivateUrl . "\n"; -# @endgist - -# @gist image_view -$getPolicy = new Qiniu_RS_GetPolicy(); -$imgView = new Qiniu_ImageView; -$imgView->Mode = 1; -$imgView->Width = 60; -$imgView->Height = 30; - -//生成fopUrl -$imgViewUrl = $imgView->MakeRequest($baseUrl); - -//对fopUrl 进行签名,生成privateUrl。 公有bucket 此步可以省去。 -$imgViewPrivateUrl = $getPolicy->MakeRequest($imgViewUrl, null); -echo "\n\n====> imageView privateUrl: \n"; -echo $imgViewPrivateUrl . "\n"; -# @endgist - - diff --git a/docs/gist/fetch.php b/docs/gist/fetch.php deleted file mode 100644 index 3514eca3..00000000 --- a/docs/gist/fetch.php +++ /dev/null @@ -1,32 +0,0 @@ - + + + + tests + + + + diff --git a/qiniu/auth_digest.php b/qiniu/auth_digest.php deleted file mode 100644 index 907acdbd..00000000 --- a/qiniu/auth_digest.php +++ /dev/null @@ -1,100 +0,0 @@ -AccessKey = $accessKey; - $this->SecretKey = $secretKey; - } - - public function Sign($data) // => $token - { - $sign = hash_hmac('sha1', $data, $this->SecretKey, true); - return $this->AccessKey . ':' . Qiniu_Encode($sign); - } - - public function SignWithData($data) // => $token - { - $data = Qiniu_Encode($data); - return $this->Sign($data) . ':' . $data; - } - - public function SignRequest($req, $incbody) // => ($token, $error) - { - $url = $req->URL; - $url = parse_url($url['path']); - $data = ''; - if (isset($url['path'])) { - $data = $url['path']; - } - if (isset($url['query'])) { - $data .= '?' . $url['query']; - } - $data .= "\n"; - - if ($incbody) { - $data .= $req->Body; - } - return $this->Sign($data); - } - - public function VerifyCallback($auth, $url, $body) // ==> bool - { - $url = parse_url($url); - $data = ''; - if (isset($url['path'])) { - $data = $url['path']; - } - if (isset($url['query'])) { - $data .= '?' . $url['query']; - } - $data .= "\n"; - - $data .= $body; - $token = 'QBox ' . $this->Sign($data); - return $auth === $token; - } -} - -function Qiniu_SetKeys($accessKey, $secretKey) -{ - global $QINIU_ACCESS_KEY; - global $QINIU_SECRET_KEY; - - $QINIU_ACCESS_KEY = $accessKey; - $QINIU_SECRET_KEY = $secretKey; -} - -function Qiniu_RequireMac($mac) // => $mac -{ - if (isset($mac)) { - return $mac; - } - - global $QINIU_ACCESS_KEY; - global $QINIU_SECRET_KEY; - - return new Qiniu_Mac($QINIU_ACCESS_KEY, $QINIU_SECRET_KEY); -} - -function Qiniu_Sign($mac, $data) // => $token -{ - return Qiniu_RequireMac($mac)->Sign($data); -} - -function Qiniu_SignWithData($mac, $data) // => $token -{ - return Qiniu_RequireMac($mac)->SignWithData($data); -} - -// ---------------------------------------------------------- - diff --git a/qiniu/conf.php b/qiniu/conf.php deleted file mode 100644 index f24bfc6b..00000000 --- a/qiniu/conf.php +++ /dev/null @@ -1,20 +0,0 @@ -'; -$QINIU_SECRET_KEY = ''; diff --git a/qiniu/fop.php b/qiniu/fop.php deleted file mode 100644 index 018c3f73..00000000 --- a/qiniu/fop.php +++ /dev/null @@ -1,58 +0,0 @@ -Mode); - - if (!empty($this->Width)) { - $ops[] = 'w/' . $this->Width; - } - if (!empty($this->Height)) { - $ops[] = 'h/' . $this->Height; - } - if (!empty($this->Quality)) { - $ops[] = 'q/' . $this->Quality; - } - if (!empty($this->Format)) { - $ops[] = 'format/' . $this->Format; - } - - return $url . "?imageView/" . implode('/', $ops); - } -} - -// -------------------------------------------------------------------------------- -// class Qiniu_Exif - -class Qiniu_Exif { - - public function MakeRequest($url) - { - return $url . "?exif"; - } - -} - -// -------------------------------------------------------------------------------- -// class Qiniu_ImageInfo - -class Qiniu_ImageInfo { - - public function MakeRequest($url) - { - return $url . "?imageInfo"; - } - -} diff --git a/qiniu/http.php b/qiniu/http.php deleted file mode 100644 index 87314b81..00000000 --- a/qiniu/http.php +++ /dev/null @@ -1,340 +0,0 @@ -Code = $code; - $this->Err = $err; - } -} - -// -------------------------------------------------------------------------------- -// class Qiniu_Request - -class Qiniu_Request -{ - public $URL; - public $Header; - public $Body; - public $UA; - - public function __construct($url, $body) - { - $this->URL = $url; - $this->Header = array(); - $this->Body = $body; - $this->UA = Qiniu_UserAgent(); - } -} - -// -------------------------------------------------------------------------------- -// class Qiniu_Response - -class Qiniu_Response -{ - public $StatusCode; - public $Header; - public $ContentLength; - public $Body; - - public function __construct($code, $body) - { - $this->StatusCode = $code; - $this->Header = array(); - $this->Body = $body; - $this->ContentLength = strlen($body); - } -} - -// -------------------------------------------------------------------------------- -// class Qiniu_Header - -function Qiniu_Header_Get($header, $key) // => $val -{ - $val = @$header[$key]; - if (isset($val)) { - if (is_array($val)) { - return $val[0]; - } - return $val; - } else { - return ''; - } -} - -function Qiniu_ResponseError($resp) // => $error -{ - $header = $resp->Header; - $details = Qiniu_Header_Get($header, 'X-Log'); - $reqId = Qiniu_Header_Get($header, 'X-Reqid'); - $err = new Qiniu_Error($resp->StatusCode, null); - - if ($err->Code > 299) { - if ($resp->ContentLength !== 0) { - if (Qiniu_Header_Get($header, 'Content-Type') === 'application/json') { - $ret = json_decode($resp->Body, true); - $err->Err = $ret['error']; - } - } - } - $err->Reqid = $reqId; - $err->Details = $details; - return $err; -} - -// -------------------------------------------------------------------------------- -// class Qiniu_Client - -function Qiniu_Client_incBody($req) // => $incbody -{ - $body = $req->Body; - if (!isset($body)) { - return false; - } - - $ct = Qiniu_Header_Get($req->Header, 'Content-Type'); - if ($ct === 'application/x-www-form-urlencoded') { - return true; - } - return false; -} - -function Qiniu_Client_do($req) // => ($resp, $error) -{ - $ch = curl_init(); - $url = $req->URL; - $options = array( - CURLOPT_USERAGENT => $req->UA, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_SSL_VERIFYPEER => false, - CURLOPT_SSL_VERIFYHOST => false, - CURLOPT_HEADER => true, - CURLOPT_NOBODY => false, - CURLOPT_CUSTOMREQUEST => 'POST', - CURLOPT_URL => $url['path'] - ); - $httpHeader = $req->Header; - if (!empty($httpHeader)) - { - $header = array(); - foreach($httpHeader as $key => $parsedUrlValue) { - $header[] = "$key: $parsedUrlValue"; - } - $options[CURLOPT_HTTPHEADER] = $header; - } - $body = $req->Body; - if (!empty($body)) { - $options[CURLOPT_POSTFIELDS] = $body; - } else { - $options[CURLOPT_POSTFIELDS] = ""; - } - curl_setopt_array($ch, $options); - $result = curl_exec($ch); - $ret = curl_errno($ch); - if ($ret !== 0) { - $err = new Qiniu_Error(0, curl_error($ch)); - curl_close($ch); - return array(null, $err); - } - $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); - $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); - curl_close($ch); - - $responseArray = explode("\r\n\r\n", $result); - $responseArraySize = sizeof($responseArray); - $respHeader = $responseArray[$responseArraySize-2]; - $respBody = $responseArray[$responseArraySize-1]; - - list($reqid, $xLog) = getReqInfo($respHeader); - - $resp = new Qiniu_Response($code, $respBody); - $resp->Header['Content-Type'] = $contentType; - $resp->Header["X-Reqid"] = $reqid; - return array($resp, null); -} - -function getReqInfo($headerContent) { - $headers = explode("\r\n", $headerContent); - $reqid = null; - $xLog = null; - foreach($headers as $header) { - $header = trim($header); - if(strpos($header, 'X-Reqid') !== false) { - list($k, $v) = explode(':', $header); - $reqid = trim($v); - } elseif(strpos($header, 'X-Log') !== false) { - list($k, $v) = explode(':', $header); - $xLog = trim($v); - } - } - return array($reqid, $xLog); -} - -class Qiniu_HttpClient -{ - public function RoundTrip($req) // => ($resp, $error) - { - return Qiniu_Client_do($req); - } -} - -class Qiniu_MacHttpClient -{ - public $Mac; - - public function __construct($mac) - { - $this->Mac = Qiniu_RequireMac($mac); - } - - public function RoundTrip($req) // => ($resp, $error) - { - $incbody = Qiniu_Client_incBody($req); - $token = $this->Mac->SignRequest($req, $incbody); - $req->Header['Authorization'] = "QBox $token"; - return Qiniu_Client_do($req); - } -} - -// -------------------------------------------------------------------------------- - -function Qiniu_Client_ret($resp) // => ($data, $error) -{ - $code = $resp->StatusCode; - $data = null; - if ($code >= 200 && $code <= 299) { - if ($resp->ContentLength !== 0) { - $data = json_decode($resp->Body, true); - if ($data === null) { - $err_msg = function_exists('json_last_error_msg') ? json_last_error_msg() : "error with content:" . $resp->Body; - $err = new Qiniu_Error(0, $err_msg); - return array(null, $err); - } - } - if ($code === 200) { - return array($data, null); - } - } - return array($data, Qiniu_ResponseError($resp)); -} - -function Qiniu_Client_Call($self, $url) // => ($data, $error) -{ - $u = array('path' => $url); - $req = new Qiniu_Request($u, null); - list($resp, $err) = $self->RoundTrip($req); - if ($err !== null) { - return array(null, $err); - } - return Qiniu_Client_ret($resp); -} - -function Qiniu_Client_CallNoRet($self, $url) // => $error -{ - $u = array('path' => $url); - $req = new Qiniu_Request($u, null); - list($resp, $err) = $self->RoundTrip($req); - if ($err !== null) { - return array(null, $err); - } - if ($resp->StatusCode === 200) { - return null; - } - return Qiniu_ResponseError($resp); -} - -function Qiniu_Client_CallWithForm( - $self, $url, $params, $contentType = 'application/x-www-form-urlencoded') // => ($data, $error) -{ - $u = array('path' => $url); - if ($contentType === 'application/x-www-form-urlencoded') { - if (is_array($params)) { - $params = http_build_query($params); - } - } - $req = new Qiniu_Request($u, $params); - if ($contentType !== 'multipart/form-data') { - $req->Header['Content-Type'] = $contentType; - } - list($resp, $err) = $self->RoundTrip($req); - if ($err !== null) { - return array(null, $err); - } - return Qiniu_Client_ret($resp); -} - -// -------------------------------------------------------------------------------- - -function Qiniu_Client_CallWithMultipartForm($self, $url, $fields, $files) -{ - list($contentType, $body) = Qiniu_Build_MultipartForm($fields, $files); - return Qiniu_Client_CallWithForm($self, $url, $body, $contentType); -} - -function Qiniu_Build_MultipartForm($fields, $files) // => ($contentType, $body) -{ - $data = array(); - $mimeBoundary = md5(microtime()); - - foreach ($fields as $name => $val) { - array_push($data, '--' . $mimeBoundary); - array_push($data, "Content-Disposition: form-data; name=\"$name\""); - array_push($data, ''); - array_push($data, $val); - } - - foreach ($files as $file) { - array_push($data, '--' . $mimeBoundary); - list($name, $fileName, $fileBody, $mimeType) = $file; - $mimeType = empty($mimeType) ? 'application/octet-stream' : $mimeType; - $fileName = Qiniu_escapeQuotes($fileName); - array_push($data, "Content-Disposition: form-data; name=\"$name\"; filename=\"$fileName\""); - array_push($data, "Content-Type: $mimeType"); - array_push($data, ''); - array_push($data, $fileBody); - } - - array_push($data, '--' . $mimeBoundary . '--'); - array_push($data, ''); - - $body = implode("\r\n", $data); - $contentType = 'multipart/form-data; boundary=' . $mimeBoundary; - return array($contentType, $body); -} - -function Qiniu_UserAgent() { - global $SDK_VER; - $sdkInfo = "QiniuPHP/$SDK_VER"; - - $systemInfo = php_uname("s"); - $machineInfo = php_uname("m"); - - $envInfo = "($systemInfo/$machineInfo)"; - - $phpVer = phpversion(); - - $ua = "$sdkInfo $envInfo PHP/$phpVer"; - return $ua; -} - -function Qiniu_escapeQuotes($str) -{ - $find = array("\\", "\""); - $replace = array("\\\\", "\\\""); - return str_replace($find, $replace, $str); -} - -// -------------------------------------------------------------------------------- - diff --git a/qiniu/io.php b/qiniu/io.php deleted file mode 100644 index d150938a..00000000 --- a/qiniu/io.php +++ /dev/null @@ -1,95 +0,0 @@ - ($putRet, $err) -{ - global $QINIU_UP_HOST; - - if ($putExtra === null) { - $putExtra = new Qiniu_PutExtra; - } - - $fields = array('token' => $upToken); - if ($key === null) { - $fname = '?'; - } else { - $fname = $key; - $fields['key'] = $key; - } - if ($putExtra->CheckCrc) { - $fields['crc32'] = $putExtra->Crc32; - } - if ($putExtra->Params) { - foreach ($putExtra->Params as $k=>$v) { - $fields[$k] = $v; - } - } - - $files = array(array('file', $fname, $body, $putExtra->MimeType)); - - $client = new Qiniu_HttpClient; - return Qiniu_Client_CallWithMultipartForm($client, $QINIU_UP_HOST, $fields, $files); -} - -function createFile($filename, $mime) -{ - // PHP 5.5 introduced a CurlFile object that deprecates the old @filename syntax - // See: https://wiki.php.net/rfc/curl-file-upload - if (function_exists('curl_file_create')) { - return curl_file_create($filename, $mime); - } - - // Use the old style if using an older version of PHP - $value = "@{$filename}"; - if (!empty($mime)) { - $value .= ';type=' . $mime; - } - - return $value; -} - -function Qiniu_PutFile($upToken, $key, $localFile, $putExtra) // => ($putRet, $err) -{ - global $QINIU_UP_HOST; - - if ($putExtra === null) { - $putExtra = new Qiniu_PutExtra; - } - - $fields = array('token' => $upToken, 'file' => createFile($localFile, $putExtra->MimeType)); - if ($key !== null) { - $fields['key'] = $key; - } - if ($putExtra->CheckCrc) { - if ($putExtra->CheckCrc === 1) { - $hash = hash_file('crc32b', $localFile); - $array = unpack('N', pack('H*', $hash)); - $putExtra->Crc32 = $array[1]; - } - $fields['crc32'] = sprintf('%u', $putExtra->Crc32); - } - if ($putExtra->Params) { - foreach ($putExtra->Params as $k=>$v) { - $fields[$k] = $v; - } - } - - $client = new Qiniu_HttpClient; - return Qiniu_Client_CallWithForm($client, $QINIU_UP_HOST, $fields, 'multipart/form-data'); -} - -// ---------------------------------------------------------- - diff --git a/qiniu/pfop.php b/qiniu/pfop.php deleted file mode 100644 index cd1a4db6..00000000 --- a/qiniu/pfop.php +++ /dev/null @@ -1,48 +0,0 @@ - $this->Bucket, - 'key' => $this->Key, - 'fops' => $this->Fops, - 'notifyURL' => $this->NotifyURL, - 'force' => $this->Force, - 'pipeline' => $this->Pipeline - ); - - $url = $QINIU_API_HOST . '/pfop/'; - - return Qiniu_Client_CallWithForm($self, $url, $ReqParams); - } - -} - -function Qiniu_PfopStatus($client, $id) -{ - global $QINIU_API_HOST; - - $url = $QINIU_API_HOST . '/status/get/prefop?'; - $params = array('id' => $id); - - return Qiniu_Client_CallWithForm($client, $url, $params); -} - - - diff --git a/qiniu/resumable_io.php b/qiniu/resumable_io.php deleted file mode 100644 index fa83c8c3..00000000 --- a/qiniu/resumable_io.php +++ /dev/null @@ -1,167 +0,0 @@ -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 = new Qiniu_Error(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 = new Qiniu_Error(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) -{ - $url = $host . '/mkfile/' . $fsize; - if ($key !== null) { - $url .= '/key/' . Qiniu_Encode($key); - } - if (!empty($extra->MimeType)) { - $url .= '/mimeType/' . Qiniu_Encode($extra->MimeType); - } - - if (!empty($extra->Params)) { - foreach ($extra->Params as $k=>$v) { - $url .= "/" . $k . "/" . Qiniu_Encode($v); - } - } - - $ctxs = array(); - foreach ($extra->Progresses as $prog) { - $ctxs []= $prog['ctx']; - } - $body = implode(',', $ctxs); - - return Qiniu_Client_CallWithForm($self, $url, $body, 'application/octet-stream'); -} - -// ---------------------------------------------------------- -// 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(); - $uploaded = 0; - while ($uploaded < $fsize) { - $tried = 0; - $tryTimes = ($putExtra->TryTimes > 0) ? $putExtra->TryTimes : 1; - $blkputRet = null; - $err = null; - if ($fsize < $uploaded + QINIU_RIO_BLOCK_SIZE) { - $bsize = $fsize - $uploaded; - } else { - $bsize = QINIU_RIO_BLOCK_SIZE; - } - while ($tried < $tryTimes) { - list($blkputRet, $err) = Qiniu_Rio_Mkblock($self, $QINIU_UP_HOST, $body, $bsize); - if ($err === null) { - break; - } - $tried += 1; - continue; - } - if ($err !== null) { - return array(null, $err); - } - if ($blkputRet === null ) { - $err = new Qiniu_Error(0, "rio: uploaded without ret"); - return array(null, $err); - } - $uploaded += $bsize; - $progresses []= $blkputRet; - } - - $putExtra->Progresses = $progresses; - return Qiniu_Rio_Mkfile($self, $QINIU_UP_HOST, $key, $fsize, $putExtra); -} - -function Qiniu_Rio_PutFile($upToken, $key, $localFile, $putExtra) // => ($putRet, $err) -{ - $fp = fopen($localFile, 'rb'); - if ($fp === false) { - $err = new Qiniu_Error(0, 'fopen failed'); - return array(null, $err); - } - - $fi = fstat($fp); - $result = Qiniu_Rio_Put($upToken, $key, $fp, $fi['size'], $putExtra); - fclose($fp); - return $result; -} - -// ---------------------------------------------------------- - diff --git a/qiniu/rs.php b/qiniu/rs.php deleted file mode 100644 index 443ca377..00000000 --- a/qiniu/rs.php +++ /dev/null @@ -1,273 +0,0 @@ - $privateUrl - { - $deadline = $this->Expires; - if ($deadline == 0) { - $deadline = 3600; - } - $deadline += time(); - - $pos = strpos($baseUrl, '?'); - if ($pos !== false) { - $baseUrl .= '&e='; - } else { - $baseUrl .= '?e='; - } - $baseUrl .= $deadline; - - $token = Qiniu_Sign($mac, $baseUrl); - return "$baseUrl&token=$token"; - } -} - -function Qiniu_RS_MakeBaseUrl($domain, $key) // => $baseUrl -{ - $keyEsc = str_replace("%2F", "/", rawurlencode($key)); - return "http://$domain/$keyEsc"; -} - -// -------------------------------------------------------------------------------- -// class Qiniu_RS_PutPolicy - -class Qiniu_RS_PutPolicy -{ - public $Scope; //必填 - public $Expires; //默认为3600s - public $CallbackUrl; - public $CallbackBody; - public $ReturnUrl; - public $ReturnBody; - public $AsyncOps; - public $EndUser; - public $InsertOnly; //若非0,则任何情况下无法覆盖上传 - public $DetectMime; //若非0,则服务端根据内容自动确定MimeType - public $FsizeLimit; - public $SaveKey; - public $PersistentOps; - public $PersistentPipeline; - public $PersistentNotifyUrl; - public $FopTimeout; - public $MimeLimit; - - public function __construct($scope) - { - $this->Scope = $scope; - } - - public function Token($mac) // => $token - { - $deadline = $this->Expires; - if ($deadline == 0) { - $deadline = 3600; - } - $deadline += time(); - - $policy = array('scope' => $this->Scope, 'deadline' => $deadline); - if (!empty($this->CallbackUrl)) { - $policy['callbackUrl'] = $this->CallbackUrl; - } - if (!empty($this->CallbackBody)) { - $policy['callbackBody'] = $this->CallbackBody; - } - if (!empty($this->ReturnUrl)) { - $policy['returnUrl'] = $this->ReturnUrl; - } - if (!empty($this->ReturnBody)) { - $policy['returnBody'] = $this->ReturnBody; - } - if (!empty($this->AsyncOps)) { - $policy['asyncOps'] = $this->AsyncOps; - } - if (!empty($this->EndUser)) { - $policy['endUser'] = $this->EndUser; - } - if (isset($this->InsertOnly)) { - $policy['insertOnly'] = $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->PersistentPipeline)) { - $policy['persistentPipeline'] = $this->PersistentPipeline; - } - if (!empty($this->PersistentNotifyUrl)) { - $policy['persistentNotifyUrl'] = $this->PersistentNotifyUrl; - } - if (!empty($this->FopTimeout)) { - $policy['fopTimeout'] = $this->FopTimeout; - } - if (!empty($this->MimeLimit)) { - $policy['mimeLimit'] = $this->MimeLimit; - } - - - $b = json_encode($policy); - return Qiniu_SignWithData($mac, $b); - } -} - -// ---------------------------------------------------------- -// class Qiniu_RS_EntryPath - -class Qiniu_RS_EntryPath -{ - public $bucket; - public $key; - - public function __construct($bucket, $key) - { - $this->bucket = $bucket; - $this->key = $key; - } -} - -// ---------------------------------------------------------- -// class Qiniu_RS_EntryPathPair - -class Qiniu_RS_EntryPathPair -{ - public $src; - public $dest; - - public function __construct($src, $dest) - { - $this->src = $src; - $this->dest = $dest; - } -} - -// ---------------------------------------------------------- - -function Qiniu_RS_URIStat($bucket, $key) -{ - return '/stat/' . Qiniu_Encode("$bucket:$key"); -} - -function Qiniu_RS_URIDelete($bucket, $key) -{ - return '/delete/' . Qiniu_Encode("$bucket:$key"); -} - -function Qiniu_RS_URICopy($bucketSrc, $keySrc, $bucketDest, $keyDest) -{ - return '/copy/' . Qiniu_Encode("$bucketSrc:$keySrc") . '/' . Qiniu_Encode("$bucketDest:$keyDest"); -} - -function Qiniu_RS_URIMove($bucketSrc, $keySrc, $bucketDest, $keyDest) -{ - return '/move/' . Qiniu_Encode("$bucketSrc:$keySrc") . '/' . Qiniu_Encode("$bucketDest:$keyDest"); -} - -// ---------------------------------------------------------- - -function Qiniu_RS_Stat($self, $bucket, $key) // => ($statRet, $error) -{ - global $QINIU_RS_HOST; - $uri = Qiniu_RS_URIStat($bucket, $key); - return Qiniu_Client_Call($self, $QINIU_RS_HOST . $uri); -} - -function Qiniu_RS_Delete($self, $bucket, $key) // => $error -{ - global $QINIU_RS_HOST; - $uri = Qiniu_RS_URIDelete($bucket, $key); - return Qiniu_Client_CallNoRet($self, $QINIU_RS_HOST . $uri); -} - -function Qiniu_RS_Move($self, $bucketSrc, $keySrc, $bucketDest, $keyDest) // => $error -{ - global $QINIU_RS_HOST; - $uri = Qiniu_RS_URIMove($bucketSrc, $keySrc, $bucketDest, $keyDest); - return Qiniu_Client_CallNoRet($self, $QINIU_RS_HOST . $uri); -} - -function Qiniu_RS_Copy($self, $bucketSrc, $keySrc, $bucketDest, $keyDest) // => $error -{ - global $QINIU_RS_HOST; - $uri = Qiniu_RS_URICopy($bucketSrc, $keySrc, $bucketDest, $keyDest); - return Qiniu_Client_CallNoRet($self, $QINIU_RS_HOST . $uri); -} - -// ---------------------------------------------------------- -// batch - -function Qiniu_RS_Batch($self, $ops) // => ($data, $error) -{ - global $QINIU_RS_HOST; - $url = $QINIU_RS_HOST . '/batch'; - $params = 'op=' . implode('&op=', $ops); - return Qiniu_Client_CallWithForm($self, $url, $params); -} - -function Qiniu_RS_BatchStat($self, $entryPaths) -{ - $params = array(); - foreach ($entryPaths as $entryPath) { - $params[] = Qiniu_RS_URIStat($entryPath->bucket, $entryPath->key); - } - return Qiniu_RS_Batch($self,$params); -} - -function Qiniu_RS_BatchDelete($self, $entryPaths) -{ - $params = array(); - foreach ($entryPaths as $entryPath) { - $params[] = Qiniu_RS_URIDelete($entryPath->bucket, $entryPath->key); - } - return Qiniu_RS_Batch($self, $params); -} - -function Qiniu_RS_BatchMove($self, $entryPairs) -{ - $params = array(); - foreach ($entryPairs as $entryPair) { - $src = $entryPair->src; - $dest = $entryPair->dest; - $params[] = Qiniu_RS_URIMove($src->bucket, $src->key, $dest->bucket, $dest->key); - } - return Qiniu_RS_Batch($self, $params); -} - -function Qiniu_RS_BatchCopy($self, $entryPairs) -{ - $params = array(); - foreach ($entryPairs as $entryPair) { - $src = $entryPair->src; - $dest = $entryPair->dest; - $params[] = Qiniu_RS_URICopy($src->bucket, $src->key, $dest->bucket, $dest->key); - } - return Qiniu_RS_Batch($self, $params); -} - -// ---------------------------------------------------------- -// fetch -function Qiniu_RS_Fetch($self, $url, $bucket, $key) -{ - - global $QINIU_IOVIP_HOST; - $path = '/fetch/' . Qiniu_Encode($url) . '/to/' . Qiniu_Encode("$bucket:$key"); - return Qiniu_Client_CallNoRet($self, $QINIU_IOVIP_HOST . $path); -} - - -// ---------------------------------------------------------- - diff --git a/qiniu/rs_utils.php b/qiniu/rs_utils.php deleted file mode 100644 index 15343d62..00000000 --- a/qiniu/rs_utils.php +++ /dev/null @@ -1,44 +0,0 @@ - ($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) // => ($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); -} - diff --git a/qiniu/rsf.php b/qiniu/rsf.php deleted file mode 100644 index 9d62be66..00000000 --- a/qiniu/rsf.php +++ /dev/null @@ -1,43 +0,0 @@ - ($items, $markerOut, $err) -{ - global $QINIU_RSF_HOST; - - $query = array('bucket' => $bucket); - if (!empty($prefix)) { - $query['prefix'] = $prefix; - } - if (!empty($marker)) { - $query['marker'] = $marker; - } - if (!empty($limit)) { - $query['limit'] = $limit; - } - - $url = $QINIU_RSF_HOST . '/list?' . http_build_query($query); - list($ret, $err) = Qiniu_Client_Call($self, $url); - if ($err !== null) { - return array(null, '', $err); - } - - $items = $ret['items']; - if (empty($ret['marker'])) { - $markerOut = ''; - $err = Qiniu_RSF_EOF; - } else { - $markerOut = $ret['marker']; - } - return array($items, $markerOut, $err); -} - diff --git a/qiniu/utils.php b/qiniu/utils.php deleted file mode 100644 index 4058865f..00000000 --- a/qiniu/utils.php +++ /dev/null @@ -1,16 +0,0 @@ -accessKey = $accessKey; + $this->secretKey = $secretKey; + } + + public function token($data) + { + $hmac = hash_hmac('sha1', $data, $this->secretKey, true); + return $this->accessKey . ':' . \Qiniu\base64_urlSafeEncode($hmac); + } + + public function tokenWithData($data) + { + $data = \Qiniu\base64_urlSafeEncode($data); + return $this->token($data) . ':' . $data; + } + + public function tokenOfRequest($urlString, $body, $contentType = null) + { + $url = parse_url($urlString); + $data = ''; + if (isset($url['path'])) { + $data = $url['path']; + } + if (isset($url['query'])) { + $data .= '?' . $url['query']; + } + $data .= "\n"; + + if ($body != null && + ($contentType == 'application/x-www-form-urlencoded') || $contentType == 'application/json') { + $data .= $body; + } + return $this->token($data); + } + + public function verifyCallback($contentType, $originAuthorization, $url, $body) + { + $authorization = 'QBox ' . $this->tokenOfRequest($url, $body, $contentType); + return $originAuthorization === $authorization; + } + + public function privateDownloadUrl($baseUrl, $expires = 3600) + { + $deadline = time() + $expires; + + $pos = strpos($baseUrl, '?'); + if ($pos !== false) { + $baseUrl .= '&e='; + } else { + $baseUrl .= '?e='; + } + $baseUrl .= $deadline; + + $token = $this->token($baseUrl); + return "$baseUrl&token=$token"; + } + + public function uploadToken( + $bucket, + $key = null, + $expires = 3600, + $policy = null, + $strictPolicy = true + ) { + $deadline = time() + $expires; + $scope = $bucket; + if ($key != null) { + $scope .= ':' . $key; + } + $args = array('scope' => $scope, 'deadline' => $deadline); + self::copyPolicy($args, $policy, $strictPolicy); + $b = json_encode($args); + return $this->tokenWithData($b); + } + + private static $policyFields = array( + 'callbackUrl', + 'callbackBody', + 'callbackHost', + 'callbackBodyType', + 'callbackFetchKey', + + 'returnUrl', + 'returnBody', + + 'endUser', + 'saveKey', + 'insertOnly', + + 'detectMime', + 'mimeLimit', + 'fsizeLimit', + + 'persistentOps', + 'persistentNotifyUrl', + 'persistentPipeline', + ); + + private static $deprecatedPolicyFields = array( + 'asyncOps', + ); + + private static function copyPolicy($policy, $originPolicy, $strictPolicy) + { + if ($originPolicy == null) { + return; + } + foreach ($originPolicy as $key => $value) { + if (in_array($key, self::$deprecatedPolicyFields)) { + throw new \InvalidArgumentException("{$key} has deprecated"); + } + if (!$strictPolicy || in_array($key, self::$policyFields)) { + $policy[$key] = $value; + } + } + } + + public function authorization($url, $body = null, $contentType = null) + { + $authorization = 'QBox ' . $this->tokenOfRequest($url, $body, $contentType); + return array('Authorization' => $authorization); + } +} diff --git a/src/Qiniu/Config.php b/src/Qiniu/Config.php new file mode 100644 index 00000000..85baf866 --- /dev/null +++ b/src/Qiniu/Config.php @@ -0,0 +1,22 @@ + $val) { + array_push($data, '--' . $mimeBoundary); + array_push($data, "Content-Disposition: form-data; name=\"$key\""); + array_push($data, ''); + array_push($data, $val); + } + + array_push($data, '--' . $mimeBoundary); + $mimeType = empty($mimeType) ? 'application/octet-stream' : $mimeType; + $fileName = self::escapeQuotes($fileName); + array_push($data, "Content-Disposition: form-data; name=\"$name\"; filename=\"$fileName\""); + array_push($data, "Content-Type: $mimeType"); + array_push($data, ''); + array_push($data, $fileBody); + + array_push($data, '--' . $mimeBoundary . '--'); + array_push($data, ''); + + $body = implode("\r\n", $data); + $contentType = 'multipart/form-data; boundary=' . $mimeBoundary; + $headers['Content-Type'] = $contentType; + $request = new Request('POST', $url, $headers, $body); + return self::sendRequest($request); + } + + private static function userAgent() + { + $sdkInfo = "QiniuPHP/" . Config::SDK_VER; + + $systemInfo = php_uname("s"); + $machineInfo = php_uname("m"); + + $envInfo = "($systemInfo/$machineInfo)"; + + $phpVer = phpversion(); + + $ua = "$sdkInfo $envInfo PHP/$phpVer"; + return $ua; + } + + private static function sendRequest($request) + { + $t1 = microtime(true); + $ch = curl_init(); + $options = array( + CURLOPT_USERAGENT => self::userAgent(), + CURLOPT_RETURNTRANSFER => true, + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_SSL_VERIFYHOST => false, + CURLOPT_HEADER => true, + CURLOPT_NOBODY => false, + CURLOPT_CUSTOMREQUEST => $request->method, + CURLOPT_URL => $request->url + ); + if (!empty($request->headers)) { + $headers = array(); + foreach ($request->headers as $key => $val) { + array_push($headers, "$key: $val"); + } + $options[CURLOPT_HTTPHEADER] = $headers; + } + + if (!empty($request->body)) { + $options[CURLOPT_POSTFIELDS] = $request->body; + } + curl_setopt_array($ch, $options); + $result = curl_exec($ch); + $t2 = microtime(true); + $duration = round($t2-$t1, 3); + $ret = curl_errno($ch); + if ($ret !== 0) { + $r = new Response(-1, $duration, array(), null, curl_error($ch)); + curl_close($ch); + return $r; + } + $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); + $headers = self::parseHeaders(substr($result, 0, $header_size)); + $body = substr($result, $header_size); + curl_close($ch); + return new Response($code, $duration, $headers, $body, null); + } + + private static function parseHeaders($raw) + { + $headers = array(); + $headerLines = explode("\r\n", $raw); + foreach ($headerLines as $line) { + $headerLine = trim($line); + $kv = explode(':', $headerLine); + if (count($kv) >1) { + $headers[$kv[0]] = trim($kv[1]); + } + } + return $headers; + } + + private static function escapeQuotes($str) + { + $find = array("\\", "\""); + $replace = array("\\\\", "\\\""); + return str_replace($find, $replace, $str); + } +} diff --git a/src/Qiniu/Http/Error.php b/src/Qiniu/Http/Error.php new file mode 100644 index 00000000..a285a5d3 --- /dev/null +++ b/src/Qiniu/Http/Error.php @@ -0,0 +1,29 @@ +url = $url; + $this->response = $response; + } + + public function code() + { + return $this->response->statusCode; + } + + public function getResponse() + { + return $this->response; + } + + public function message() + { + return $this->response->error; + } +} diff --git a/src/Qiniu/Http/Request.php b/src/Qiniu/Http/Request.php new file mode 100644 index 00000000..43b0bfdb --- /dev/null +++ b/src/Qiniu/Http/Request.php @@ -0,0 +1,18 @@ +method = strtoupper($method); + $this->url = $url; + $this->headers = $headers; + $this->body = $body; + } +} diff --git a/src/Qiniu/Http/Response.php b/src/Qiniu/Http/Response.php new file mode 100644 index 00000000..8daebdeb --- /dev/null +++ b/src/Qiniu/Http/Response.php @@ -0,0 +1,167 @@ + 'Continue', + 101 => 'Switching Protocols', + 102 => 'Processing', + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 207 => 'Multi-Status', + 208 => 'Already Reported', + 226 => 'IM Used', + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 307 => 'Temporary Redirect', + 308 => 'Permanent Redirect', + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested Range Not Satisfiable', + 417 => 'Expectation Failed', + 422 => 'Unprocessable Entity', + 423 => 'Locked', + 424 => 'Failed Dependency', + 425 => 'Reserved for WebDAV advanced collections expired proposal', + 426 => 'Upgrade required', + 428 => 'Precondition Required', + 429 => 'Too Many Requests', + 431 => 'Request Header Fields Too Large', + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported', + 506 => 'Variant Also Negotiates (Experimental)', + 507 => 'Insufficient Storage', + 508 => 'Loop Detected', + 510 => 'Not Extended', + 511 => 'Network Authentication Required', + ); + + public function __construct($code, $duration, array $headers = array(), $body = null, $error = null) + { + $this->statusCode = $code; + $this->duration = $duration; + $this->headers = $headers; + $this->body = $body; + $this->error = $error; + $this->jsonData = null; + if ($error != null) { + return; + } + + if ($body == null) { + if ($code != 200) { + $this->error = self::$statusTexts[$code]; + } + return; + } + if ($headers['Content-Type'] == 'application/json') { + try { + $jsonData = self::bodyJson($body); + if ($code >=400) { + if ($jsonData['error'] != null) { + $this->error = $jsonData['error']; + } else { + $this->error = $body; + } + } + $this->jsonData = $jsonData; + } catch (\InvalidArgumentException $e) { + if ($code >= 200 && $code < 300) { + $this->error = $e->getMessage(); + } else { + $this->error = $body; + } + } + } elseif ($code >=400) { + $this->error = $body; + } + } + + public function json(array $config = array()) + { + if ($this->jsonData != null) { + return $this->jsonData; + } + return self::bodyJson($this->body); + } + + private static function bodyJson($body, array $config = array()) + { + return \Qiniu\json_decode( + (string) $body, + isset($config['object']) ? !$config['object'] : true, + 512, + isset($config['big_int_strings']) ? JSON_BIGINT_AS_STRING : 0 + ); + } + + public function xVia() + { + $via = $this->headers['X-Via']; + if ($via == null) { + $via = $this->headers['X-Px']; + } + if ($via == null) { + $via = $this->headers['Fw-Via']; + } + return $via; + } + + public function xLog() + { + return $this->headers['X-Log']; + } + + public function xReqId() + { + return $this->headers['X-Reqid']; + } + + public function needRetry() + { + $code = $this->statusCode; + if ($code< 0 || ($code / 100 == 5 and $code != 579) || $code == 996) { + return true; + } + } +} diff --git a/src/Qiniu/Processing/Operation.php b/src/Qiniu/Processing/Operation.php new file mode 100644 index 00000000..e425dd79 --- /dev/null +++ b/src/Qiniu/Processing/Operation.php @@ -0,0 +1,27 @@ + $value) { + array_push($op, "$key/$value"); + } + return implode('/', $op); + } + + public static function pipeCmd($cmds) + { + return implode('|', $cmds); + } + + public static function saveas($op, $bucket, $key) + { + return self::pipeCmd(array($op, 'saveas/' . \Qiniu\entry($bucket, $key))); + } +} diff --git a/src/Qiniu/Processing/PersistentFop.php b/src/Qiniu/Processing/PersistentFop.php new file mode 100644 index 00000000..7de3b560 --- /dev/null +++ b/src/Qiniu/Processing/PersistentFop.php @@ -0,0 +1,58 @@ +auth = $auth; + $this->bucket = $bucket; + $this->pipeline = $pipeline; + $this->notify_url = $notify_url; + } + + public function execute($key, array $fops, $force = false) + { + $ops = implode(';', $fops); + $params = array('bucket' => $this->bucket, 'key' => $key, 'fops' => $ops); + if (!empty($this->pipeline)) { + $params['pipeline'] = $this->pipeline; + } + if (!empty($this->notify_url)) { + $params['notifyURL'] = $this->notify_url; + } + if ($force) { + $params['force'] = 1; + } + $data = http_build_query($params); + $url = Config::API_HOST . '/pfop/'; + $headers = $this->auth->authorization($url, $data, 'application/x-www-form-urlencoded'); + $headers['Content-Type'] = 'application/x-www-form-urlencoded'; + $response = Client::post($url, $data, $headers); + if ($response->statusCode != 200) { + return array(null, new Error($url, $response)); + } + $r = $response->json(); + $id = $r['persistentId']; + return array($id, null); + } + + public static function status($id) + { + $url = Config::API_HOST . "/status/get/prefop?id=$id"; + $response = Client::get($url); + if ($response->statusCode != 200) { + return array(null, new Error($url, $response)); + } + return array($response->json(), null); + } +} diff --git a/src/Qiniu/Storage/BucketManager.php b/src/Qiniu/Storage/BucketManager.php new file mode 100644 index 00000000..0940ce61 --- /dev/null +++ b/src/Qiniu/Storage/BucketManager.php @@ -0,0 +1,205 @@ +auth = $auth; + } + + public function buckets() + { + return $this->rsget('/buckets'); + } + + public function listFiles($bucket, $prefix = null, $marker = null, $limit = 1000, $delimiter = null) + { + $query = array('bucket' => $bucket); + if (!empty($prefix)) { + $query['prefix'] = $prefix; + } + if (!empty($marker)) { + $query['marker'] = $marker; + } + if (!empty($limit)) { + $query['limit'] = $limit; + } + if (!empty($delimiter)) { + $query['delimiter'] = $delimiter; + } + $url = Config::RSF_HOST . '/list?' . http_build_query($query); + list($ret, $error) = $this->get($url); + if ($ret == null) { + return array(null, null, $error); + } + $marker = isset($ret['marker']) ? $ret['marker'] : null; + return array($ret['items'], $marker, null); + } + + public function stat($bucket, $key) + { + $path = '/stat/' . \Qiniu\entry($bucket, $key); + return $this->rsGet($path); + } + + public function delete($bucket, $key) + { + $path = '/delete/' . \Qiniu\entry($bucket, $key); + list($_, $error) = $this->rsPost($path); + return $error; + } + + public function rename($bucket, $oldname, $newname) + { + return $this->move($bucket, $oldname, $bucket, $newname); + } + + public function copy($from_bucket, $from_key, $to_bucket, $to_key) + { + $from = \Qiniu\entry($from_bucket, $from_key); + $to = \Qiniu\entry($to_bucket, $to_key); + $path = '/copy/' . $from . '/' . $to; + list($_, $error) = $this->rsPost($path); + return $error; + } + + public function move($from_bucket, $from_key, $to_bucket, $to_key) + { + $from = \Qiniu\entry($from_bucket, $from_key); + $to = \Qiniu\entry($to_bucket, $to_key); + $path = '/move/' . $from . '/' . $to; + list($_, $error) = $this->rsPost($path); + return $error; + } + + public function changeMime($bucket, $key, $mime) + { + $resource = \Qiniu\entry($bucket, $key); + $encode_mime = \Qiniu\base64_urlSafeEncode($mime); + $path = '/chgm/' . $resource . '/mime/' .$encode_mime; + list($_, $error) = $this->rsPost($path); + return $error; + } + + public function fetch($url, $bucket, $key) + { + $resource = \Qiniu\base64_urlSafeEncode($url); + $to = \Qiniu\entry($bucket, $key); + $path = '/fetch/' . $resource . '/to/' . $to; + list($_, $error) = $this->ioPost($path); + return $error; + } + + public function prefetch($bucket, $key) + { + $resource = \Qiniu\entry($bucket, $key); + $path = '/prefetch/' . $resource; + list($_, $error) = $this->ioPost($path); + return $error; + } + + public function batch($operations) + { + $params = 'op=' . implode('&op=', $operations); + return $this->rsPost('/batch', $params); + } + + private function rsPost($path, $body = null) + { + $url = Config::RS_HOST . $path; + return $this->post($url, $body); + } + + private function rsGet($path) + { + $url = Config::RS_HOST . $path; + return $this->get($url); + } + + private function ioPost($path, $body = null) + { + $url = Config::IO_HOST . $path; + return $this->post($url, $body); + } + + private function get($url) + { + $headers = $this->auth->authorization($url); + $ret = Client::get($url, $headers); + if ($ret->statusCode == 200 && $ret->error == null) { + return array($ret->json(), null); + } + return array(null, new Error($url, $ret)); + } + + private function post($url, $body) + { + $headers = $this->auth->authorization($url, $body, 'application/x-www-form-urlencoded'); + $ret = Client::post($url, $body, $headers); + if ($ret->statusCode == 200 && $ret->error == null) { + $r = $ret->body == null ? array() : $ret->json(); + return array($r, null); + } + return array(null, new Error($url, $ret)); + } + + public static function buildBatchCopy($source_bucket, $key_pairs, $target_bucket) + { + return self::twoKeyBatch('copy', $source_bucket, $key_pairs, $target_bucket); + } + + + public static function buildBatchRename($bucket, $key_pairs) + { + return self::buildBatchMove($bucket, $key_pairs, $bucket); + } + + + public static function buildBatchMove($source_bucket, $key_pairs, $target_bucket) + { + return self::twoKeyBatch('move', $source_bucket, $key_pairs, $target_bucket); + } + + + public static function buildBatchDelete($bucket, $keys) + { + return self::oneKeyBatch('delete', $bucket, $keys); + } + + + public static function buildBatchStat($bucket, $keys) + { + return self::oneKeyBatch('stat', $bucket, $keys); + } + + private static function oneKeyBatch($operation, $bucket, $keys) + { + $data = array(); + foreach ($keys as $key) { + array_push($data, $operation . '/' . \Qiniu\entry($bucket, $key)); + } + return $data; + } + + private static function twoKeyBatch($operation, $source_bucket, $key_pairs, $target_bucket) + { + if ($target_bucket == null) { + $target_bucket = $source_bucket; + } + $data = array(); + foreach ($key_pairs as $from_key => $to_key) { + $from = \Qiniu\entry($source_bucket, $from_key); + $to = \Qiniu\entry($target_bucket, $to_key); + array_push($data, $operation . '/' . $from . '/' . $to); + } + return $data; + } +} diff --git a/src/Qiniu/Storage/FormUploader.php b/src/Qiniu/Storage/FormUploader.php new file mode 100644 index 00000000..1e479116 --- /dev/null +++ b/src/Qiniu/Storage/FormUploader.php @@ -0,0 +1,89 @@ + $upToken); + if ($key === null) { + $fname = 'filename'; + } else { + $fname = $key; + $fields['key'] = $key; + } + if ($checkCrc) { + $fields['crc32'] = \Qiniu\crc32_data($data); + } + if ($params) { + foreach ($params as $k => $v) { + $fields[$k] = $v; + } + } + + $response = Client::multipartPost(Config::$defaultHost, $fields, 'file', $fname, $data, $mime); + if ($response->statusCode == 200 && $response->json() != null) { + return array($response->json(), null); + } + return array(null, new Error(Config::$defaultHost, $response)); + } + + public static function putFile( + $upToken, + $key, + $filePath, + $params, + $mime, + $checkCrc + ) { + + $fields = array('token' => $upToken, 'file' => self::createFile($filePath, $mime)); + if ($key === null) { + $fname = 'filename'; + } else { + $fname = $key; + $fields['key'] = $key; + } + if ($checkCrc) { + $fields['crc32'] = \Qiniu\crc32_file($filePath); + } + if ($params) { + foreach ($params as $k => $v) { + $fields[$k] = $v; + } + } + $headers =array('Content-Type' => 'multipart/form-data'); + $response = client::post(Config::$defaultHost, $fields, $headers); + if ($response->statusCode == 200 && $response->json() != null) { + return array($response->json(), null); + } + return array(null, new Error(Config::$defaultHost, $response)); + } + + private static function createFile($filename, $mime) + { + // PHP 5.5 introduced a CurlFile object that deprecates the old @filename syntax + // See: https://wiki.php.net/rfc/curl-file-upload + if (function_exists('curl_file_create')) { + return curl_file_create($filename, $mime); + } + + // Use the old style if using an older version of PHP + $value = "@{$filename}"; + if (!empty($mime)) { + $value .= ';type=' . $mime; + } + + return $value; + } +} diff --git a/src/Qiniu/Storage/ResumeUploader.php b/src/Qiniu/Storage/ResumeUploader.php new file mode 100644 index 00000000..26bc7831 --- /dev/null +++ b/src/Qiniu/Storage/ResumeUploader.php @@ -0,0 +1,125 @@ +upToken = $upToken; + $this->key = $key; + $this->inputStream = $inputStream; + $this->size = $size; + $this->params = $params; + $this->mime = $mime; + $this->host = Config::$defaultHost; + $this->contexts = array(); + } + + public function upload() + { + $uploaded = 0; + while ($uploaded < $this->size) { + $blockSize = $this->blockSize($uploaded); + $data = fread($this->inputStream, $blockSize); + if ($data === false) { + fclose($this->inputStream); + throw new Exception("file read failed", 1); + } + $crc = \Qiniu\crc32_data($data); + $response = $this->makeBlock($data, $blockSize); + $ret = null; + if ($response->statusCode == 200 && $response->error == null + && $response->json() != null) { + $ret = $response->json(); + } + if ($response->statusCode < 0) { + $this->host = Config::UPBACKUP_HOST; + } + if ($response->needRetry() || $crc != $ret['crc32']) { + $response = $this->makeBlock($data, $blockSize); + $ret = $response->json(); + } + + if ($response->statusCode != 200 || $crc != $ret['crc32']) { + fclose($this->inputStream); + return array(null, new Error($this->currentUrl, $response)); + } + array_push($this->contexts, $ret['ctx']); + $uploaded += $blockSize; + } + fclose($this->inputStream); + return $this->makeFile(); + } + + private function makeBlock($block, $blockSize) + { + $url = $this->host . '/mkblk/' . $blockSize; + return $this->post($url, $block); + } + + private function fileUrl() + { + $url = $this->host . '/mkfile/' . $this->size; + $url .= '/mimeType/' . \Qiniu\base64_urlSafeEncode($this->mime); + if ($this->key != null) { + $url .= '/key/' . \Qiniu\base64_urlSafeEncode($this->key); + } + if (!empty($this->params)) { + foreach ($this->params as $key => $value) { + $val = \Qiniu\base64_urlSafeEncode($value); + $url .= "/$key/$val"; + } + } + return $url; + } + + private function makeFile() + { + $url = $this->fileUrl(); + $body = implode(',', $this->contexts); + $response = $this->post($url, $body); + if ($response->needRetry()) { + $response = $this->post($url, $body); + } + if ($response->statusCode != 200) { + return array(null, new Error($this->currentUrl, $response)); + } + return array($response->json(), null); + } + + private function post($url, $data) + { + $this->currentUrl = $url; + $headers = array('Authorization' => 'UpToken ' . $this->upToken); + return Client::post($url, $data, $headers); + } + + private function blockSize($uploaded) + { + if ($this->size < $uploaded + Config::BLOCK_SIZE) { + return $bsize = $this->size - $uploaded; + } + return Config::BLOCK_SIZE; + } +} diff --git a/src/Qiniu/Storage/UploadManager.php b/src/Qiniu/Storage/UploadManager.php new file mode 100644 index 00000000..0cfbc7d5 --- /dev/null +++ b/src/Qiniu/Storage/UploadManager.php @@ -0,0 +1,90 @@ +upload(); + } + + public static function trimParams($params) + { + if ($params == null) { + return null; + } + $ret = array(); + foreach ($params as $k => $v) { + $pos = strpos($k, 'x:'); + if ($pos === 0 && !empty($v)) { + $ret[$k] = $v; + } + } + return $ret; + } +} diff --git a/src/Qiniu/functions.php b/src/Qiniu/functions.php new file mode 100644 index 00000000..553f3025 --- /dev/null +++ b/src/Qiniu/functions.php @@ -0,0 +1,80 @@ + 'JSON_ERROR_DEPTH - Maximum stack depth exceeded', + JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH - Underflow or the modes mismatch', + JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR - Unexpected control character found', + JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX - Syntax error, malformed JSON', + JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8 - Malformed UTF-8 characters, possibly incorrectly encoded' + ); + + $data = \json_decode($json, $assoc, $depth); + + if (JSON_ERROR_NONE !== json_last_error()) { + $last = json_last_error(); + throw new \InvalidArgumentException( + 'Unable to parse JSON data: ' + . (isset($jsonErrors[$last]) + ? $jsonErrors[$last] + : 'Unknown error') + ); + } + + return $data; + } + + function entry($bucket, $key) + { + return base64_urlSafeEncode($bucket . ':' . $key); + } +} diff --git a/tests/AuthDigestTest.php b/tests/AuthDigestTest.php deleted file mode 100644 index e8486f7b..00000000 --- a/tests/AuthDigestTest.php +++ /dev/null @@ -1,45 +0,0 @@ - 'YWJj', - 'abc0=?e' => 'YWJjMD0_ZQ==' - ); - foreach ($cases as $k => $v) { - $v1 = Qiniu_Encode($k); - $this->assertEquals($v, $v1); - } - } - - public function testVerifyCallback() - { - initKeys(); - $mac1 = Qiniu_RequireMac(null); - $auth = 'QBox Vhiv6a22kVN_zhtetbPNeG9sY3JUL1HG597EmBwQ:JrRyg9So6DNrNDY5qj1sygt0SmQ='; - $url = 'http://rs.qbox.me/batch'; - $body = 'op=/delete/cGhwc2RrOnRlc3RPcDI=&op=/delete/cGhwc2RrOnRlc3RPcDM=&op=/delete/cGhwc2RrOnRlc3RPcDQ='; - $pass = $mac1->VerifyCallback($auth, $url, $body); - $this->assertTrue($pass); - } - -/* public function testSetKeys() - { - $mac1 = Qiniu_RequireMac(null); - $this->assertTrue(!empty($mac1->AccessKey) && !empty($mac1->SecretKey), 'please provide keys'); - - Qiniu_SetKeys('abc', 'def'); - $mac = Qiniu_RequireMac(null); - $this->assertEquals($mac->AccessKey, 'abc'); - $this->assertEquals($mac->SecretKey, 'def'); - - Qiniu_SetKeys($mac1->AccessKey, $mac1->SecretKey); - } -*/ -} - diff --git a/tests/FopTest.php b/tests/FopTest.php deleted file mode 100644 index 8ab91d1c..00000000 --- a/tests/FopTest.php +++ /dev/null @@ -1,38 +0,0 @@ -Mode = 1; - $imageView->Width = 80; - $imageView->Format = 'jpg'; - - $url = $this->url; - - $expectedUrl = $url . '?imageView/1/w/80/format/jpg'; - $this->assertEquals($imageView->MakeRequest($url), $expectedUrl); - } - - public function testExif() - { - $exif = new Qiniu_Exif(); - $url = $this->url; - $expectedUrl = $url . '?exif'; - $this->assertEquals($exif->MakeRequest($url), $expectedUrl); - } - - public function testImageInfo() - { - $imageView = new Qiniu_ImageInfo(); - $url = $this->url; - $expectedUrl = $url . '?imageInfo'; - - $this->assertEquals($imageView->MakeRequest($url), $expectedUrl); - } -} diff --git a/tests/IoTest.php b/tests/IoTest.php deleted file mode 100644 index 089b65de..00000000 --- a/tests/IoTest.php +++ /dev/null @@ -1,175 +0,0 @@ -client = new Qiniu_MacHttpClient(null); - $this->bucket = getenv("QINIU_BUCKET_NAME"); - } - - public function testReqid() - { - $key = 'testReqid' . getTid(); - list($ret, $err) = Qiniu_PutFile("", $key, __file__, null); - $this->assertNotNull($err); - $this->assertNotNull($err->Reqid); - var_dump($err); - } - - public function testPutFile() - { - $key = 'testPutFile' . getTid(); - $err = Qiniu_RS_Delete($this->client, $this->bucket, $key); - - $putPolicy = new Qiniu_RS_PutPolicy($this->bucket); - $upToken = $putPolicy->Token(null); - $putExtra = new Qiniu_PutExtra(); - $putExtra->Params = array('x:test'=>'test'); - $putExtra->CheckCrc = 1; - list($ret, $err) = Qiniu_PutFile($upToken, $key, __file__, $putExtra); - $this->assertNull($err); - $this->assertArrayHasKey('hash', $ret); - $this->assertArrayHasKey('x:test', $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 testPut() - { - $key = 'testPut' . getTid(); - $err = Qiniu_RS_Delete($this->client, $this->bucket, $key); - - $putPolicy = new Qiniu_RS_PutPolicy($this->bucket); - $upToken = $putPolicy->Token(null); - $putExtra = new Qiniu_PutExtra(); - $putExtra->Params = array('x:test'=>'test'); - list($ret, $err) = Qiniu_Put($upToken, $key, "hello world!", $putExtra); - $this->assertNull($err); - $this->assertArrayHasKey('hash', $ret); - $this->assertArrayHasKey('x:test', $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 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_mimetype() { - $key = 'testPut_mimetype' . getTid(); - $err = Qiniu_RS_Delete($this->client, $this->bucket, $key); - $scope = $this->bucket . ":" . $key; - - $putPolicy = new Qiniu_RS_PutPolicy($scope); - $putPolicy->ReturnBody = '{"key":$(key),"mimeType":$(mimeType)}'; - $upToken = $putPolicy->Token(null); - - $putExtra = new Qiniu_PutExtra(); - $putExtra->MimeType = 'image/jpg'; - - list($ret1, $err1) = Qiniu_PutFile($upToken, $key, __file__, $putExtra); - var_dump($ret1); - $this->assertNull($err1); - $this->assertEquals($ret1['mimeType'], 'image/jpg'); - - list($ret2, $err2) = Qiniu_Put($upToken, $key, "hello world", $putExtra); - var_dump($ret2); - $this->assertNull($err2); - $this->assertEquals($ret2['mimeType'], 'image/jpg'); - - $err = Qiniu_RS_Delete($this->client, $this->bucket, $key); - } - - 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->Code, 614); - 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); - } - - public function testPut_mimeLimit() { - $key = 'testPut_mimeLimit' . getTid(); - $scope = $this->bucket . ':' . $key; - $err = Qiniu_RS_Delete($this->client, $this->bucket, $key); - - $putPolicy = new Qiniu_RS_PutPolicy($scope); - $putPolicy->MimeLimit = "image/*"; - $upToken = $putPolicy->Token(null); - - list($ret, $err) = Qiniu_PutFile($upToken, $key, __file__, null); - $this->assertNull($ret); - $this->assertEquals($err->Err, "limited mimeType: this file type is forbidden to upload"); - var_dump($err); - } -} - diff --git a/tests/PersistentTest.php b/tests/PersistentTest.php deleted file mode 100644 index 0f4e2beb..00000000 --- a/tests/PersistentTest.php +++ /dev/null @@ -1,65 +0,0 @@ -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); - } -} - diff --git a/tests/Qiniu/Tests/AuthTest.php b/tests/Qiniu/Tests/AuthTest.php new file mode 100644 index 00000000..5a99c461 --- /dev/null +++ b/tests/Qiniu/Tests/AuthTest.php @@ -0,0 +1,84 @@ +token('test'); + $this->assertEquals('abcdefghklmnopq:mSNBTR7uS2crJsyFr2Amwv1LaYg=', $token); + } + + public function testTokenWithData() + { + global $dummyAuth; + $token = $dummyAuth->tokenWithData('test'); + $this->assertEquals('abcdefghklmnopq:-jP8eEV9v48MkYiBGs81aDxl60E=:dGVzdA==', $token); + } + + public function testTokenOfRequest() + { + global $dummyAuth; + $token = $dummyAuth->tokenOfRequest('http://www.qiniu.com?go=1', 'test', ''); + $this->assertEquals('abcdefghklmnopq:cFyRVoWrE3IugPIMP5YJFTO-O-Y=', $token); + $ctype = 'application/x-www-form-urlencoded'; + $token = $dummyAuth->tokenOfRequest('http://www.qiniu.com?go=1', 'test', $ctype); + $this->assertEquals($token, 'abcdefghklmnopq:svWRNcacOE-YMsc70nuIYdaa1e4='); + } + + public function testPrivateDownloadUrl() + { + global $dummyAuth; + $_SERVER['override_qiniu_auth_time'] = true; + $url = $dummyAuth->privateDownloadUrl('http://www.qiniu.com?go=1'); + $expect = 'http://www.qiniu.com?go=1&e=1234571490&token=abcdefghklmnopq:8vzBeLZ9W3E4kbBLFLW0Xe0u7v4='; + $this->assertEquals($expect, $url); + unset($_SERVER['override_qiniu_auth_time']); + } + + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessage asyncOps has deprecated + */ + public function testDeprecatedPolicy() + { + global $dummyAuth; + $token = $dummyAuth->uploadToken('1', null, 3600, array('asyncOps'=> 1)); + } + + public function testUploadToken() + { + global $dummyAuth; + $_SERVER['override_qiniu_auth_time'] = true; + $token = $dummyAuth->uploadToken('1', '2', 3600, array('endUser'=> 'y')); + $exp = 'abcdefghklmnopq:x53hx7845_pygLochtRWlnrL-90=:eyJzY29wZSI6IjE6MiIsImRlYWRsaW5lIjoxMjM0NTcxNDkwfQ=='; + $this->assertEquals($exp, $token); + unset($_SERVER['override_qiniu_auth_time']); + } + + public function testVerifyCallback() + { + + } + } +} diff --git a/tests/Qiniu/Tests/Base64Test.php b/tests/Qiniu/Tests/Base64Test.php new file mode 100644 index 00000000..6d633530 --- /dev/null +++ b/tests/Qiniu/Tests/Base64Test.php @@ -0,0 +1,14 @@ +assertEquals($a, \Qiniu\base64_urlSafeDecode($b)); + } +} diff --git a/tests/Qiniu/Tests/BucketTest.php b/tests/Qiniu/Tests/BucketTest.php new file mode 100644 index 00000000..87ff391e --- /dev/null +++ b/tests/Qiniu/Tests/BucketTest.php @@ -0,0 +1,176 @@ +bucketName = $bucketName; + $this->key = $key; + + global $testAuth; + $this->bucketManager = new BucketManager($testAuth); + + global $dummyAuth; + $this->dummyBucketManager = new BucketManager($dummyAuth); + } + + public function testBuckets() + { + + list($list, $error) = $this->bucketManager->buckets(); + $this->assertTrue(in_array($this->bucketName, $list)); + $this->assertNull($error); + + list($list2, $error) = $this->dummyBucketManager->buckets(); + $this->assertEquals(401, $error->code()); + $this->assertNull($list2); + $this->assertNotNull($error->message()); + } + + public function testList() + { + list($items, $marker, $error) = $this->bucketManager->listFiles($this->bucketName, null, null, 2); + $this->assertNotNull($items[0]); + $this->assertNotNull($marker); + } + + public function testStat() + { + list($stat, $error) = $this->bucketManager->stat($this->bucketName, $this->key); + $this->assertNotNull($stat); + $this->assertNull($error); + $this->assertNotNull($stat['hash']); + + list($stat, $error) = $this->bucketManager->stat($this->bucketName, 'nofile'); + $this->assertNull($stat); + $this->assertEquals(612, $error->code()); + $this->assertNotNull($error->message()); + + list($stat, $error) = $this->bucketManager->stat('nobucket', 'nofile'); + $this->assertNull($stat); + $this->assertEquals(631, $error->code()); + $this->assertNotNull($error->message()); + } + + public function testDelete() + { + $error = $this->bucketManager->delete($this->bucketName, 'del'); + $this->assertEquals(612, $error->code()); + } + + + public function testRename() + { + $key = 'renamefrom' . rand(); + $this->bucketManager->copy($this->bucketName, $this->key, $this->bucketName, $key); + $key2 = 'renameto' . $key; + $error = $this->bucketManager->rename($this->bucketName, $key, $key2); + $this->assertNull($error); + $error = $this->bucketManager->delete($this->bucketName, $key2); + $this->assertNull($error); + } + + + public function testCopy() + { + $key = 'copyto' . rand(); + $error = $this->bucketManager->copy( + $this->bucketName, + $this->key, + $this->bucketName, + $key + ); + $this->assertNull($error); + $error = $this->bucketManager->delete($this->bucketName, $key); + $this->assertNull($error); + } + + + public function testChangeMime() + { + $error = $this->bucketManager->changeMime( + $this->bucketName, + 'php-sdk.html', + 'text/html' + ); + $this->assertNull($error); + } + + public function testPrefetch() + { + $error = $this->bucketManager->prefetch( + $this->bucketName, + 'php-sdk.html' + ); + $this->assertNull($error); + } + + public function testFetch() + { + $error = $this->bucketManager->fetch( + 'http://developer.qiniu.com/docs/v6/sdk/php-sdk.html', + $this->bucketName, + 'fetch.html' + ); + $this->assertNull($error); + } + + public function testBatchCopy() + { + $key = 'copyto' . rand(); + $ops = BucketManager::buildBatchCopy( + $this->bucketName, + array($this->key => $key), + $this->bucketName + ); + list($ret, $error) = $this->bucketManager->batch($ops); + $this->assertEquals(200, $ret[0]['code']); + $ops = BucketManager::buildBatchDelete($this->bucketName, array($key)); + list($ret, $error) = $this->bucketManager->batch($ops); + $this->assertEquals(200, $ret[0]['code']); + } + + public function testBatchMove() + { + $key = 'movefrom'. rand(); + $this->bucketManager->copy($this->bucketName, $this->key, $this->bucketName, $key); + $key2 = $key . 'to'; + $ops = BucketManager::buildBatchMove( + $this->bucketName, + array($key => $key2), + $this->bucketName + ); + list($ret, $error) = $this->bucketManager->batch($ops); + $this->assertEquals(200, $ret[0]['code']); + $error = $this->bucketManager->delete($this->bucketName, $key2); + $this->assertNull($error); + } + + public function testBatchRename() + { + $key = 'rename' . rand(); + $this->bucketManager->copy($this->bucketName, $this->key, $this->bucketName, $key); + $key2 = $key . 'to'; + $ops = BucketManager::buildBatchRename($this->bucketName, array($key => $key2)); + list($ret, $error) = $this->bucketManager->batch($ops); + $this->assertEquals(200, $ret[0]['code']); + $error = $this->bucketManager->delete($this->bucketName, $key2); + $this->assertNull($error); + } + + public function testBatchStat() + { + $ops = BucketManager::buildBatchStat($this->bucketName, array('php-sdk.html')); + list($ret, $error) = $this->bucketManager->batch($ops); + $this->assertEquals(200, $ret[0]['code']); + } +} diff --git a/tests/Qiniu/Tests/Crc32Test.php b/tests/Qiniu/Tests/Crc32Test.php new file mode 100644 index 00000000..bfb36da8 --- /dev/null +++ b/tests/Qiniu/Tests/Crc32Test.php @@ -0,0 +1,21 @@ +assertEquals('1352841281', $b); + } + + public function testFile() + { + $b = \Qiniu\crc32_file(__file__); + $c = \Qiniu\crc32_file(__file__); + $this->assertEquals($c, $b); + } +} diff --git a/tests/Qiniu/Tests/DownloadTest.php b/tests/Qiniu/Tests/DownloadTest.php new file mode 100644 index 00000000..82990f2a --- /dev/null +++ b/tests/Qiniu/Tests/DownloadTest.php @@ -0,0 +1,25 @@ +privateDownloadUrl($base_url); + $response = Client::get($private_url); + $this->assertEquals(200, $response->statusCode); + } + + public function testFop() + { + global $testAuth; + $base_url = 'http://private-res.qiniudn.com/gogopher.jpg?exif'; + $private_url = $testAuth->privateDownloadUrl($base_url); + $response = Client::get($private_url); + $this->assertEquals(200, $response->statusCode); + } +} diff --git a/tests/Qiniu/Tests/EtagTest.php b/tests/Qiniu/Tests/EtagTest.php new file mode 100644 index 00000000..d95857d6 --- /dev/null +++ b/tests/Qiniu/Tests/EtagTest.php @@ -0,0 +1,52 @@ +assertEquals('Fto5o-5ea0sNMlW_75VgGJCv2AcJ', $r); + $this->assertNull($error); + } + + public function testLess4M() + { + $file = qiniuTempFile(3*1024*1024); + list($r, $error) = Etag::sum($file); + unlink($file); + $this->assertEquals('lrGEYiVvREEgGl_foQEnZ5a5BqwZ', $r); + $this->assertNull($error); + } + + public function test4M() + { + $file = qiniuTempFile(4*1024*1024); + list($r, $error) = Etag::sum($file); + unlink($file); + $this->assertEquals('lvOwUCzD-YVymzwJLRGZR3eD__GV', $r); + $this->assertNull($error); + } + + public function testMore4M() + { + $file = qiniuTempFile(5*1024*1024); + list($r, $error) = Etag::sum($file); + unlink($file); + $this->assertEquals('lqtEDHt7Yo5j1a2mjlB2Ds8DUYNM', $r); + $this->assertNull($error); + } + + public function test8M() + { + $file = qiniuTempFile(8*1024*1024); + list($r, $error) = Etag::sum($file); + unlink($file); + $this->assertEquals('ljpekgMJ9VSYlE8hMX06GIWXxfDI', $r); + $this->assertNull($error); + } +} diff --git a/tests/Qiniu/Tests/FormUpTest.php b/tests/Qiniu/Tests/FormUpTest.php new file mode 100644 index 00000000..fcbf525a --- /dev/null +++ b/tests/Qiniu/Tests/FormUpTest.php @@ -0,0 +1,54 @@ +bucketName = $bucketName; + + global $testAuth; + $this->auth = $testAuth; + } + public function testData() + { + $token = $this->auth->uploadToken($this->bucketName); + list($ret, $error) = FormUploader::put($token, 'formput', 'hello world', null, 'text/plain', true); + $this->assertNull($error); + $this->assertNotNull($ret['hash']); + } + + public function testData2() + { + $upManager = new UploadManager(); + $token = $this->auth->uploadToken($this->bucketName); + list($ret, $error) = $upManager->put($token, 'formput', 'hello world', null, 'text/plain', true); + $this->assertNull($error); + $this->assertNotNull($ret['hash']); + } + + public function testFile() + { + $key = 'formPutFile'; + $token = $this->auth->uploadToken($this->bucketName, $key); + list($ret, $error) = FormUploader::putFile($token, $key, __file__, null, 'text/plain', true); + $this->assertNull($error); + $this->assertNotNull($ret['hash']); + } + + public function testFile2() + { + $key = 'formPutFile'; + $token = $this->auth->uploadToken($this->bucketName, $key); + $upManager = new UploadManager(); + list($ret, $error) = $upManager->putFile($token, $key, __file__, null, 'text/plain', true); + $this->assertNull($error); + $this->assertNotNull($ret['hash']); + } +} diff --git a/tests/Qiniu/Tests/HttpTest.php b/tests/Qiniu/Tests/HttpTest.php new file mode 100644 index 00000000..ebfe6cb0 --- /dev/null +++ b/tests/Qiniu/Tests/HttpTest.php @@ -0,0 +1,43 @@ +assertEquals($response->statusCode, 200); + $this->assertNotNull($response->body); + $this->assertNull($response->error); + } + + public function testGetQiniu() + { + $response = Client::get('up.qiniu.com'); + $this->assertEquals($response->statusCode, 405); + $this->assertNotNull($response->body); + $this->assertNotNull($response->xReqId()); + $this->assertNotNull($response->xLog()); + $this->assertNotNull($response->error); + } + + public function testPost() + { + $response = Client::post('baidu.com', null); + $this->assertEquals($response->statusCode, 405); + $this->assertNotNull($response->body); + $this->assertNotNull($response->error); + } + + public function testPostQiniu() + { + $response = Client::post('up.qiniu.com', null); + $this->assertEquals($response->statusCode, 400); + $this->assertNotNull($response->body); + $this->assertNotNull($response->xReqId()); + $this->assertNotNull($response->xLog()); + $this->assertNotNull($response->error); + } +} diff --git a/tests/Qiniu/Tests/PfopTest.php b/tests/Qiniu/Tests/PfopTest.php new file mode 100644 index 00000000..37af6aed --- /dev/null +++ b/tests/Qiniu/Tests/PfopTest.php @@ -0,0 +1,22 @@ +execute('sintel_trailer.mp4', $ops, true); + $this->assertNull($error); + list($status, $error) = PersistentFop::status($id); + $this->assertNotNull($status); + $this->assertNull($error); + } +} diff --git a/tests/Qiniu/Tests/ResumeUpTest.php b/tests/Qiniu/Tests/ResumeUpTest.php new file mode 100644 index 00000000..dd7e7e4a --- /dev/null +++ b/tests/Qiniu/Tests/ResumeUpTest.php @@ -0,0 +1,43 @@ +bucketName = $bucketName; + + global $testAuth; + $this->auth = $testAuth; + } + + public function test4ML() + { + $key = 'resumePutFile4ML'; + $upManager = new UploadManager(); + $token = $this->auth->uploadToken($this->bucketName, $key); + $tempFile = qiniuTempFile(4*1024*1024+10); + list($ret, $error) = $upManager->putFile($token, $key, $tempFile); + $this->assertNull($error); + $this->assertNotNull($ret['hash']); + unlink($tempFile); + } + + // public function test8M() + // { + // $key = 'resumePutFile8M'; + // $upManager = new UploadManager(); + // $token = $this->auth->uploadToken($this->bucketName, $key); + // $tempFile = qiniuTempFile(8*1024*1024+10); + // list($ret, $error) = $upManager->putFile($token, $key, $tempFile); + // $this->assertNull($error); + // $this->assertNotNull($ret['hash']); + // unlink($tempFile); + // } +} diff --git a/tests/RioTest.php b/tests/RioTest.php deleted file mode 100644 index b6474bb5..00000000 --- a/tests/RioTest.php +++ /dev/null @@ -1,81 +0,0 @@ -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() - { - if (getTestEnv() == "travis") { - return; - } - $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); - $putExtra->Params = array('x:test'=>'test'); - $reader = new MockReader; - list($ret, $err) = Qiniu_Rio_Put($upToken, $key, $reader, 5, $putExtra); - $this->assertNull($err); - $this->assertEquals($ret['hash'], "Fnvgeq9GDVk6Mj0Nsz2gW2S_3LOl"); - $this->assertEquals($ret['x:test'], "test"); - 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() - { - if (getTestEnv() == "travis") { - return; - } - $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); - $putExtra->Params = array('x:test'=>'test'); - $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"); - $this->assertEquals($ret['x:test'], "test"); - 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); - } -} - diff --git a/tests/RsTest.php b/tests/RsTest.php deleted file mode 100644 index b02375a2..00000000 --- a/tests/RsTest.php +++ /dev/null @@ -1,98 +0,0 @@ -client = new Qiniu_MacHttpClient(null); - $this->bucket = getenv("QINIU_BUCKET_NAME"); - $this->key = getenv("QINIU_KEY_NAME"); - } - - public function testStat() - { - $putPolicy = new Qiniu_RS_PutPolicy($this->bucket . ":" . $this->key); - $upToken = $putPolicy->Token(null); - list($ret, $err) = Qiniu_PutFile($upToken, $this->key, __file__, null); - $this->assertNull($err); - Qiniu_RS_Delete($this->client, $this->bucket, $this->notExistKey); - list($ret, $err) = Qiniu_RS_Stat($this->client, $this->bucket, $this->key); - $this->assertArrayHasKey('hash', $ret); - $this->assertNull($err); - list($ret, $err) = Qiniu_RS_Stat($this->client, $this->bucket, $this->notExistKey); - $this->assertNull($ret); - $this->assertFalse($err === null); - } - - public function testDeleteMoveCopy() - { - $key2 = 'testOp2' . getTid(); - $key3 = 'testOp3' . getTid(); - Qiniu_RS_Delete($this->client, $this->bucket, $key2); - Qiniu_RS_Delete($this->client, $this->bucket, $key3); - - $err = Qiniu_RS_Copy($this->client, $this->bucket, $this->key, $this->bucket, $key2); - $this->assertNull($err); - $err = Qiniu_RS_Move($this->client, $this->bucket, $key2, $this->bucket, $key3); - $this->assertNull($err); - $err = Qiniu_RS_Delete($this->client, $this->bucket, $key3); - $this->assertNull($err); - $err = Qiniu_RS_Delete($this->client, $this->bucket, $key2); - $this->assertNotNull($err, "delete key2 false"); - } - - public function testBatchStat() - { - $key2 = 'testOp2' . getTid(); - Qiniu_RS_Delete($this->client, $this->bucket, $key2); - $entries = array(new Qiniu_RS_EntryPath($this->bucket, $this->key), new Qiniu_RS_EntryPath($this->bucket, $key2)); - list($ret, $err) = Qiniu_RS_BatchStat($this->client, $entries); - $this->assertNotNull($err); - $this->assertEquals($ret[0]['code'], 200); - $this->assertEquals($ret[1]['code'], 612); - } - - public function testBatchDeleteMoveCopy() - { - $key2 = 'testOp2' . getTid(); - $key3 = 'testOp3' . getTid(); - $key4 = 'testOp4' . getTid(); - $e1 = new Qiniu_RS_EntryPath($this->bucket, $this->key); - $e2 = new Qiniu_RS_EntryPath($this->bucket, $key2); - $e3 = new Qiniu_RS_EntryPath($this->bucket, $key3); - $e4 = new Qiniu_RS_EntryPath($this->bucket, $key4); - Qiniu_RS_BatchDelete($this->client, array($e2, $e3,$e4)); - - $entryPairs = array(new Qiniu_RS_EntryPathPair($e1, $e2), new Qiniu_RS_EntryPathPair($e1, $e3)); - list($ret, $err) = Qiniu_RS_BatchCopy($this->client, $entryPairs); - $this->assertNull($err); - $this->assertEquals($ret[0]['code'], 200); - $this->assertEquals($ret[1]['code'], 200); - - list($ret, $err) = Qiniu_RS_BatchMove($this->client, array(new Qiniu_RS_EntryPathPair($e2, $e4))); - $this->assertNull($err); - $this->assertEquals($ret[0]['code'], 200); - - list($ret, $err) = Qiniu_RS_BatchDelete($this->client, array($e3, $e4)); - $this->assertNull($err); - $this->assertEquals($ret[0]['code'], 200); - $this->assertEquals($ret[1]['code'], 200); - - Qiniu_RS_BatchDelete($this->client, array($e2, $e3, $e4)); - } - - public function testUrlEncode() { - $url = Qiniu_RS_MakeBaseUrl("www.qiniu.com", "a/b/c d"); - var_dump($url); - $this->assertEquals($url, "http://www.qiniu.com/a/b/c%20d"); - } -} - diff --git a/tests/RsUtilsTest.php b/tests/RsUtilsTest.php deleted file mode 100644 index 75a8b7f5..00000000 --- a/tests/RsUtilsTest.php +++ /dev/null @@ -1,98 +0,0 @@ -client = new Qiniu_MacHttpClient(null); - $this->bucket = getenv("QINIU_BUCKET_NAME"); - } - - public function testRput() - { - if (getTestEnv() == "travis") { - return; - } - $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() - { - if (getTestEnv() == "travis") { - return; - } - $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(); - $err = Qiniu_RS_Delete($this->client, $this->bucket, $key); - - $putExtra = new Qiniu_PutExtra(); - $putExtra->CheckCrc = 1; - list($ret, $err) = Qiniu_RS_PutFile($this->client, $this->bucket, $key, __file__, $putExtra); - $this->assertNull($err); - $this->assertArrayHasKey('hash', $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 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); - $this->assertNull($err); - $this->assertArrayHasKey('hash', $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); - } -} - diff --git a/tests/RsfTest.php b/tests/RsfTest.php deleted file mode 100644 index 66967927..00000000 --- a/tests/RsfTest.php +++ /dev/null @@ -1,31 +0,0 @@ -client = new Qiniu_MacHttpClient(null); - $this->bucket = getenv('QINIU_BUCKET_NAME'); - $this->key = getenv('QINIU_KEY_NAME'); - } - - public function testListPrefix() - { - echo $this->bucket; - list($items, $markerOut, $err) = Qiniu_RSF_ListPrefix($this->client, $this->bucket); - $this->assertEquals($err, Qiniu_RSF_EOF); - $this->assertEquals($markerOut, ''); - - list($items, $markerOut, $err) = Qiniu_RSF_ListPrefix($this->client, $this->bucket, '', '', 1); - $this->assertFalse($markerOut === ''); - - list($items, $markerOut, $err) = Qiniu_RSF_ListPrefix($this->client, $this->bucket, $this->key); - $this->assertLessThanOrEqual(count($items), 1); - } -} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index d555531d..f3dfa816 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,58 +1,37 @@ 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); - } + $fileName = tempnam(sys_get_temp_dir(), 'qiniu_'); + $file = fopen($fileName, 'wb'); + if ($size > 0) { + fseek($file, $size-1); + fwrite($file, ' '); + } + fclose($file); + return $fileName; } -