PluginProbe
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN / 1.0.7
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN v1.0.7
1.3.2 1.3.1 1.3.0 1.2.4 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.2.0 All 28 releases
xspeed / includes / class-gzip.php

class-gzip.php in xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN 1.0.7, at includes/class-gzip.php

140 lines 4.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * GZIP toggle.
4 *
5 * Apache + LiteSpeed: writes/removes a marker block in the site root
6 * .htaccess. Other servers (nginx, IIS): the toggle stores the user's
7 * preference but server config must be edited manually — the UI surfaces
8 * a copy-pasteable snippet via Gzip::manual_snippet().
9 *
10 * @package XSpeed
11 */
12
13 namespace XSpeed;
14
15 defined( 'ABSPATH' ) || exit;
16
17 class Gzip {
18
19 const MARKER = 'xSpeed GZIP';
20
21 public static function apply( $enabled ) {
22 if ( ! Server::supports_htaccess() ) {
23 return false;
24 }
25
26 $htaccess = ABSPATH . '.htaccess';
27 if ( ! file_exists( $htaccess ) ) {
28 return false;
29 }
30
31 if ( ! function_exists( 'insert_with_markers' ) ) {
32 require_once ABSPATH . 'wp-admin/includes/misc.php';
33 }
34
35 // Build the block from the GZIP base (only when GZIP is on) plus any
36 // rules add-ons append via the filter. An add-on (e.g. the Pro Brotli
37 // module) may want its own directives even when GZIP itself is off —
38 // so we run the filter regardless and write whatever it returns,
39 // emptying the marker block only when there is genuinely nothing.
40 $rules = self::apache_rules( (bool) $enabled );
41 return (bool) insert_with_markers( $htaccess, self::MARKER, $rules );
42 }
43
44 /**
45 * Compression rules written inside the marker block.
46 *
47 * @param bool $gzip_enabled Whether to include the GZIP (mod_deflate)
48 * base rules. Add-on filter contributions are
49 * applied either way, so Brotli (or another
50 * encoder) can be served even with GZIP off.
51 * @return string[]
52 */
53 public static function apache_rules( $gzip_enabled = true ) {
54 $rules = $gzip_enabled ? array(
55 '<IfModule mod_deflate.c>',
56 ' AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript',
57 ' AddOutputFilterByType DEFLATE application/javascript application/x-javascript application/json',
58 ' AddOutputFilterByType DEFLATE application/xml application/xhtml+xml application/rss+xml',
59 ' AddOutputFilterByType DEFLATE image/svg+xml font/ttf font/otf application/font-woff application/font-woff2',
60 '</IfModule>',
61 ) : array();
62
63 /**
64 * Filter the Apache compression rules written to .htaccess.
65 *
66 * The core engine emits GZIP (mod_deflate) when GZIP is enabled.
67 * Add-ons (xspeed-pro Brotli module) append their own
68 * <IfModule mod_brotli.c> block so Brotli is served where supported,
69 * GZIP otherwise. The base array is empty when GZIP is off, so an
70 * add-on can be the sole contributor. Listeners MUST return the full
71 * rules array (append, don't replace).
72 *
73 * @param string[] $rules Lines written inside the xSpeed GZIP marker block.
74 * @param bool $gzip_enabled Whether GZIP's own base rules are included.
75 */
76 return (array) apply_filters( 'xspeed_compression_apache_rules', $rules, $gzip_enabled );
77 }
78
79 /**
80 * nginx config snippet for users to paste into their server block.
81 */
82 public static function nginx_snippet() {
83 $snippet = implode(
84 "\n",
85 array(
86 'gzip on;',
87 'gzip_vary on;',
88 'gzip_min_length 1024;',
89 'gzip_proxied any;',
90 'gzip_comp_level 6;',
91 'gzip_types',
92 ' text/plain text/css text/xml text/javascript',
93 ' application/javascript application/json application/xml',
94 ' application/xml+rss application/xhtml+xml',
95 ' image/svg+xml font/ttf font/otf application/font-woff application/font-woff2;',
96 )
97 );
98
99 /**
100 * Filter the nginx compression snippet shown for manual config.
101 *
102 * Core emits the GZIP directives. Add-ons (xspeed-pro Brotli
103 * module) append an ngx_brotli block so users can paste Brotli +
104 * GZIP fallback in one go. Return the full snippet string.
105 *
106 * @param string $snippet The nginx directives block.
107 */
108 return (string) apply_filters( 'xspeed_compression_nginx_snippet', $snippet );
109 }
110
111 /**
112 * Returns true if the response we just received looks GZIP-encoded.
113 * Result is cached in a transient for 1 hour because the probe makes a
114 * full HTTP request to home_url() — too slow to run on every /status hit.
115 */
116 public static function probe_active() {
117 $cached = get_transient( 'xspeed_gzip_active' );
118 if ( false !== $cached ) {
119 return '1' === $cached;
120 }
121
122 $res = wp_remote_get(
123 home_url( '/' ),
124 array(
125 'headers' => array( 'Accept-Encoding' => 'gzip' ),
126 'timeout' => 3,
127 )
128 );
129
130 $active = false;
131 if ( ! is_wp_error( $res ) ) {
132 $enc = wp_remote_retrieve_header( $res, 'content-encoding' );
133 $active = is_string( $enc ) && false !== stripos( $enc, 'gzip' );
134 }
135
136 set_transient( 'xspeed_gzip_active', $active ? '1' : '0', HOUR_IN_SECONDS );
137 return $active;
138 }
139 }
140