Skip to content

Commit 94350e0

Browse files
authored
Merge pull request #190 from rwifeng/multi_zones
multi zone support
2 parents d1bca45 + 31630c5 commit 94350e0

File tree

11 files changed

+255
-36
lines changed

11 files changed

+255
-36
lines changed
File renamed without changes.

examples/pfop_ watermark.php renamed to examples/pfop_watermark.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
$notifyUrl = 'http://375dec79.ngrok.com/notify.php';
2222
$pfop = new PersistentFop($auth, $bucket, $pipeline, $notifyUrl);
2323

24-
//需要添加水印的图片UrlSafeBase64,可以参考http://developer.qiniu.com/code/v6/api/dora-api/av/video-watermark.html
24+
//需要添加水印的图片UrlSafeBase64
25+
//可以参考http://developer.qiniu.com/code/v6/api/dora-api/av/video-watermark.html
2526
$base64URL = Qiniu\base64_urlSafeEncode('http://developer.qiniu.com/resource/logo-2.jpg');
2627

2728
//水印参数

src/Qiniu/Auth.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
namespace Qiniu;
33

44
use Qiniu;
5+
use Qiniu\Zone;
56

67
final class Auth
78
{
@@ -14,6 +15,11 @@ public function __construct($accessKey, $secretKey)
1415
$this->secretKey = $secretKey;
1516
}
1617

