Completed
Push — master ( 2756ab...861876 )
by Bai
11s
created

Zone   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 180
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 98.89%

Importance

Changes 18
Bugs 1 Features 3
Metric Value
dl 0
loc 180
ccs 89
cts 90
cp 0.9889
rs 10
c 18
b 1
f 3
wmc 26
lcom 1
cbo 3

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 2
A getUpHostByToken() 0 6 1
A getBackupUpHostByToken() 0 8 2
A getIoHost() 0 6 1
A getUpHosts() 0 10 2
A unmarshalUpToken() 0 21 3
B getBucketHosts() 0 24 3
A getBucketHostsFromCache() 0 17 4
A setBucketHostsToCache() 0 6 1
A hostCacheFromFile() 0 12 2
A hostCacheToFile() 0 6 1
A hostCacheFilePath() 0 5 1
A bucketHosts() 0 10 3
1
<?php
2
namespace Qiniu;
3
4
use Qiniu\Http\Client;
5
use Qiniu\Http\Error;
6
7
final class Zone
8
{
9
    public $ioHost;            // 七牛源站Host
10
    public $upHost;
11
    public $upHostBackup;
12
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 69
    public function __construct($scheme = null)
21
    {
22 69
        $this->hostCache = array();
23 69
        if ($scheme != null) {
24 12
            $this->scheme = $scheme;
25 12
        }
26 69
    }
27
28 21
    public function getUpHostByToken($uptoken)
29
    {
30 21
        list($ak, $bucket) = $this->unmarshalUpToken($uptoken);
31 21
        list($upHosts,) = $this->getUpHosts($ak, $bucket);
32 21
        return $upHosts[0];
33
    }
34
35 3
    public function getBackupUpHostByToken($uptoken)
36
    {
37 3
        list($ak, $bucket) = $this->unmarshalUpToken($uptoken);
38 3
        list($upHosts,) = $this->getUpHosts($ak, $bucket);
39
40 3
        $upHost = isset($upHosts[1]) ? $upHosts[1] : $upHosts[0];
41 3
        return $upHost;
42
    }
43
44 9
    public function getIoHost($ak, $bucket)
45
    {
46 9
        list($bucketHosts,) = $this->getBucketHosts($ak, $bucket);
47 9
        $ioHosts = $bucketHosts['ioHost'];
48 9
        return $ioHosts[0];
49
    }
50
51 27
    public function getUpHosts($ak, $bucket)
52
    {
53 27
        list($bucketHosts, $err) = $this->getBucketHosts($ak, $bucket);
54 27
        if ($err !== null) {
55 3
            return array(null, $err);
56
        }
57
58 24
        $upHosts = $bucketHosts['upHosts'];
59 24
        return array($upHosts, null);
60
    }
61
62 21
    private function unmarshalUpToken($uptoken)
63
    {
64 21
        $token = explode(':', $uptoken);
65 21
        if (count($token) !== 3) {
66
            throw new \Exception("Invalid Uptoken", 1);
67
        }
68
69 21
        $ak = $token[0];
70 21
        $policy = base64_urlSafeDecode($token[2]);
71 21
        $policy = json_decode($policy, true);
72
73 21
        $scope = $policy['scope'];
74 21
        $bucket = $scope;
75
76 21
        if (strpos($scope, ':')) {
77 12
            $scopes = explode(':', $scope);
78 12
            $bucket = $scopes[0];
79 12
        }
80
81 21
        return array($ak, $bucket);
82
    }
83
84 36
    public function getBucketHosts($ak, $bucket)
85
    {
86 36
        $key = $this->scheme . ":$ak:$bucket";
87
88 36
        $bucketHosts = $this->getBucketHostsFromCache($key);
89 36
        if (count($bucketHosts) > 0) {
90 30
            return array($bucketHosts, null);
91
        }
92
93 9
        list($hosts, $err) = $this->bucketHosts($ak, $bucket);
94 9
        if ($err !== null) {
95 3
            return array(null , $err);
96
        }
97
98 6
        $schemeHosts = $hosts[$this->scheme];
99
        $bucketHosts = array(
100 6
            'upHosts' => $schemeHosts['up'],
101 6
            'ioHost' => $schemeHosts['io'],
102 6
            'deadline' => time() + $hosts['ttl']
103 6
        );
104
105 6
        $this->setBucketHostsToCache($key, $bucketHosts);
106 6
        return array($bucketHosts, null);
107
    }
108
109 36
    private function getBucketHostsFromCache($key)
110
    {
111 36
        $ret = array();
112 36
        if (count($this->hostCache) === 0) {
113 36
            $this->hostCacheFromFile();
114 36
        }
115
116 36
        if (!array_key_exists($key, $this->hostCache)) {
117 9
            return $ret;
118
        }
119
120 30
        if ($this->hostCache[$key]['deadline'] > time()) {
121 30
            $ret = $this->hostCache[$key];
122 30
        }
123
124 30
        return $ret;
125
    }
126
127 6
    private function setBucketHostsToCache($key, $val)
128
    {
129 6
        $this->hostCache[$key] = $val;
130 6
        $this->hostCacheToFile();
131 6
        return;
132
    }
133
134 36
    private function hostCacheFromFile()
135
    {
136
137 36
        $path = $this->hostCacheFilePath();
138 36
        if (!file_exists($path)) {
139 6
            return;
140
        }
141
142 30
        $bucketHosts = file_get_contents($path);
143 30
        $this->hostCache = json_decode($bucketHosts, true);
144 30
        return;
145
    }
146
147 6
    private function hostCacheToFile()
148
    {
149 6
        $path = $this->hostCacheFilePath();
150 6
        file_put_contents($path, json_encode($this->hostCache), LOCK_EX);
151 6
        return;
152
    }
153
154 36
    private function hostCacheFilePath()
155
    {
156 36
        $home = getenv('HOME');
157 36
        return $home . '/.qiniu_phpsdk_hostscache.json';
158
    }
159
160
    /*  请求包:
161
     *   GET /v1/query?ak=<ak>&&bucket=<bucket>
162
     *  返回包:
163
     *  
164
     *  200 OK {
165
     *    "ttl": <ttl>,              // 有效时间
166
     *    "http": {
167
     *      "up": [],
168
     *      "io": [],                // 当bucket为global时,我们不需要iohost, io缺省
169
     *    },
170
     *    "https": {
171
     *      "up": [],
172
     *      "io": [],                // 当bucket为global时,我们不需要iohost, io缺省
173
     *    }
174
     *  }
175
     **/
176 9
    private function bucketHosts($ak, $bucket)
177
    {
178 9
        $url = Config::UC_HOST . '/v1/query' . "?ak=$ak&bucket=$bucket";
179 9
        $ret = Client::Get($url);
180 9
        if (!$ret->ok()) {
181 3
            return array(null, new Error($url, $ret));
182
        }
183 6
        $r = ($ret->body === null) ? array() : $ret->json();
184 6
        return array($r, null);
185
    }
186
}
187