-
Notifications
You must be signed in to change notification settings - Fork 0
/
FetchStatusCodes.php
80 lines (61 loc) · 2.05 KB
/
FetchStatusCodes.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<?php declare(strict_types=1);
use React\Promise\Deferred;
class FetchStatusCodes extends Deferred
{
public function __invoke(array $urls)
{
$multiHandle = curl_multi_init();
$handles = $this->getHandlesForUrls($urls, $multiHandle);
$this->executeMultiHandle($multiHandle);
$statusCodes = $this->getStatusCodes($handles);
curl_multi_close($multiHandle);
$successRate = $this->calculateSuccessRate($statusCodes);
if ($successRate > 20) {
$this->resolve($statusCodes);
} else {
$this->reject('Success rate too low: ' . $successRate);
}
}
private function getHandlesForUrls(array $urls, $multiHandle): array
{
$handles = [];
foreach ($urls as $url) {
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_NOBODY, 1);
curl_setopt($handle, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 5);
$handles[] = $handle;
curl_multi_add_handle($multiHandle, $handle);
}
return $handles;
}
private function executeMultiHandle($multiHandle): void
{
$active = 0;
do {
curl_multi_exec($multiHandle, $active);
curl_multi_select($multiHandle);
} while ($active);
}
private function getStatusCodes(array $handles): array
{
$statusCodes = [];
foreach ($handles as $handle) {
$result = curl_getinfo($handle);
$statusCodes[$result['url']] = $result['http_code'];
}
return $statusCodes;
}
private function calculateSuccessRate(array $statusCodes): int
{
$successCodes = array_filter($statusCodes, function ($code) {
if ($code >= 200 && $code < 300) {
return true;
}
return false;
});
$percent = (count($successCodes) * 100) / count($statusCodes);
return (int) round($percent);
}
}