18+
public function getAccessKey()
19+
{
20+
return $this->accessKey;
21+
}
22+
1723
public function sign($data)
1824
{
1925
$hmac = hash_hmac('sha1', $data, $this->secretKey, true);
@@ -71,7 +77,8 @@ public function uploadToken(
7177
$key = null,
7278
$expires = 3600,
7379
$policy = null,
74-
$strictPolicy = true
80+
$strictPolicy = true,
81+
Zone $zone = null
7582
) {
7683
$deadline = time() + $expires;
7784
$scope = $bucket;
@@ -82,6 +89,16 @@ public function uploadToken(
8289
$args = self::copyPolicy($args, $policy, $strictPolicy);
8390
$args['scope'] = $scope;
8491
$args['deadline'] = $deadline;
92+
93+
if ($zone === null) {
94+
$zone = new Zone();
95+
}
96+
97+
list($upHosts, $err) = $zone->getUpHosts($this->accessKey, $bucket);
98+
if ($err === null) {
99+
$args['upHosts'] = $upHosts;
100+
}
101+
85102
$b = json_encode($args);
86103
return $this->signWithData($b);
87104
}
@@ -114,6 +131,8 @@ public function uploadToken(
114131
'persistentPipeline',
115132

116133
'deleteAfterDays',
134+
135+
'upHosts',
117136
);
118137

119138
private static $deprecatedPolicyFields = array(

src/Qiniu/Config.php

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,25 @@
11
<?php
22
namespace Qiniu;
33

4+
use Qiniu\Zone;
5+
46
final class Config
57
{
68
const SDK_VER = '7.0.8';
79

810
const BLOCK_SIZE = 4194304; //4*1024*1024 分块上传块大小,该参数为接口规格,不能修改
911

10-
const IO_HOST = 'http://iovip.qbox.me'; // 七牛源站Host
1112
const RS_HOST = 'http://rs.qbox.me'; // 文件元信息管理操作Host
1213
const RSF_HOST = 'http://rsf.qbox.me'; // 列举操作Host
1314
const API_HOST = 'http://api.qiniu.com'; // 数据处理操作Host
15+
const UC_HOST = 'http://uc.qbox.me'; // Host
1416

15-
private $upHost; // 上传Host
16-
private $upHostBackup; // 上传备用Host
17+
public $zone;
1718

1819
public function __construct(Zone $z = null) // 构造函数,默认为zone0
1920
{
20-
if ($z === null) {
21-
$z = Zone::zone0();
22-
}
23-
$this->upHost = $z->upHost;
24-
$this->upHostBackup = $z->upHostBackup;
25-
}
26-
27-
public function getUpHost()
28-
{
29-
return $this->upHost;
30-
}
31-
32-
public function getUpHostBackup()
33-
{
34-
return $this->upHostBackup;
21+
// if ($z === null) {
22+
$this->zone = new Zone();
23+
// }
3524
}
3625
}

src/Qiniu/Storage/BucketManager.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use Qiniu\Auth;
55
use Qiniu\Config;
6+
use Qiniu\Zone;
67
use Qiniu\Http\Client;
78
use Qiniu\Http\Error;
89

@@ -14,10 +15,14 @@
1415
final class BucketManager
1516
{
1617
private $auth;
18+
private $zone;
1719

18-
public function __construct(Auth $auth)
20+
public function __construct(Auth $auth, Zone $zone = null)
1921
{
2022
$this->auth = $auth;
23+
if ($zone === null) {
24+
$this->zone = new Zone();
25+
}
2126
}
2227

2328
/**
@@ -206,7 +211,12 @@ public function fetch($url, $bucket, $key = null)
206211
$resource = \Qiniu\base64_urlSafeEncode($url);
207212
$to = \Qiniu\entry($bucket, $key);
208213
$path = '/fetch/' . $resource . '/to/' . $to;
209-
return $this->ioPost($path);
214+
215+
$ak = $this->auth->getAccessKey();
216+
$ioHost = $this->zone->getIoHost($ak, $bucket);
217+
218+
$url = $ioHost . $path;
219+
return $this->post($url, null);
210220
}
211221

212222
/**
@@ -222,7 +232,12 @@ public function prefetch($bucket, $key)
222232
{
223233
$resource = \Qiniu\entry($bucket, $key);
224234
$path = '/prefetch/' . $resource;
225-
list(, $error) = $this->ioPost($path);
235+
236+
$ak = $this->auth->getAccessKey();
237+
$ioHost = $this->zone->getIoHost($ak, $bucket);
238+
239+
$url = $ioHost . $path;
240+
list(, $error) = $this->post($url, null);
226241
return $error;
227242
}
228243

src/Qiniu/Storage/FormUploader.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,10 @@ public static function put(
4949
}
5050
}
5151

52-
$response = Client::multipartPost($config->getUpHost(), $fields, 'file', $fname, $data, $mime);
52+
$upHost = $config->zone->getUpHostByToken($upToken);
53+
$response = Client::multipartPost($upHost, $fields, 'file', $fname, $data, $mime);
5354
if (!$response->ok()) {
54-
return array(null, new Error($config->getUpHost(), $response));
55+
return array(null, new Error($upHost, $response));
5556
}
5657
return array($response->json(), null);
5758
}
@@ -97,9 +98,11 @@ public static function putFile(
9798
}
9899
$fields['key'] = $key;
99100
$headers =array('Content-Type' => 'multipart/form-data');
100-
$response = client::post($config->getUpHost(), $fields, $headers);
101+
102+
$upHost = $config->zone->getUpHostByToken($upToken);
103+
$response = client::post($upHost, $fields, $headers);
101104
if (!$response->ok()) {
102-
return array(null, new Error($config->getUpHost(), $response));
105+
return array(null, new Error($upHost, $response));
103106
}
104107
return array($response->json(), null);
105108
}

src/Qiniu/Storage/ResumeUploader.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function __construct(
5454
$this->mime = $mime;
5555
$this->contexts = array();
5656
$this->config = $config;
57-
$this->host = $config->getUpHost();
57+
$this->host = $config->zone->getUpHostByToken($upToken);
5858
}
5959

6060
/**
@@ -76,7 +76,7 @@ public function upload()
7676
$ret = $response->json();
7777
}
7878
if ($response->statusCode < 0) {
79-
$this->host = $this->config->getUpHostBackup();
79+
$this->host = $this->config->zone->getBackupUpHostByToken($this->upToken);
8080
}
8181
if ($response->needRetry() || !isset($ret['crc32']) || $crc != $ret['crc32']) {
8282
$response = $this->makeBlock($data, $blockSize);

src/Qiniu/Storage/UploadManager.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ public function putFile(
109109
$checkCrc
110110
);
111111
}
112+
112113
$up = new ResumeUploader(
113114
$upToken,
114115
$key,

src/Qiniu/Zone.php

Lines changed: 144 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,161 @@
11
<?php
22
namespace Qiniu;
33

4+
use Qiniu\Http\Client;
5+
use Qiniu\Http\Error;
6+
47
final class Zone
58
{
9+
public $ioHost; // 七牛源站Host
610
public $upHost;
711
public $upHostBackup;
812

9-
public function __construct($upHost, $upHostBackup)
13+
//array(
14+
// <scheme>:<ak>:<bucket> ==>
15+
// array('deadline' => 'xxx', 'upHosts' => array(), 'ioHost' => 'xxx.com')
16+
//)
17+
public $hostCache;
18+
public $scheme = 'http';
19+
20+
public function __construct($scheme = null)
21+
{
22+
$this->hostCache = array();
23+
if ($scheme != null) {
24+
$this->scheme = $scheme;
25+
}
26+
}
27+
28+
public function getUpHostByToken($uptoken)
29+
{
30+
list($ak, $bucket) = $this->unmarshalUpToken($uptoken);
31+
list($upHosts,) = $this->getUpHosts($ak, $bucket);
32+
return $upHosts[0];
33+
}
34+
35+
public function getBackupUpHostByToken($uptoken)
36+
{
37+
list($ak, $bucket) = $this->unmarshalUpToken($uptoken);
38+
list($upHosts,) = $this->getUpHosts($ak, $bucket);
39+
return $upHosts[1];
40+
}
41+
42+
public function getIoHost($ak, $bucket)
43+
{
44+
list($bucketHosts,) = $this->getBucketHosts($ak, $bucket);
45+
$ioHosts = $bucketHosts['ioHost'];
46+
if (count($ioHosts) === 0) {
47+
return "";
48+
}
49+
50+
return $ioHosts[0];
51+
}
52+
53+
public function getUpHosts($ak, $bucket)
54+
{
55+
list($bucketHosts, $err) = $this->getBucketHosts($ak, $bucket);
56+
if ($err !== null) {
57+
return array(null, $err);
58+
}
59+
60+
$upHosts = $bucketHosts['upHosts'];
61+
return array($upHosts, null);
62+
}
63+
64+
private function unmarshalUpToken($uptoken)
65+
{
66+
$token = explode(':', $uptoken);
67+
if (count($token) !== 3) {
68+
throw new \Exception("Invalid Uptoken", 1);
69+
}
70+
71+
$ak = $token[0];
72+
$policy = base64_urlSafeDecode($token[2]);
73+
$policy = json_decode($policy, true);
74+
75+
$scope = $policy['scope'];
76+
$bucket = $scope;
77+
78+
if (strpos($scope, ':')) {
79+
$scopes = explode(':', $scope);
80+
$bucket = $scopes[0];
81+
}
82+
83+
return array($ak, $bucket);
84+
}
85+
86+
public function getBucketHosts($ak, $bucket)
87+
{
88+
$key = $this->scheme . $ak . $bucket;
89+
90+
$bucketHosts = $this->getBucketHostsFromCache($key);
91+
if (count($bucketHosts) > 0) {
92+
return array($bucketHosts, null);
93+
}
94+
95+
list($hosts, $err) = $this->bucketHosts($ak, $bucket);
96+
if ($err !== null) {
97+
return array(null , $err);
98+
}
99+
100+
$schemeHosts = $hosts[$this->scheme];
101+
$bucketHosts = array(
102+
'upHosts' => $schemeHosts['up'],
103+
'ioHost' => $schemeHosts['io'],
104+
'deadline' => time() + $hosts['ttl']
105+
);
106+
107+
$this->setBucketHostsToCache($key, $bucketHosts);
108+
return array($bucketHosts, null);
109+
}
110+
111+
private function getBucketHostsFromCache($key)
10112
{
11-
$this->upHost = $upHost;
12-
$this->upHostBackup = $upHostBackup;
113+
$ret = array();
114+
if (count($this->hostCache) === 0) {
115+
return $ret;
116+
}
117+
118+
if (!array_key_exists($key, $this->hostCache)) {
119+
return $ret;
120+
}
121+
122+
if ($this->hostCache[$key]['deadline'] > time()) {
123+
$ret = $this->hostCache[$key];
124+
}
125+
126+
return $ret;
13127
}
14128

15-
public static function zone0()
129+
private function setBucketHostsToCache($key, $val)
16130
{
17-
return new self('http://up.qiniu.com', 'http://upload.qiniu.com');
131+
$this->hostCache[$key] = $val;
132+
return;
18133
}
19134

20-
public static function zone1()
135+
/* 请求包:
136+
* GET /v1/query?ak=<ak>&&bucket=<bucket>
137+
* 返回包:
138+
*
139+
* 200 OK {
140+
* "ttl": <ttl>, // 有效时间
141+
* "http": {
142+
* "up": [],
143+
* "io": [], // 当bucket为global时,我们不需要iohost, io缺省
144+
* },
145+
* "https": {
146+
* "up": [],
147+
* "io": [], // 当bucket为global时,我们不需要iohost, io缺省
148+
* }
149+
* }
150+
**/
151+
private function bucketHosts($ak, $bucket)
21152
{
22-
return new self('http://up-z1.qiniu.com', 'http://upload-z1.qiniu.com');
153+
$url = Config::UC_HOST . '/v1/query' . "?ak=$ak&bucket=$bucket";
154+
$ret = Client::Get($url);
155+
if (!$ret->ok()) {
156+
return array(null, new Error($url, $ret));
157+
}
158+
$r = ($ret->body === null) ? array() : $ret->json();
159+
return array($r, null);
23160
}
24161
}

0 commit comments

Comments
 (0)