Client   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 189
Duplicated Lines 0 %

Test Coverage

Coverage 94.12%

Importance

Changes 6
Bugs 1 Features 2
Metric Value
eloc 82
c 6
b 1
f 2
dl 0
loc 189
ccs 96
cts 102
cp 0.9412
rs 10
wmc 19

9 Methods

Rating   Name   Duplication   Size   Complexity  
A userAgent() 0 13 1
A post() 0 4 1
A get() 0 4 1
A PUT() 0 4 1
A sendRequestWithMiddleware() 0 7 1
A delete() 0 4 1
A multipartPost() 0 36 3
A escapeQuotes() 0 8 2
B sendRequest() 0 46 8
1
<?php
2
3
namespace Qiniu\Http;
4
5
use Qiniu\Config;
6
use Qiniu\Http\Middleware;
7
8
final class Client
9
{
10 69
    /**
11
     * @param $url
12 69
     * @param array $headers
13 69
     * @param RequestOptions $opt
14
     * @return Response
15
     */
16
    public static function get($url, array $headers = array(), $opt = null)
17
    {
18
        $request = new Request('GET', $url, $headers, null, $opt);
19
        return self::sendRequestWithMiddleware($request);
20
    }
21
22 57
    /**
23
     * @param $url
24 57
     * @param array $headers
25 57
     * @param array $opt detail see {@see Request::$opt}
26
     * @return Response
27
     */
28
    public static function delete($url, array $headers = array(), $opt = null)
29
    {
30
        $request = new Request('DELETE', $url, $headers, null, $opt);
31
        return self::sendRequest($request);
32
    }
33
34 9
    /**
35
     * @param $url
36
     * @param $body
37
     * @param array $headers
38
     * @param RequestOptions $opt
39
     * @return Response
40
     */
41
    public static function post($url, $body, array $headers = array(), $opt = null)
42
    {
43 9
        $request = new Request('POST', $url, $headers, $body, $opt);
44 9
        return self::sendRequest($request);
45
    }
46 9
47 9
    /**
48 9
     * @param $url
49 9
     * @param $body
50 9
     * @param array $headers
51 9
     * @param RequestOptions $opt
52
     * @return Response
53 9
     */
54 9
    public static function PUT($url, $body, array $headers = array(), $opt = null)
55 9
    {
56 9
        $request = new Request('PUT', $url, $headers, $body, $opt);
57 9
        return self::sendRequest($request);
58 9
    }
59 9
60
    /**
61 9
     * @param $url
62 9
     * @param array $fields
63
     * @param string $name
64 9
     * @param string $fileName
65
     * @param $fileBody
66 9
     * @param null $mimeType
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $mimeType is correct as it would always require null to be passed?
Loading history...
67 9
     * @param array $headers
68 9
     * @param RequestOptions $opt
69 9
     * @return Response
70
     */
71
    public static function multipartPost(
72 102
        $url,
73
        $fields,
74 102
        $name,
75
        $fileName,
76 102
        $fileBody,
77 102
        $mimeType = null,
78
        $headers = array(),
79 102
        $opt = null
80
    ) {
81 102
        $data = array();
82
        $mimeBoundary = md5(microtime());
83 102
84 102
        foreach ($fields as $key => $val) {
85
            array_push($data, '--' . $mimeBoundary);
86
            array_push($data, "Content-Disposition: form-data; name=\"$key\"");
87 102
            array_push($data, '');
88
            array_push($data, $val);
89 102
        }
90 102
91
        array_push($data, '--' . $mimeBoundary);
92 102
        $finalMimeType = empty($mimeType) ? 'application/octet-stream' : $mimeType;
93 102
        $finalFileName = self::escapeQuotes($fileName);
94 102
        array_push($data, "Content-Disposition: form-data; name=\"$name\"; filename=\"$finalFileName\"");
95 102
        array_push($data, "Content-Type: $finalMimeType");
96 102
        array_push($data, '');
97 102
        array_push($data, $fileBody);
98 102
99 102
        array_push($data, '--' . $mimeBoundary . '--');
100 102
        array_push($data, '');
101
102 102
        $body = implode("\r\n", $data);
103 102
        $contentType = 'multipart/form-data; boundary=' . $mimeBoundary;
104 102
        $headers['Content-Type'] = $contentType;
105 102
        $request = new Request('POST', $url, $headers, $body, $opt);
106 69
        return self::sendRequest($request);
107 69
    }
108 69
109 69
    private static function userAgent()
110 69
    {
111 69
        $sdkInfo = "QiniuPHP/" . Config::SDK_VER;
112 102
113 102
        $systemInfo = php_uname("s");
114 39
        $machineInfo = php_uname("m");
115 39
116 102
        $envInfo = "($systemInfo/$machineInfo)";
117 102
118 102
        $phpVer = phpversion();
119 102
120 102
        $ua = "$sdkInfo $envInfo PHP/$phpVer";
121 102
        return $ua;
122 3
    }
123 3
124 3
    /**
125
     * @param Request $request
126 102
     * @return Response
127 102
     */
128 102
    public static function sendRequestWithMiddleware($request)
129 102
    {
130 102
        $middlewares = $request->opt->middlewares;
131 102
        $handle = Middleware\compose($middlewares, function ($req) {
132
            return Client::sendRequest($req);
133
        });
134 102
        return $handle($request);
135
    }
136 102
137 102
    /**
138 102
     * @param Request $request
139 102
     * @return Response
140 102
     */
141 102
    public static function sendRequest($request)
142 102
    {
143 102
        $t1 = microtime(true);
144 102
        $ch = curl_init();
145 102
        $options = array(
146 102
            CURLOPT_USERAGENT => self::userAgent(),
147
            CURLOPT_RETURNTRANSFER => true,
148
            CURLOPT_HEADER => true,
149 9
            CURLOPT_NOBODY => false,
150
            CURLOPT_CUSTOMREQUEST => $request->method,
151 9
            CURLOPT_URL => $request->url,
152 9
        );
153 9
        foreach ($request->opt->getCurlOpt() as $k => $v) {
154
            $options[$k] = $v;
155
        }
156 102
        // Handle open_basedir & safe mode
157
        if (!ini_get('safe_mode') && !ini_get('open_basedir')) {
158 102
            $options[CURLOPT_FOLLOWLOCATION] = true;
159
        }
160
        if (!empty($request->headers)) {
161
            $headers = array();
162
            foreach ($request->headers as $key => $val) {
163
                array_push($headers, "$key: $val");
164
            }
165
            $options[CURLOPT_HTTPHEADER] = $headers;
166
        }
167
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
168
        if (!empty($request->body)) {
169
            $options[CURLOPT_POSTFIELDS] = $request->body;
170
        }
171
        curl_setopt_array($ch, $options);
172
        $result = curl_exec($ch);
173
        $t2 = microtime(true);
174
        $duration = round($t2 - $t1, 3);
175
        $ret = curl_errno($ch);
176
        if ($ret !== 0) {
177
            $r = new Response(-1, $duration, array(), null, curl_error($ch));
178
            curl_close($ch);
179
            return $r;
180
        }
181
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
182
        $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
183
        $headers = Header::parseRawText(substr($result, 0, $header_size));
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type true; however, parameter $string of substr() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

183
        $headers = Header::parseRawText(substr(/** @scrutinizer ignore-type */ $result, 0, $header_size));
Loading history...
184
        $body = substr($result, $header_size);
185
        curl_close($ch);
186
        return new Response($code, $duration, $headers, $body, null);
187
    }
188
189
    private static function escapeQuotes($str)
190
    {
191
        if (is_null($str)) {
192
            return null;
193
        }
194
        $find = array("\\", "\"");
195
        $replace = array("\\\\", "\\\"");
196
        return str_replace($find, $replace, $str);
197
    }
198
}
199