Skip to content

Commit

Permalink
Connection: Add rate limiter to the package versions endpoint calls (…
Browse files Browse the repository at this point in the history
…#35379)

* Connection: Add rate limiter to the package versions endpoint calls.
---------

Co-authored-by: Foteini Giannaropoulou <giannaropoulou.foteini@gmail.com>

Committed via a GitHub action: https://github.com/Automattic/jetpack/actions/runs/7752618063
  • Loading branch information
fgiannar authored and matticbot committed Feb 2, 2024
1 parent 7d1b054 commit b6ce979
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 5 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

This is an alpha version! The changes listed here are not final.

### Added
- Add rate limiter to the package versions endpoint calls.

### Changed
- Adjust 'get_site_id()' method to return null if there's no blog ID.
- Updated package dependencies.
Expand Down
30 changes: 30 additions & 0 deletions src/class-package-version-tracker.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,26 @@ class Package_Version_Tracker {
*/
const CACHED_FAILED_REQUEST_EXPIRATION = 1 * HOUR_IN_SECONDS;

/**
* Transient key for rate limiting the package version requests;
*/
const RATE_LIMITER_KEY = 'jetpack_update_remote_package_last_query';

/**
* Only allow one versions check (and request) per minute.
*/
const RATE_LIMITER_TIMEOUT = MINUTE_IN_SECONDS;

/**
* Uses the jetpack_package_versions filter to obtain the package versions from packages that need
* version tracking. If the package versions have changed, updates the option and notifies WPCOM.
*/
public function maybe_update_package_versions() {
if ( $this->is_rate_limiting() ) {
// The version check is being rate limited.
return;
}

/**
* Obtains the package versions.
*
Expand Down Expand Up @@ -108,4 +123,19 @@ protected function update_package_versions_option( $package_versions ) {
set_transient( self::CACHED_FAILED_REQUEST_KEY, time(), self::CACHED_FAILED_REQUEST_EXPIRATION );
}
}

/**
* Check if version check is being rate limited, and update the rate limiting transient if needed.
*
* @return bool
*/
private function is_rate_limiting() {
if ( get_transient( static::RATE_LIMITER_KEY ) ) {
return true;
}

set_transient( static::RATE_LIMITER_KEY, time(), static::RATE_LIMITER_TIMEOUT );

return false;
}
}
35 changes: 30 additions & 5 deletions tests/php/test_package_version_tracker.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ public function tear_down() {
$this->http_request_attempted = false;
Constants::clear_constants();
WorDBless_Options::init()->clear_options();

delete_transient( Package_Version_Tracker::CACHED_FAILED_REQUEST_KEY );
delete_transient( Package_Version_Tracker::RATE_LIMITER_KEY );
}

/**
Expand Down Expand Up @@ -317,9 +320,34 @@ function () {
$failed_request_cached = get_transient( Package_Version_Tracker::CACHED_FAILED_REQUEST_KEY );

$this->assertNotFalse( $failed_request_cached );
}

// Clean-up.
delete_transient( Package_Version_Tracker::CACHED_FAILED_REQUEST_KEY );
/**
* Tests the maybe_update_package_versions method with rate limit applied.
*/
public function test_maybe_update_package_versions_with_rate_limit() {
\Jetpack_Options::update_option( 'blog_token', 'asdasd.123123' );
\Jetpack_Options::update_option( 'id', 1234 );

add_filter( 'pre_http_request', array( $this, 'intercept_http_request_success' ) );

update_option( Package_Version_Tracker::PACKAGE_VERSION_OPTION, self::PACKAGE_VERSIONS );
set_transient( Package_Version_Tracker::RATE_LIMITER_KEY, time() );

add_filter(
'jetpack_package_versions',
function () {
return self::CHANGED_VERSIONS;
}
);

( new Package_Version_Tracker() )->maybe_update_package_versions();

remove_filter( 'pre_http_request', array( $this, 'intercept_http_request_success' ) );

$this->assertFalse( $this->http_request_attempted );

$this->assertSame( self::PACKAGE_VERSIONS, get_option( Package_Version_Tracker::PACKAGE_VERSION_OPTION ) );
}

/**
Expand Down Expand Up @@ -349,9 +377,6 @@ function () {
$this->assertFalse( $this->http_request_attempted );

$this->assertSame( self::PACKAGE_VERSIONS, get_option( Package_Version_Tracker::PACKAGE_VERSION_OPTION ) );

// Clean-up.
delete_transient( Package_Version_Tracker::CACHED_FAILED_REQUEST_KEY );
}

/**
Expand Down

0 comments on commit b6ce979

Please sign in to comment.