Passed
Pull Request — master (#77)
by Mark
10:16 queued 02:30
created

HttpChecker::getResourceUrlArray()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 8
ccs 3
cts 4
cp 0.75
crap 2.0625
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace PragmaRX\Health\Checkers;
4
5
use GuzzleHttp\TransferStats;
6
use GuzzleHttp\Client as Guzzle;
7
use Illuminate\Support\Collection;
8
9
class HttpChecker extends BaseChecker
10
{
11
    /**
12
     * @var bool
13
     */
14
    protected $secure = false;
15
16
    /**
17
     * @var
18
     */
19
    protected $guzzle;
20
21
    /**
22
     * @var
23
     */
24
    private $totalTime;
25
26
    /**
27
     * @var
28
     */
29
    private $url;
30
31
    /**
32
     * HTTP Checker.
33
     *
34
     * @return bool
35
     */
36 6
    public function check()
37
    {
38
        try {
39 6
            $health = [];
40
41 6
            foreach ($this->getResourceUrlArray() as $url) {
42 6
                list($healthy, $message) = $this->checkWebPage(
43 6
                    $this->makeUrlWithScheme($url, $this->secure),
44 6
                    $this->secure
45
                );
46
47 6
                $health[] = $this->makeResult($healthy, $message);
48
            }
49
50 6
            return $health;
51 6
        } catch (\Exception $exception) {
52 6
            return $this->makeResultFromException($exception);
53
        }
54
    }
55
56
    /**
57
     *  Get array of resource urls.
58
     *
59
     * @return array
60
     */
61 6
    private function getResourceUrlArray()
62
    {
63 6
        if (is_a($this->resource['url'], Collection::class)) {
64
            return $this->resource['url']->toArray();
65
        }
66
67 6
        return (array) $this->resource['url'];
68
    }
69
70
    /**
71
     *  Check web pages.
72
     *
73
     * @param $url
74
     * @param bool $ssl
75
     * @return mixed
76
     */
77 6
    private function checkWebPage($url, $ssl = false)
78
    {
79 6
        $success = $this->requestSuccessful($url, $ssl);
80
81
        return [
82 6
            $success,
83 6
            $success ? '' : $this->getErrorMessage(),
84
        ];
85
    }
86
87
    /**
88
     * Send an http request and fetch the response.
89
     *
90
     * @param $url
91
     * @param $ssl
92
     * @return mixed|\Psr\Http\Message\ResponseInterface
93
     */
94 6
    private function fetchResponse($url, $ssl)
95
    {
96 6
        $this->url = $url;
97
98 6
        return (new Guzzle())->request(
99 6
            'GET',
100 6
            $this->url,
101 6
            $this->getConnectionOptions($ssl)
102
        );
103
    }
104
105
    /**
106
     * Get http connection options.
107
     *
108
     * @param $ssl
109
     * @return array
110
     */
111 6
    private function getConnectionOptions($ssl)
112
    {
113
        return [
114 6
            'connect_timeout' => $this->getConnectionTimeout(),
115 6
            'timeout' => $this->getConnectionTimeout(),
116 6
            'verify' => $ssl,
117 6
            'on_stats' => $this->onStatsCallback(),
118
        ];
119
    }
120
121
    /**
122
     * Get the error message.
123
     *
124
     * @return string
125
     */
126
    private function getErrorMessage()
127
    {
128
        $message = array_get($this->resource, 'timeout_message') ?:
129
                    '[TIMEOUT] A request to %s took %s seconds. Timeout is set to %s seconds.';
130
131
        return sprintf(
132
            $message,
133
            $this->url,
134
            $this->totalTime,
135
            $this->getRoundtripTimeout()
136
        );
137
    }
138
139
    /**
140
     * The the connection timeout.
141
     *
142
     * @return int
143
     */
144 6
    private function getConnectionTimeout()
145
    {
146 6
        return array_get($this->resource, 'connection_timeout') ?: 30;
147
    }
148
149
    /**
150
     * The the roundtrip timeout.
151
     *
152
     * @return int
153
     */
154 6
    private function getRoundtripTimeout()
155
    {
156 6
        return array_get($this->resource, 'roundtrip_timeout') ?: 30;
157
    }
158
159
    /**
160
     * Make a url with a proper scheme.
161
     *
162
     * @param $url
163
     * @param $secure
164
     * @return mixed
165
     */
166 6
    private function makeUrlWithScheme($url, $secure)
167
    {
168 6
        return preg_replace('|^((https?:)?\/\/)?(.*)|', 'http'.($secure ? 's' : '').'://\\3', $url);
169
    }
170
171
    /**
172
     * Guzzle OnStats callback.
173
     *
174
     * @return \Closure
175
     */
176
    private function onStatsCallback()
177
    {
178 6
        return function (TransferStats $stats) {
179 6
            $this->totalTime = $stats->getTransferTime();
180 6
        };
181
    }
182
183
    /**
184
     * Send a request and get the result.
185
     *
186
     * @param $url
187
     * @param $ssl
188
     * @return bool
189
     * @internal param $response
190
     */
191 6
    private function requestSuccessful($url, $ssl)
192
    {
193 6
        return $this->fetchResponse($url, $ssl)->getStatusCode() == 200 &&
194 6
                ! $this->requestTimedout();
195
    }
196
197
    /**
198
     * Check if the request timed out.
199
     *
200
     * @return bool
201
     */
202 6
    private function requestTimedout()
203
    {
204 6
        return $this->totalTime > $this->getRoundtripTimeout();
205
    }
206
}
207