Skip to content

Instantly share code, notes, and snippets.

@dd32
Last active June 8, 2021 04:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dd32/5ebefcd5754be48004b3290003b1c92c to your computer and use it in GitHub Desktop.
Save dd32/5ebefcd5754be48004b3290003b1c92c to your computer and use it in GitHub Desktop.
<?php
/**
* Plugin Name: Redirect WordPress.org downloads through a local caching proxy.
*/
/**
* PLEASE NOTE:
* - Please only cache downloads for a short period of time, ZIPs may change even though the URL doesn't.
* - This will cause download counts to not be counted on WordPress.org.
* - downloads.wordpress.org serves: Plugins, Themes, Translations, and Core Update packages, amongst other things.
*/
function redirect_downloads_to_local_cache( $result, $args, $url ) {
// If something has already filtered this request, respect it.
if ( $result ) {
return $result;
}
// Only cache certain hostnames, specifically the downloads hostnames.
// NOTE: downloads.wordpress.org is the normal hostname, downloads.w.org may be used occasionally though.
// Add any other restrictions as appropriate.
$hostname = parse_url( $url, PHP_URL_HOST );
if ( ! in_array( $hostname, [ 'downloads.wordpress.org', 'downloads.w.org' ] ) ) {
return $result;
}
// Request the file from the cache proxy instead:
$path = parse_url( $url, PHP_URL_PATH );
$cache_url = 'https://cache-downloads.example.com' . $path;
$cached = wp_remote_request( $cache_url, $args );
if ( 200 === wp_remote_retrieve_response_code( $cached ) ) {
// Only return the cached response if it's not an error.
// Note: This uses a 200 response code instead of WP_Error checks, this means 404's will not be cached, but also cache server failures will not cause issues.
return $cached;
}
// Return the original result in the event that the cache didn't, this will cause the original request to `https://downloads.wordpress.org/` to continue.
return $result;
}
add_filter( 'pre_http_request', 'redirect_downloads_to_local_cache', 10, 3 );
// Example:
var_dump( wp_remote_get( 'https://downloads.wordpress.org/plugin-checksums/hello-dolly/1.7.2.json' ) );
// The request will first hit https://cache-downloads.example.com/plugin-checksums/hello-dolly/1.7.2.json and get a NXDOMAIN
// The request will then continue on to the original URL.
// If cache-downloads.example.com returned a 200 response though, that'd have been used instead of falling back to downloads.wordpress.org
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment