Completed
Push — master ( d61801...46edea )
by Biao
05:21
created

SimpleHttpTrait::httpGet()   D

Complexity

Conditions 18
Paths 62

Size

Total Lines 71
Code Lines 54

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 18
eloc 54
c 1
b 0
f 0
nc 62
nop 2
dl 0
loc 71
rs 4.8666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Hhxsv5\LaravelS\Components\HttpClient;
4
5
use Hhxsv5\LaravelS\Swoole\Coroutine\Context;
6
use Swoole\Coroutine\Http\Client as CoroutineClient;
7
8
trait SimpleHttpTrait
9
{
10
    protected $curlOptions = [
11
        //bool
12
        CURLOPT_HEADER         => true,
13
        CURLOPT_FOLLOWLOCATION => true,
14
        CURLOPT_RETURNTRANSFER => true,
15
16
        //int
17
        CURLOPT_MAXREDIRS      => 3,
18
        CURLOPT_TIMEOUT        => 5,
19
        CURLOPT_CONNECTTIMEOUT => 3,
20
    ];
21
22
    /**
23
     * Sends a GET request and returns a array response.
24
     * @param string $url
25
     * @param array $options
26
     * @return array
27
     */
28
    public function httpGet($url, array $options)
29
    {
30
        if (Context::inCoroutine()) {
31
            $parts = parse_url($url);
32
            $path = isset($parts['path']) ? $parts['path'] : '/';
33
            if (isset($parts['query'])) {
34
                $path .= '?' . $parts['query'];
35
            }
36
            if (isset($parts['fragment'])) {
37
                $path .= '#' . $parts['fragment'];
38
            }
39
            $client = new CoroutineClient($parts['host'], isset($parts['port']) ? $parts['port'] : 80, isset($parts['scheme']) && $parts['scheme'] === 'https');
40
            if (isset($options['timeout'])) {
41
                $client->set([
42
                    'timeout' => $options['timeout'],
43
                ]);
44
            }
45
            $client->get($path);
46
            $client->close();
47
            if ($client->errCode === 110) {
48
                return ['statusCode' => 0, 'headers' => [], 'body' => ''];
49
            }
50
            if ($client->errCode !== 0) {
51
                $msg = sprintf('Failed to send Http request(%s), errcode=%d, errmsg=%s', $url, $client->errCode, $client->errMsg);
0 ignored issues
show
Bug introduced by
The property errMsg does not seem to exist on Swoole\Coroutine\Http\Client.
Loading history...
52
                throw new \RuntimeException($msg, $client->errCode);
53
            }
54
            return ['statusCode' => $client->statusCode, 'headers' => $client->headers, 'body' => $client->body];
55
        } else {
56
            $handle = curl_init();
57
            $finalOptions = [
58
                    CURLOPT_URL     => $url,
59
                    CURLOPT_HTTPGET => true,
60
                ] + $this->curlOptions;
61
            if (isset($options['timeout'])) {
62
                $finalOptions[CURLOPT_TIMEOUT] = $options['timeout'];
63
            }
64
            curl_setopt_array($handle, $finalOptions);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $ch of curl_setopt_array() does only seem to accept resource, 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

64
            curl_setopt_array(/** @scrutinizer ignore-type */ $handle, $finalOptions);
Loading history...
65
            $responseStr = curl_exec($handle);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $ch of curl_exec() does only seem to accept resource, 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

65
            $responseStr = curl_exec(/** @scrutinizer ignore-type */ $handle);
Loading history...
66
            $errno = curl_errno($handle);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $ch of curl_errno() does only seem to accept resource, 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

66
            $errno = curl_errno(/** @scrutinizer ignore-type */ $handle);
Loading history...
67
            $errmsg = curl_error($handle);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $ch of curl_error() does only seem to accept resource, 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

67
            $errmsg = curl_error(/** @scrutinizer ignore-type */ $handle);
Loading history...
68
            // Fix: curl_errno() always return 0 when fail
69
            if ($errno !== 0 || $errmsg !== '') {
70
                curl_close($handle);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $ch of curl_close() does only seem to accept resource, 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

70
                curl_close(/** @scrutinizer ignore-type */ $handle);
Loading history...
71
                $msg = sprintf('Failed to send Http request(%s), errcode=%d, errmsg=%s', $url, $errno, $errmsg);
72
                throw new \RuntimeException($msg, $errno);
73
            }
74
75
            $headerSize = curl_getinfo($handle, CURLINFO_HEADER_SIZE);
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $ch of curl_getinfo() does only seem to accept resource, 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

75
            $headerSize = curl_getinfo(/** @scrutinizer ignore-type */ $handle, CURLINFO_HEADER_SIZE);
Loading history...
76
            $statusCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
77
            curl_close($handle);
78
79
            $header = substr($responseStr, 0, $headerSize);
80
            $body = substr($responseStr, $headerSize);
81
            $lines = explode("\n", $header);
82
            array_shift($lines); // Remove status
83
84
            $headers = [];
85
            foreach ($lines as $part) {
86
                $middle = explode(':', $part);
87
                $key = trim($middle[0]);
88
                if ($key === '') {
89
                    continue;
90
                }
91
                if (isset($headers[$key])) {
92
                    $headers[$key] = (array)$headers[$key];
93
                    $headers[$key][] = isset($middle[1]) ? trim($middle[1]) : '';
94
                } else {
95
                    $headers[$key] = isset($middle[1]) ? trim($middle[1]) : '';
96
                }
97
            }
98
            return ['statusCode' => $statusCode, 'headers' => $headers, 'body' => $body];
99
        }
100
    }
101
}