Test Failed
Pull Request — master (#154)
by Antonio Carlos
04:56 queued 02:28
created

src/Checkers/Http.php (4 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
use PragmaRX\Health\Support\Result;
9
10
class Http extends Base
11
{
12
    /**
13
     * @return Result
14
     */
15
    protected $secure = false;
16
17
    /**
18
     * @var
19
     */
20
    protected $guzzle;
21
22
    /**
23
     * @var
24
     */
25
    private $totalTime;
26
27
    /**
28
     * @var
29
     */
30
    private $url;
31
32
    /**
33
     * HTTP Checker.
34
     *
35
     * @return Result
36
     */
37
    public function check()
38
    {
39
        try {
40
            $health = [];
41
42
            foreach ($this->getResourceUrlArray() as $url) {
43
                [$healthy, $message] = $this->checkWebPage(
0 ignored issues
show
The variable $healthy does not exist. Did you mean $health?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
The variable $message does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
44
                    $this->makeUrlWithScheme($url, $this->secure),
45
                    $this->secure
46
                );
47
48
                if (! $healthy) {
0 ignored issues
show
The variable $healthy does not exist. Did you mean $health?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
49
                    return $this->makeResult($healthy, $message);
0 ignored issues
show
The variable $healthy does not exist. Did you mean $health?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
50
                }
51
            }
52
53
            return $this->makeHealthyResult();
54
        } catch (\Exception $exception) {
55
            report($exception);
56
57
            return $this->makeResultFromException($exception);
58
        }
59
    }
60
61
    /**
62
     *  Get array of resource urls.
63
     *
64
     * @return array
65
     */
66
    private function getResourceUrlArray()
67
    {
68
        if (is_a($this->target->urls, Collection::class)) {
69
            return $this->target->urls->toArray();
70
        }
71
72
        return (array) $this->target->urls;
73
    }
74
75
    /**
76
     *  Check web pages.
77
     *
78
     * @param $url
79
     * @param bool $ssl
80
     * @return mixed
81
     */
82
    private function checkWebPage($url, $ssl = false)
83
    {
84
        $success = $this->requestSuccessful($url, $ssl);
85
86
        return [$success, $success ? '' : $this->getErrorMessage()];
87
    }
88
89
    /**
90
     * Send an http request and fetch the response.
91
     *
92
     * @param $url
93
     * @param $ssl
94
     * @return mixed|\Psr\Http\Message\ResponseInterface
95
     * @throws \GuzzleHttp\Exception\GuzzleException
96
     */
97
    private function fetchResponse($url, $ssl)
98
    {
99
        $this->url = $url;
100
101
        return (new Guzzle())->request(
102
            'GET',
103
            $this->url,
104
            $this->getConnectionOptions($ssl)
105
        );
106
    }
107
108
    /**
109
     * Get http connection options.
110
     *
111
     * @param $ssl
112
     * @return array
113
     */
114
    private function getConnectionOptions($ssl)
115
    {
116
        return [
117
            'connect_timeout' => $this->getConnectionTimeout(),
118
            'timeout' => $this->getConnectionTimeout(),
119
            'verify' => $ssl,
120
            'on_stats' => $this->onStatsCallback(),
121
        ];
122
    }
123
124
    /**
125
     * Get the error message.
126
     *
127
     * @return string
128
     */
129
    private function getErrorMessage()
130
    {
131
        $message = $this->target->resource->timeoutMessage;
132
133
        return sprintf(
134
            $message,
135
            $this->url,
136
            $this->totalTime,
137
            $this->getRoundtripTimeout()
138
        );
139
    }
140
141
    /**
142
     * The the connection timeout.
143
     *
144
     * @return int
145
     */
146
    private function getConnectionTimeout()
147
    {
148
        return $this->target->resource->connectionTimeout;
149
    }
150
151
    /**
152
     * The the roundtrip timeout.
153
     *
154
     * @return int
155
     */
156
    private function getRoundtripTimeout()
157
    {
158
        return $this->target->resource->roundtripTimeout;
159
    }
160
161
    /**
162
     * Make a url with a proper scheme.
163
     *
164
     * @param $url
165
     * @param $secure
166
     * @return mixed
167
     */
168
    private function makeUrlWithScheme($url, $secure)
169
    {
170
        return preg_replace(
171
            '|^((https?:)?\/\/)?(.*)|',
172
            'http'.($secure ? 's' : '').'://\\3',
173
            $url
174
        );
175
    }
176
177
    /**
178
     * Guzzle OnStats callback.
179
     *
180
     * @return \Closure
181
     */
182
    private function onStatsCallback()
183
    {
184
        return function (TransferStats $stats) {
185
            $this->totalTime = $stats->getTransferTime();
186
        };
187
    }
188
189
    /**
190
     * Send a request and get the result.
191
     *
192
     * @param $url
193
     * @param $ssl
194
     * @return bool
195
     * @internal param $response
196
     */
197
    private function requestSuccessful($url, $ssl)
198
    {
199
        return
200
            $this->fetchResponse($url, $ssl)->getStatusCode() == 200 &&
201
            ! $this->requestTimedout();
202
    }
203
204
    /**
205
     * Check if the request timed out.
206
     *
207
     * @return bool
208
     */
209
    private function requestTimedout()
210
    {
211
        return $this->totalTime > $this->getRoundtripTimeout();
212
    }
213
}
214