PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backups, Restore, Migration & Clone / trunk
WP STAGING – WordPress Backups, Restore, Migration & Clone vtrunk
4.12.0 4.11.2 4.11.1 4.11.0 4.10.0 4.9.5 4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Framework / Traits / ThrottledResponseTrait.php
wp-staging / Framework / Traits Last commit date
ApplyFiltersTrait.php 2 weeks ago ArrayableTrait.php 2 weeks ago BatchSizeCalculateTrait.php 2 weeks ago BearerTokenTrait.php 2 weeks ago BenchmarkTrait.php 2 weeks ago BooleanTransientTrait.php 2 weeks ago DatabaseSearchReplaceTrait.php 1 week ago DbRowsGeneratorTrait.php 2 weeks ago DebugLogTrait.php 2 weeks ago DeveloperTimerTrait.php 2 weeks ago EndOfLinePlaceholderTrait.php 2 weeks ago EventLoggerTrait.php 2 weeks ago FileScanToCacheTrait.php 2 weeks ago FormatTrait.php 2 weeks ago HttpRequestTrait.php 1 week ago HydrateTrait.php 2 weeks ago I18nTrait.php 2 weeks ago IpResolverTrait.php 2 weeks ago JobResponseTrait.php 2 weeks ago MaintenanceTrait.php 7 months ago MemoryExhaustTrait.php 2 weeks ago MySQLRowsGeneratorTrait.php 2 weeks ago NoticesTrait.php 2 weeks ago PagesTrait.php 15 hours ago PropertyConstructor.php 2 weeks ago RenameTmpDirectoryTrait.php 2 weeks ago ResourceTrait.php 1 week ago RestRequestTrait.php 2 weeks ago RestoreFileExclusionTrait.php 2 weeks ago RestoresPreservedOptionsTrait.php 15 hours ago SafeFileInfoTrait.php 2 weeks ago SerializeTrait.php 1 week ago SetTimeLimitTrait.php 2 weeks ago SlashTrait.php 2 weeks ago SqlCommentTrait.php 2 weeks ago TablePrefixValidator.php 5 months ago ThrottledResponseTrait.php 1 week ago UrlTrait.php 2 weeks ago ValueGetterTrait.php 2 weeks ago WindowsOsTrait.php 2 weeks ago WordPressOptionNameTrait.php 1 week ago
ThrottledResponseTrait.php
147 lines
1 <?php
2
3 namespace WPStaging\Framework\Traits;
4
5
6
7
8
9
10
11
12 trait ThrottledResponseTrait
13 {
14
15
16
17
18 protected function isThrottledResponse($response): bool
19 {
20 if (is_wp_error($response)) {
21 return false;
22 }
23
24 $responseCode = (int)wp_remote_retrieve_response_code($response);
25 if (in_array($responseCode, [429, 503], true)) {
26 return true;
27 }
28
29 if ($responseCode !== 403) {
30 return false;
31 }
32
33 return $this->reportsRateLimit(wp_remote_retrieve_body($response));
34 }
35
36
37
38
39
40 protected function reportsRateLimit(string $message): bool
41 {
42 $reasons = [
43 'userRateLimitExceeded',
44 'rateLimitExceeded',
45 'SlowDown',
46 'too_many_requests',
47 'too_many_write_operations',
48 ];
49
50 foreach ($reasons as $reason) {
51 if (stripos($message, $reason) !== false) {
52 return true;
53 }
54 }
55
56 return false;
57 }
58
59
60
61
62
63
64
65
66 protected function requestUntilNotThrottled(string $url, array $args)
67 {
68 $response = wp_remote_request($url, $args);
69
70 for ($attempt = 1; $attempt <= $this->getMaxThrottleRetries(); $attempt++) {
71 if (!$this->isThrottledResponse($response)) {
72 return $response;
73 }
74
75 if (!$this->waitForThrottleToPass($response, $attempt)) {
76 return $response;
77 }
78
79 $response = wp_remote_request($url, $args);
80 }
81
82 return $response;
83 }
84
85
86
87
88
89
90 protected function postUntilNotThrottled(string $url, array $args)
91 {
92 $args['method'] = 'POST';
93
94 return $this->requestUntilNotThrottled($url, $args);
95 }
96
97
98
99
100 protected function getMaxThrottleRetries(): int
101 {
102 return 3;
103 }
104
105
106
107
108
109 protected function getRequestedWaitSeconds($response): int
110 {
111 if (is_wp_error($response)) {
112 return 0;
113 }
114
115 $retryAfter = wp_remote_retrieve_header($response, 'retry-after');
116 if (is_array($retryAfter)) {
117 $retryAfter = reset($retryAfter);
118 }
119
120 return (int)$retryAfter;
121 }
122
123
124
125
126
127
128
129
130 protected function waitForThrottleToPass($response, int $attempt): bool
131 {
132 $backoffSeconds = 2;
133 $maxWaitSeconds = 10;
134
135 $requestedWait = $this->getRequestedWaitSeconds($response);
136 $waitSeconds = $requestedWait > 0 ? $requestedWait : $attempt * $backoffSeconds;
137
138 if ($waitSeconds > $maxWaitSeconds) {
139 return false;
140 }
141
142 sleep($waitSeconds);
143
144 return true;
145 }
146 }
147