Last active
March 12, 2017 04:08
-
-
Save simonw/15d4a17a65e4a9f8c44f9378688af4fb to your computer and use it in GitHub Desktop.
Fix for simple-proxy.php WordPress plugin to get it working with Varnish (addresses a gzip headers error)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Plugin Name: Simple Proxy | |
Description: A very simple proxy. Useful when you're moving from one server to another. | |
Author: Greg Priday | |
Author URI: http://siteorigin.com/ | |
Version: 1.0 | |
*/ | |
function simple_proxy_admin_menu(){ | |
add_submenu_page('options-general.php', __('Simple Proxy Settings', 'simple-proxy'), __('Simple Proxy', 'simple-proxy'), 'manage_options', 'so-simple-proxy', 'simple_proxy_admin_page'); | |
if(!empty($_POST['simple_proxy']) && !empty($_POST['_spnonce']) && wp_verify_nonce($_POST['_spnonce'], 'simple-proxy-save')) { | |
$settings = $_POST['simple_proxy']; | |
$settings['enabled'] = !empty($settings['enabled']); | |
$settings['url'] = rtrim($settings['url'], '/'); | |
update_option('simple_proxy_settings', $settings); | |
if( !empty( $_POST['simple_proxy_clear'] ) && WP_Filesystem() ) { | |
// Clear the proxy cache | |
global $wp_filesystem; | |
$cache_folder = $wp_filesystem->wp_content_dir().'proxy_cache/'; | |
$wp_filesystem->rmdir($cache_folder, true); | |
} | |
} | |
} | |
add_action('admin_menu', 'simple_proxy_admin_menu'); | |
function simple_proxy_admin_page(){ | |
$settings = get_option( 'simple_proxy_settings', array() ); | |
?> | |
<div class="wrap"> | |
<h2><?php _e('Simple Proxy Settings', 'simple-proxy') ?></h2> | |
<form action="<?php echo add_query_arg(false, false) ?>" method="post"> | |
<table class="form-table"> | |
<tbody> | |
<tr valign="top"> | |
<th scope="row"><?php _e('Proxy URL', 'simple-proxy') ?></th> | |
<td> | |
<input type="text" class="widefat" name="simple_proxy[url]" value="<?php echo (!empty($settings['url'])) ? esc_attr($settings['url']) : '' ?>" placeholder="http://"> | |
</td> | |
</tr> | |
<tr valign="top"> | |
<th scope="row"><?php _e('Proxy Enabled', 'simple-proxy') ?></th> | |
<td> | |
<label> | |
<input type="checkbox" name="simple_proxy[enabled]" <?php checked(!empty($settings['enabled'])) ?>> | |
<?php _e('enabled', 'simple-proxy') ?> | |
</label> | |
</td> | |
</tr> | |
<tr valign="top"> | |
<th scope="row"><?php _e('Clear Cache', 'simple-proxy') ?></th> | |
<td> | |
<label> | |
<input type="checkbox" name="simple_proxy_clear"> | |
<?php _e('check to clear the cache (once off)', 'simple-proxy') ?> | |
</label> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
<p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="<?php esc_attr_e('Save Changes', 'simple-proxy') ?>"></p> | |
<?php wp_nonce_field('simple-proxy-save', '_spnonce') ?> | |
</form> | |
</div> | |
<?php | |
} | |
function simple_proxy_init() { | |
// Don't process this if we're in the admin or login/register pages | |
if( is_admin() || in_array( $GLOBALS['pagenow'], array( 'wp-login.php', 'wp-register.php', 'wp-cron.php' ) ) ) return; | |
$settings = get_option( 'simple_proxy_settings', array() ); | |
if(empty($settings['enabled']) || empty($settings['url'])) return; | |
require_once(ABSPATH . 'wp-admin/includes/file.php'); | |
if(!WP_Filesystem()) return; | |
global $wp_filesystem; | |
$cache_folder = $wp_filesystem->wp_content_dir().'proxy_cache/'; | |
if(!$wp_filesystem->is_dir( $cache_folder )) { | |
$wp_filesystem->mkdir($cache_folder); | |
} | |
$url = esc_url( $settings['url'] ) . $_SERVER['REQUEST_URI']; | |
// Check if we have this in cache | |
$cache_file = $cache_folder.md5($url).'.dat'; | |
if( $wp_filesystem->is_file($cache_file) && ( time() - $wp_filesystem->mtime($cache_file) < 86400 ) ) { | |
$response = unserialize($wp_filesystem->get_contents($cache_file)); | |
} | |
else { | |
$response = wp_remote_get( | |
add_query_arg('no_cache', rand(0, 65536), $url), | |
array( | |
'timeout' => 120, | |
'decompress' => false, | |
) | |
); | |
if(!is_wp_error($response) && isset($response['response']['code']) && $response['response']['code'] == 200) { | |
$wp_filesystem->put_contents($cache_file, serialize($response)); | |
} | |
elseif($wp_filesystem->is_file($cache_file)) { | |
// The cache file still exists, use it so long | |
$response = unserialize($wp_filesystem->get_contents($cache_file)); | |
} | |
} | |
foreach($response['headers'] as $name => $value) { | |
if (strtolower($name) != 'content-encoding') { | |
header($name.': '.$value, true); | |
} | |
} | |
$body = str_replace($settings['url'], site_url(), $response['body']); | |
if(empty($body)) return; | |
echo $body; | |
exit(); | |
} | |
add_action('init', 'simple_proxy_init'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I was trying to use this plugin on a WordPress install hosted on DreamPress. DreamPress comes with a pre-configured Varnish, and I was getting 503 errors from Varnish when it attempted to delivered proxied pages.
I ran varnishlog from an SSH session and saw the following:
To fix this, I changed a couple of things. Firstly, I modified the call to the wp_remote_get() function to turn off gzip compression in that HTTP call, which should have prevented my proxied-to backend from serving gzipped content. Upon further inspection the backend still appeared to be returning a 'content-encoding: gzip' header for some reason even though the body wasn't gzipped, so I exclude that header from the headers that are copied across into the final response from the proxy plugin.
This seems to work now.