Completed
Push — master ( 94350e...2756ab )
by Bai
16:19 queued 14:10
created

Zone   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 178
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 94.38%

Importance

Changes 17
Bugs 1 Features 2
Metric Value
c 17
b 1
f 2
dl 0
loc 178
ccs 84
cts 89
cp 0.9438
rs 10
wmc 25
lcom 1
cbo 3

13 Methods

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