PreloadUrl.php
6.1 KB
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
<?php
namespace WP_Rocket\Engine\Preload\Controller;
use WP_Rocket\Admin\Options_Data;
use WP_Rocket\Engine\Preload\Database\Queries\Cache;
use WP_Filesystem_Direct;
class PreloadUrl {
use CheckExcludedTrait;
/**
* Preload queue.
*
* @var Queue
*/
protected $queue;
/**
* Preload database query.
*
* @var Cache
*/
protected $query;
/**
* Configurations options.
*
* @var Options_Data
*/
protected $options;
/**
* Filesystem.
*
* @var WP_Filesystem_Direct
*/
protected $filesystem;
/**
* Instantiate preload controller.
*
* @param Options_Data $options configuration options.
* @param Queue $queue preload queue.
* @param Cache $rocket_cache preload database query.
* @param WP_Filesystem_Direct $filesystem Filesystem.
*/
public function __construct( Options_Data $options, Queue $queue, Cache $rocket_cache, WP_Filesystem_Direct $filesystem ) {
$this->options = $options;
$this->query = $rocket_cache;
$this->queue = $queue;
$this->filesystem = $filesystem;
}
/**
* Preload an url.
*
* @param string $url url to preload.
* @return void
*/
public function preload_url( string $url ) {
$is_mobile = $this->options->get( 'do_caching_mobile_files', false );
if ( $this->is_already_cached( $url ) && ( ! $is_mobile || $this->is_already_cached( $url, true ) ) ) {
$this->query->make_status_complete( $url );
return;
}
$requests = [
[
'url' => $url,
'is_mobile' => false,
'headers' => [
'blocking' => false,
'timeout' => 0.01,
'user-agent' => 'WP Rocket/Preload',
],
],
];
if ( $is_mobile ) {
$requests[] = [
'url' => $url,
'headers' => [
'user-agent' => $this->get_mobile_user_agent_prefix(),
],
'is_mobile' => true,
];
}
/**
* Filters to modify requests done to preload an url.
*
* @param array $requests Requests that will be done.
*/
$requests = apply_filters( 'rocket_preload_before_preload_url', $requests );
if ( ! is_array( $requests ) ) {
return;
}
$requests = array_filter( $requests );
foreach ( $requests as $request ) {
if ( ! isset( $request['url'] ) || ! is_string( $request['url'] ) ) {
continue;
}
$headers = isset( $request['headers'] ) && is_array( $request['headers'] ) ? $request['headers'] : [];
$headers = array_merge(
$headers,
[
'blocking' => false,
'timeout' => 0.01,
/**
* Filter to activate the verification of SSl.
*
* @param string $activate is the verification activated.
*/
'sslverify' => apply_filters( 'https_local_ssl_verify', false ), // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
]
);
/**
* Filters the arguments for the preload request.
*
* @param array $headers Request arguments.
*/
$headers = apply_filters(
'rocket_preload_url_request_args',
$headers
);
if ( ! is_array( $headers ) ) {
return;
}
wp_safe_remote_get(
user_trailingslashit( $request['url'] ),
$headers
);
/**
* Filter the delay between each preload request.
*
* @param float $delay_between the defined delay.
* @returns float
*/
$delay_between = apply_filters( 'rocket_preload_delay_between_requests', 500000 );
usleep( $delay_between );
}
}
/**
* Get the prefix to prepend to the user agent used for preload to make a HTTP request detected as a mobile device.
*
* @return string
*/
protected function get_mobile_user_agent_prefix() {
$prefix = 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1';
/**
* Filter the prefix to prepend to the user agent used for preload to make a HTTP request detected as a mobile device.
*
* @param string $prefix The prefix.
*/
$new_prefix = apply_filters( 'rocket_mobile_preload_user_agent_prefix', $prefix );
if ( empty( $new_prefix ) || ! is_string( $new_prefix ) ) {
return $prefix;
}
return $new_prefix;
}
/**
* Process pending jobs inside CRON iteration.
*
* @return void
*/
public function process_pending_jobs() {
$count = apply_filters( 'rocket_preload_cache_pending_jobs_cron_rows_count', 45 );
$rows = $this->query->get_pending_jobs( $count );
foreach ( $rows as $index => $row ) {
if ( $this->is_excluded_by_filter( $row->url ) ) {
$this->query->delete_by_url( $row->url );
continue;
}
$this->query->make_status_inprogress( $row->id );
$this->queue->add_job_preload_job_preload_url_async( $row->url );
}
}
/**
* Check if the cache file for $item already exists.
*
* @param string $url The URL to preload.
* @param bool $is_mobile is mobile text.
*
* @return bool
*/
public function is_already_cached( string $url, bool $is_mobile = false ) {
static $https;
if ( ! isset( $https ) ) {
$https = is_ssl() && $this->options->get( 'cache_ssl' ) ? '-https' : '';
}
$url = get_rocket_parse_url( $url );
/** This filter is documented in inc/functions/htaccess.php */
if ( apply_filters( 'rocket_url_no_dots', false ) ) {
$url['host'] = str_replace( '.', '_', $url['host'] );
}
$url['path'] = trailingslashit( $url['path'] );
if ( '' !== $url['query'] ) {
$url['query'] = '#' . $url['query'] . '/';
}
$mobile = $is_mobile ? '-mobile' : '';
$file_cache_path = rocket_get_constant( 'WP_ROCKET_CACHE_PATH' ) . $url['host'] . strtolower( $url['path'] . $url['query'] ) . 'index' . $mobile . $https . '.html';
if ( ! $this->options->get( 'cache_webp', false ) ) {
return $this->filesystem->exists( $file_cache_path );
}
$webp_path = rocket_get_constant( 'WP_ROCKET_CACHE_PATH' ) . $url['host'] . strtolower( $url['path'] . $url['query'] ) . 'index' . $mobile . $https . '-webp.html';
$no_webp_path = rocket_get_constant( 'WP_ROCKET_CACHE_PATH' ) . $url['host'] . strtolower( $url['path'] . $url['query'] ) . '.no-webp';
return $this->filesystem->exists( $webp_path ) || ( $this->filesystem->exists( $no_webp_path ) && $this->filesystem->exists( $file_cache_path ) );
}
}