Completed
Push — master ( d1bca4...94350e )
by Bai
10s
created

Zone   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 92%

Importance

Changes 14
Bugs 1 Features 2
Metric Value
c 14
b 1
f 2
dl 0
loc 155
ccs 69
cts 75
cp 0.92
rs 10
wmc 22
lcom 1
cbo 3

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 2
A getUpHostByToken() 0 6 1
A getBackupUpHostByToken() 0 6 1
A getIoHost() 0 10 2
A getUpHosts() 0 10 2
A unmarshalUpToken() 0 21 3
B getBucketHosts() 0 24 3
A getBucketHostsFromCache() 0 17 4
A setBucketHostsToCache() 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 63
    public function __construct($scheme = null)
21
    {
22 63
        $this->hostCache = array();
23 63
        if ($scheme != null) {
24 6
            $this->scheme = $scheme;
25 4
        }
26 63
    }
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 6
    public function getIoHost($ak, $bucket)
43
    {
44 6
        list($bucketHosts,) = $this->getBucketHosts($ak, $bucket);
45 6
        $ioHosts = $bucketHosts['ioHost'];
46 6
        if (count($ioHosts) === 0) {
47
            return "";
48
        }
49
50 6
        return $ioHosts[0];
51
    }
52
53 24
    public function getUpHosts($ak, $bucket)
54
    {
55 24
        list($bucketHosts, $err) = $this->getBucketHosts($ak, $bucket);
56 24
        if ($err !== null) {
57 3
            return array(null, $err);
58
        }
59
60 21
        $upHosts = $bucketHosts['upHosts'];
61 21
        return array($upHosts, null);
62
    }
63
64 18
    private function unmarshalUpToken($uptoken)
65
    {
66 18
        $token = explode(':', $uptoken);
67 18
        if (count($token) !== 3) {
68
            throw new \Exception("Invalid Uptoken", 1);
69
        }
70
71 18
        $ak = $token[0];
72 18
        $policy = base64_urlSafeDecode($token[2]);
73 18
        $policy = json_decode($policy, true);
74
75 18
        $scope = $policy['scope'];
76 18
        $bucket = $scope;
77
78 18
        if (strpos($scope, ':')) {
79 12
            $scopes = explode(':', $scope);
80 12
            $bucket = $scopes[0];
81 8
        }
82
83 18
        return array($ak, $bucket);
84
    }
85
86 30
    public function getBucketHosts($ak, $bucket)
87
    {
88 30
        $key = $this->scheme . $ak . $bucket;
89
90 30
        $bucketHosts = $this->getBucketHostsFromCache($key);
91 30
        if (count($bucketHosts) > 0) {
92 3
            return array($bucketHosts, null);
93
        }
94
95 30
        list($hosts, $err) = $this->bucketHosts($ak, $bucket);
96 30
        if ($err !== null) {
97 3
            return array(null , $err);
98
        }
99
100 27
        $schemeHosts = $hosts[$this->scheme];
101
        $bucketHosts = array(
102 27
            'upHosts' => $schemeHosts['up'],
103 27
            'ioHost' => $schemeHosts['io'],
104 27
            'deadline' => time() + $hosts['ttl']
105 18
        );
106
107 27
        $this->setBucketHostsToCache($key, $bucketHosts);
108 27
        return array($bucketHosts, null);
109
    }
110
111 30
    private function getBucketHostsFromCache($key)
112
    {
113 30
        $ret = array();
114 30
        if (count($this->hostCache) === 0) {
115 30
            return $ret;
116
        }
117
118 6
        if (!array_key_exists($key, $this->hostCache)) {
119 3
            return $ret;
120
        }
121
122 3
        if ($this->hostCache[$key]['deadline'] > time()) {
123 3
            $ret = $this->hostCache[$key];
124 2
        }
125
126 3
        return $ret;
127
    }
128
129 27
    private function setBucketHostsToCache($key, $val)
130
    {
131 27
        $this->hostCache[$key] = $val;
132 27
        return;
133
    }
134
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 30
    private function bucketHosts($ak, $bucket)
152
    {
153 30
        $url = Config::UC_HOST . '/v1/query' . "?ak=$ak&bucket=$bucket";
154 30
        $ret = Client::Get($url);
155 30
        if (!$ret->ok()) {
156 3
            return array(null, new Error($url, $ret));
157
        }
158 27
        $r = ($ret->body === null) ? array() : $ret->json();
159 27
        return array($r, null);
160
    }
161
}
162