Skip to content
This repository has been archived by the owner on Feb 23, 2019. It is now read-only.

Commit

Permalink
Expanded Regex Support & Improved Page Cache Cookies (#398)
Browse files Browse the repository at this point in the history
To provide better robustness I added full regex support for the following "Minify" fields:

* Never Minify the Following JS Files
* Never Minify the Following CSS Files
* Rejected User Agents

There have been several times in the past where having some regex support for the aforementioned fields would have resolved real-world user issues (e.g., dynamically generated js files with always changing names, which shouldn't be cached).

I also fixed an issue with Page Cache's "Reject Cookies" field.  It originally only accepted keys and so if someone gave a "key-value" pair (as is common for cookies) it would have failed despite the key existing.  It now allows the user to provide (optionally) a value, in the form: "name=value". Acceptable example entries could be: "mycookie=myvalue", "plugin"login=", "cookie"name".

A minor tweak was also made to "Util"Rule::array"trim()" because although the function was suppose to trim a given array it was not; it was simply checking to see if the entries weren't empty.  It now trims and removes empty entries, effectively becoming a true array trimmer.
  • Loading branch information
amiga-500 authored Feb 19, 2017
1 parent a0ab895 commit 143b723
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 64 deletions.
8 changes: 4 additions & 4 deletions BrowserCache_Environment.php
Original file line number Diff line number Diff line change
Expand Up @@ -527,18 +527,18 @@ private function _rules_cache_generate_apache_for_type( $config, $mime_types,
} else {
if ( $compatibility ) {
$rules .= " FileETag None\n";
$headers_rules .= " Header unset ETag\n";
$headers_rules .= " Header unset ETag\n";
}
}

if ( $unset_setcookie )
$headers_rules .= " Header unset Set-Cookie\n";
$headers_rules .= " Header unset Set-Cookie\n";

if ( !$set_last_modified )
$headers_rules .= " Header unset Last-Modified\n";
$headers_rules .= " Header unset Last-Modified\n";

if ( $w3tc )
$headers_rules .= " Header set X-Powered-By \"" .
$headers_rules .= " Header set X-Powered-By \"" .
Util_Environment::w3tc_header() . "\"\n";

if ( strlen( $headers_rules ) > 0 ) {
Expand Down
29 changes: 27 additions & 2 deletions Minify_Page.php
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,20 @@ function get_recommendations_js( $content ) {
$files = array_map( array( '\W3TC\Util_Environment', 'normalize_file_minify' ), $files );
$files = array_unique( $files );
$ignore_files = $this->_config->get_array( 'minify.reject.files.js' );
$files = array_diff( $files, $ignore_files );

$ignore_files = str_replace( "~", "\~", $ignore_files );
Util_Rule::array_trim( $ignore_files );

if ( !empty( $ignore_files ) ) {
$diff = array();
foreach( $files as $file ) {
if ( !@preg_match( '~' . implode( "|", $ignore_files ) . '~i', $file ) ) {
$diff[] = $file;
}
}
$files = $diff;
}

return $files;
}

Expand All @@ -654,7 +667,19 @@ function get_recommendations_css( $content ) {
$files = array_map( array( '\W3TC\Util_Environment', 'normalize_file_minify' ), $files );
$files = array_unique( $files );
$ignore_files = $this->_config->get_array( 'minify.reject.files.css' );
$files = array_diff( $files, $ignore_files );

$ignore_files = str_replace( "~", "\~", $ignore_files );
Util_Rule::array_trim( $ignore_files );

if ( !empty( $ignore_files ) ) {
$diff = array();
foreach( $files as $file ) {
if ( !@preg_match( '~' . implode( "|", $ignore_files ) . '~i', $file ) ) {
$diff[] = $file;
}
}
$files = $diff;
}

return $files;
}
Expand Down
34 changes: 20 additions & 14 deletions Minify_Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,6 @@ function ob_callback( $buffer ) {
$embed_pos = 0;
}

$ignore_css_files = array_map( array( '\W3TC\Util_Environment', 'normalize_file' ), $ignore_css_files );
$handled_styles = array();
$style_tags = Minify_Extract::extract_css( $buffer );
$previous_file_was_ignored = false;
Expand Down Expand Up @@ -228,7 +227,11 @@ function ob_callback( $buffer ) {

$handled_styles[] = $file;
$this->replaced_styles[] = $file;
if ( in_array( $file, $ignore_css_files ) ) {

$ignore_css_files = str_replace( "~", "\~", $ignore_css_files );
Util_Rule::array_trim( $ignore_css_files );

if ( !empty( $ignore_css_files ) && @preg_match( '~' . implode("|", $ignore_css_files ) . '~i', $file ) ) {
if ( $tag_pos > $embed_pos ) {
if ( $files_to_minify ) {
$data = array(
Expand Down Expand Up @@ -1040,17 +1043,18 @@ function can_minify2( $buffer ) {
* @return boolean
*/
function check_ua() {
$uas = array_merge( $this->_config->get_array( 'minify.reject.ua' ), array(
W3TC_POWERED_BY
) );
if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
$uas = array_merge( $this->_config->get_array( 'minify.reject.ua' ), array(
W3TC_POWERED_BY
) );

foreach ( $uas as $ua ) {
if ( !empty( $ua ) ) {
if ( isset( $_SERVER['HTTP_USER_AGENT'] ) && stristr( $_SERVER['HTTP_USER_AGENT'], $ua ) !== false ) {
return false;
}
}
}
$uas = str_replace( "~", "\~", $uas );
Util_Rule::array_trim( $uas );

if ( !empty( $uas ) && @preg_match( '~' . implode( "|", $uas ) . '~i', $_SERVER['HTTP_USER_AGENT'] ) ) {
return false;
}
}

return true;
}
Expand Down Expand Up @@ -1404,7 +1408,9 @@ function __construct( $config, $buffer, $minify_helpers ) {

// ignored files
$this->ignore_js_files = $this->config->get_array( 'minify.reject.files.js' );
$this->ignore_js_files = array_map( array( '\W3TC\Util_Environment', 'normalize_file' ), $this->ignore_js_files );

$this->ignore_js_files = str_replace( "~", "\~", $this->ignore_js_files );
Util_Rule::array_trim( $this->ignore_js_files );

// define embed type
$this->embed_type = array(
Expand Down Expand Up @@ -1522,7 +1528,7 @@ private function process_script_tag( $script_tag, $script_tag_number ) {

$step1_result = $this->minify_helpers->is_file_for_minification( $script_src, $file );
$step1 = !empty( $step1_result );
$step2 = !in_array( $file, $this->ignore_js_files );
$step2 = empty( $this->ignore_js_files ) || !@preg_match( '~' . implode( "|", $this->ignore_js_files ) . '~i', $file );

$do_tag_minification = $step1 && $step2;
$do_tag_minification = apply_filters( 'w3tc_minify_js_do_tag_minification',
Expand Down
39 changes: 22 additions & 17 deletions PgCache_ContentGrabber.php
Original file line number Diff line number Diff line change
Expand Up @@ -783,8 +783,9 @@ function _check_cache_exception() {
$accept_uri = $this->_config->get_array( 'pgcache.accept.files' );
$accept_uri = array_map( array( '\W3TC\Util_Environment', 'parse_path' ), $accept_uri );

foreach ( $accept_uri as &$val ) $val = trim( str_replace( "~", "\~", $val ) );
$accept_uri = array_filter( $accept_uri, function( $val ){ return $val != ""; } );
$accept_uri = str_replace( "~", "\~", $accept_uri );
Util_Rule::array_trim( $accept_uri );

if ( !empty( $accept_uri ) && @preg_match( '~' . implode( "|", $accept_uri ) . '~i', $this->_request_uri ) ) {
return true;
}
Expand Down Expand Up @@ -863,9 +864,9 @@ function _check_authors() {
*/
function _check_custom_fields() {
$reject_custom = $this->_config->get_array( 'pgcache.reject.custom' );
foreach ( $reject_custom as &$val ) {
$val = preg_quote( trim( $val ), '~' );
}
Util_Rule::array_trim( $reject_custom );
$reject_custom = array_map( array( '\W3TC\Util_Environment', 'preg_quote' ), $reject_custom );

$reject_custom = implode( "|",array_filter( $reject_custom ) );

Expand Down Expand Up @@ -948,17 +949,21 @@ function _check_cookies() {
}
}

foreach ( $this->_config->get_array( 'pgcache.reject.cookie' ) as $reject_cookie ) {
if ( !empty( $reject_cookie ) ) {
foreach ( array_keys( $_COOKIE ) as $cookie_name ) {
if ( strstr( $cookie_name, $reject_cookie ) !== false ) {
return false;
}
}
}
}
$reject_cookies = $this->_config->get_array( 'pgcache.reject.cookie' );
Util_Rule::array_trim( $reject_cookies );

return true;
$reject_cookies = str_replace( "+", " ", $reject_cookies );
$reject_cookies = array_map( array( '\W3TC\Util_Environment', 'preg_quote' ), $reject_cookies );

$reject_cookies = implode( '|', $reject_cookies );

foreach ( $_COOKIE as $key => $value ) {
if ( @preg_match( '~' . $reject_cookies . '~i', $key . "=$value" ) ) {
return false;
}
}

return true;
}

/**
Expand Down Expand Up @@ -1757,10 +1762,10 @@ private function _is_cacheable_content_type() {
*/
private function _check_query_string() {
$accept_qs = $this->_config->get_array( 'pgcache.accept.qs' );
$accept_qs = array_filter( $accept_qs, function( $val ) { return $val != ""; } );
Util_Rule::array_trim( $accept_qs );

foreach ( $accept_qs as &$val ) {
$val = preg_quote( trim( str_replace( "+", " ", $val ) ), "~" );
$val = Util_Environment::preg_quote( str_replace( "+", " ", $val ) );
$val .= ( strpos( $val, '=' ) === false ? '.*?' : '' );
}

Expand Down
37 changes: 21 additions & 16 deletions PgCache_Environment.php
Original file line number Diff line number Diff line change
Expand Up @@ -595,12 +595,12 @@ private function rules_core_generate_apache( $config ) {
/**
* Set accept query strings
*/
$w3tc_query_strings = array_filter( $config->get_array( 'pgcache.accept.qs' ), function( $val ) { return $val != ""; } );
$w3tc_query_strings = $config->get_array( 'pgcache.accept.qs' );
Util_Rule::array_trim( $w3tc_query_strings );

if ( !empty( $w3tc_query_strings ) ) {
foreach ( $w3tc_query_strings as &$val ) {
$val = trim( str_replace( " ", "\+", preg_quote( $val ) ) );
}
$w3tc_query_strings = str_replace( ' ', '+', $w3tc_query_strings );
$w3tc_query_strings = array_map( array( '\W3TC\Util_Environment', 'preg_quote' ), $w3tc_query_strings );

$rules .= " RewriteRule ^ - [E=W3TC_QUERY_STRING:%{QUERY_STRING}]\n";

Expand Down Expand Up @@ -735,8 +735,11 @@ private function rules_core_generate_apache( $config ) {
/**
* Check for rejected cookies
*/
$use_cache_rules .= " RewriteCond %{HTTP_COOKIE} !(" . implode( '|',
array_map( array( '\W3TC\Util_Environment', 'preg_quote' ), $reject_cookies ) ) . ") [NC]\n";
if ( !empty( $reject_cookies ) ) {
$reject_cookies = str_replace( ' ', '+', $reject_cookies );
$use_cache_rules .= " RewriteCond %{HTTP_COOKIE} !(" . implode( '|',
array_map( array( '\W3TC\Util_Environment', 'preg_quote' ), $reject_cookies ) ) . ") [NC]\n";
}

/**
* Check for rejected user agents
Expand Down Expand Up @@ -764,7 +767,7 @@ private function rules_core_generate_apache( $config ) {
$rules .= " RewriteRule .* \"" . $uri_prefix . $ext .
$env_W3TC_ENC . "\" [L]\n";

if ($config->get_boolean('pgcache.cache.apache_handle_xml')) {
if ($config->get_boolean( 'pgcache.cache.apache_handle_xml' ) ) {
$ext = '.xml';
$rules .= " RewriteCond \"" . $document_root . $uri_prefix . $ext .
$env_W3TC_ENC . "\"" . $switch . "\n";
Expand Down Expand Up @@ -852,12 +855,12 @@ private function rules_core_generate_nginx( $config ) {
/**
* Set accept query strings
*/
$w3tc_query_strings = array_filter( $config->get_array( 'pgcache.accept.qs' ), function( $val ) { return $val != ""; } );
$w3tc_query_strings = $config->get_array( 'pgcache.accept.qs' );
Util_Rule::array_trim( $w3tc_query_strings );

if ( !empty( $w3tc_query_strings ) ) {
foreach ( $w3tc_query_strings as &$val ) {
$val = trim( str_replace( " ", "\+", preg_quote( $val ) ) );
}
$w3tc_query_strings = str_replace( ' ', '+', $w3tc_query_strings );
$w3tc_query_strings = array_map( array( '\W3TC\Util_Environment', 'preg_quote' ), $w3tc_query_strings );

$rules .= "set \$w3tc_query_string \$query_string;\n";

Expand Down Expand Up @@ -947,11 +950,13 @@ private function rules_core_generate_nginx( $config ) {
/**
* Check for rejected cookies
*/
$rules .= "if (\$http_cookie ~* \"(" . implode( '|',
array_map( array( '\W3TC\Util_Environment', 'preg_quote' ), $reject_cookies ) ) . ")\") {\n";
$rules .= " set \$w3tc_rewrite 0;\n";
$rules .= "}\n";

if ( !empty( $reject_cookies ) ) {
$reject_cookies = str_replace( ' ', '+', $reject_cookies );
$rules .= "if (\$http_cookie ~* \"(" . implode( '|',
array_map( array( '\W3TC\Util_Environment', 'preg_quote' ), $reject_cookies ) ) . ")\") {\n";
$rules .= " set \$w3tc_rewrite 0;\n";
$rules .= "}\n";
}
/**
* Check for rejected user agents
*/
Expand Down
6 changes: 2 additions & 4 deletions Util_Rule.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ static public function is_permalink_rules() {
* Removes empty elements
*/
static public function array_trim( &$a ) {
for ( $n = count( $a ) - 1; $n >= 0; $n-- ) {
if ( empty( $a[$n] ) )
array_splice( $a, $n, 1 );
}
$a = array_map( 'trim', $a );
$a = array_filter( $a, function( $val ) { return $val != ""; } );
}

/**
Expand Down
8 changes: 4 additions & 4 deletions inc/options/minify.php
Original file line number Diff line number Diff line change
Expand Up @@ -486,23 +486,23 @@
<td>
<textarea id="minify_reject_uri" name="minify__reject__uri"
<?php Util_Ui::sealing_disabled( 'minify.' ) ?> cols="40" rows="5"><?php echo esc_textarea( implode( "\r\n", $this->_config->get_array( 'minify.reject.uri' ) ) ); ?></textarea><br />
<span class="description"><?php _e( 'Always ignore the specified pages / directories. Use relative paths. Omit: protocol, hostname, leading forward slash and query strings.', 'w3-total-cache' ); ?></span>
<span class="description"><?php _e( 'Always ignore the specified pages / directories. Use relative paths. Supports regular expressions. Omit: protocol, hostname, leading forward slash and query strings.', 'w3-total-cache' ); ?></span>
</td>
</tr>
<tr>
<th><label for="minify_reject_files_js"><?php Util_Ui::e_config_label( 'minify.reject.files.js' ) ?></label></th>
<td>
<textarea id="minify_reject_files_js" name="minify__reject__files__js"
<?php Util_Ui::sealing_disabled( 'minify.' ) ?> cols="40" rows="5"><?php echo esc_textarea( implode( "\r\n", $this->_config->get_array( 'minify.reject.files.js' ) ) ); ?></textarea><br />
<span class="description"><?php _e( 'Always ignore the specified <acronym title="JavaScript">JS</acronym> files. Use relative paths. Omit: protocol, hostname, leading forward slash and query strings.', 'w3-total-cache' ); ?></span>
<span class="description"><?php _e( 'Always ignore the specified <acronym title="JavaScript">JS</acronym> files. Use relative paths. Supports regular expressions. Omit: protocol, hostname, leading forward slash and query strings.', 'w3-total-cache' ); ?></span>
</td>
</tr>
<tr>
<th><label for="minify_reject_files_css"><?php Util_Ui::e_config_label( 'minify.reject.files.css' ) ?></label></th>
<td>
<textarea id="minify_reject_files_css" name="minify__reject__files__css"
<?php Util_Ui::sealing_disabled( 'minify.' ) ?> cols="40" rows="5"><?php echo esc_textarea( implode( "\r\n", $this->_config->get_array( 'minify.reject.files.css' ) ) ); ?></textarea><br />
<span class="description"><?php _e( 'Always ignore the specified <acronym title="Cascading Style Sheet">CSS</acronym> files. Use relative paths. Omit: protocol, hostname, leading forward slash and query strings.', 'w3-total-cache' ); ?></span>
<span class="description"><?php _e( 'Always ignore the specified <acronym title="Cascading Style Sheet">CSS</acronym> files. Use relative paths. Supports regular expressions. Omit: protocol, hostname, leading forward slash and query strings.', 'w3-total-cache' ); ?></span>
</td>
</tr>
<tr>
Expand All @@ -511,7 +511,7 @@
<textarea id="minify_reject_ua" name="minify__reject__ua"
<?php Util_Ui::sealing_disabled( 'minify.' ) ?>
cols="40" rows="5"><?php echo esc_textarea( implode( "\r\n", $this->_config->get_array( 'minify.reject.ua' ) ) ); ?></textarea><br />
<span class="description"><?php _e( 'Specify user agents that will never receive minified content.', 'w3-total-cache' ); ?></span>
<span class="description"><?php _e( 'Specify user agents that will never receive minified content. Supports regular expressions.', 'w3-total-cache' ); ?></span>
</td>
</tr>
<?php if ( $auto ): ?>
Expand Down
6 changes: 3 additions & 3 deletions inc/options/pgcache.php
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@
<textarea id="pgcache_reject_cookie" name="pgcache__reject__cookie"
<?php Util_Ui::sealing_disabled( 'pgcache.' ) ?>
cols="40" rows="5"><?php echo esc_textarea( implode( "\r\n", $this->_config->get_array( 'pgcache.reject.cookie' ) ) ); ?></textarea><br />
<span class="description"><?php _e( 'Never cache pages that use the specified cookies.', 'w3-total-cache' ); ?></span>
<span class="description"><?php _e( 'Never cache pages that use these specified cookie name-value pairs. The value part is not required. But if used, separate name-value pairs with an equals sign (i.e., name=value). Each pair should be on their own line.', 'w3-total-cache' ); ?></span>
</td>
</tr>
<tr>
Expand All @@ -366,7 +366,7 @@
<span class="description">
<?php
echo sprintf(
__( 'Always ignore the specified pages / directories. Supports regular expressions (See <a href="%s">FAQ</a>)', 'w3-total-cache' ), network_admin_url( 'admin.php?page=w3tc_faq#q82' )
__( 'Always ignore the specified pages / directories. Use relative paths. Supports regular expressions (See <a href="%s">FAQ</a>)', 'w3-total-cache' ), network_admin_url( 'admin.php?page=w3tc_faq#q82' )
); ?>
</span>
</td>
Expand Down Expand Up @@ -413,7 +413,7 @@
<textarea id="pgcache_accept_files" name="pgcache__accept__files"
<?php Util_Ui::sealing_disabled( 'pgcache.' ) ?>
cols="40" rows="5"><?php echo esc_textarea( implode( "\r\n", $this->_config->get_array( 'pgcache.accept.files' ) ) ); ?></textarea><br />
<span class="description"><?php echo sprintf( __( 'Cache the specified pages / directories even if listed in the "Never Cache" fields. Supports regular expression (See <a href="%s">FAQ</a>)', 'w3-total-cache' ), network_admin_url( 'admin.php?page=w3tc_faq#q82' ) ); ?></span>
<span class="description"><?php echo sprintf( __( 'Cache the specified pages / directories even if listed in the "Never Cache" fields. Use relative paths. Supports regular expression (See <a href="%s">FAQ</a>)', 'w3-total-cache' ), network_admin_url( 'admin.php?page=w3tc_faq#q82' ) ); ?></span>
</td>
</tr>
<?php if ( substr( $permalink_structure, -1 ) == '/' ): ?>
Expand Down
4 changes: 4 additions & 0 deletions pub/css/widget.css
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,7 @@
.maxcdn-netdna-widget-base.sign-up p span.desc {
color:#8F8F8F;
}

#purge_urls {
width: 100%;
}

0 comments on commit 143b723

Please sign in to comment.