Skip to content

Commit

Permalink
Users: Always use HTTPS URLs for Gravatar links.
Browse files Browse the repository at this point in the history
Modifies gravatar image URLs to always use the HTTPS version from secure.gravatar.com. 

Gravatar now redirects HTTP image requests to their HTTPS equivalent, resulting in redirects for sites running over an HTTP connection (`is_ssl() === false`). Since the introduction of HTTP/2 the use of sub-domains for different hashes ([1-3].gravatar.com) now represents a performance hinderance rather than improvement.

The scheme passed to `get_avatar_data()` is now ignored for the generation of Gravatar URLs but the setting retained to avoid introducing bugs for sites using either local avatars or third party providers.

Props neoxx, SergeyBiryukov, sippis, peterwilsoncc, mukesh27, costdev, dd32.
Fixes #37454.



git-svn-id: https://develop.svn.wordpress.org/trunk@58822 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
peterwilsoncc committed Jul 29, 2024
1 parent a3173b6 commit c1ffe33
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 35 deletions.
21 changes: 12 additions & 9 deletions src/wp-includes/link-template.php
Original file line number Diff line number Diff line change
Expand Up @@ -4328,6 +4328,7 @@ function is_avatar_comment_type( $comment_type ) {
* Retrieves default data about the avatar.
*
* @since 4.2.0
* @since 6.7.0 Gravatar URLs always use HTTPS.
*
* @param mixed $id_or_email The avatar to retrieve. Accepts a user ID, Gravatar MD5 hash,
* user email, WP_User object, WP_Post object, or WP_Comment object.
Expand Down Expand Up @@ -4358,6 +4359,9 @@ function is_avatar_comment_type( $comment_type ) {
* - 'X' (even more mature than above)
* Default is the value of the 'avatar_rating' option.
* @type string $scheme URL scheme to use. See set_url_scheme() for accepted values.
* For Gravatars this setting is ignored and HTTPS is used to avoid
* unnecessary redirects. The setting is retained for systems using
* the {@see 'pre_get_avatar_data'} filter to customize avatars.
* Default null.
* @type array $processed_args When the function returns, the value will be the processed/sanitized $args
* plus a "found_avatar" guess. Pass as a reference. Default null.
Expand Down Expand Up @@ -4508,9 +4512,6 @@ function get_avatar_data( $id_or_email, $args = null ) {

if ( $email_hash ) {
$args['found_avatar'] = true;
$gravatar_server = hexdec( $email_hash[0] ) % 3;
} else {
$gravatar_server = rand( 0, 2 );
}

$url_args = array(
Expand All @@ -4520,15 +4521,17 @@ function get_avatar_data( $id_or_email, $args = null ) {
'r' => $args['rating'],
);

if ( is_ssl() ) {
$url = 'https://secure.gravatar.com/avatar/' . $email_hash;
} else {
$url = sprintf( 'http://%d.gravatar.com/avatar/%s', $gravatar_server, $email_hash );
}
/*
* Gravatars are always served over HTTPS.
*
* The Gravatar website redirects HTTP requests to HTTPS URLs so always
* use the HTTPS scheme to avoid unnecessary redirects.
*/
$url = 'https://secure.gravatar.com/avatar/' . $email_hash;

$url = add_query_arg(
rawurlencode_deep( array_filter( $url_args ) ),
set_url_scheme( $url, $args['scheme'] )
$url
);

/**
Expand Down
20 changes: 15 additions & 5 deletions tests/phpunit/tests/avatar.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Tests_Avatar extends WP_UnitTestCase {
*/
public function test_get_avatar_url_gravatar_url() {
$url = get_avatar_url( 1 );
$this->assertSame( preg_match( '|^http?://[0-9]+.gravatar.com/avatar/[0-9a-f]{32}\?|', $url ), 1 );
$this->assertSame( preg_match( '|^https?://secure.gravatar.com/avatar/[0-9a-f]{32}\?|', $url ), 1 );
}

/**
Expand Down Expand Up @@ -56,19 +56,29 @@ public function test_get_avatar_url_rating() {
}

/**
* Ensures the get_avatar_url always returns an HTTPS scheme for gravatars.
*
* @ticket 21195
* @ticket 37454
*
* @covers ::get_avatar_url
*/
public function test_get_avatar_url_scheme() {
$url = get_avatar_url( 1 );
$this->assertSame( preg_match( '|^http://|', $url ), 1 );
$this->assertSame( preg_match( '|^https://|', $url ), 1, 'Avatars should default to the HTTPS scheme' );

$args = array( 'scheme' => 'https' );
$url = get_avatar_url( 1, $args );
$this->assertSame( preg_match( '|^https://|', $url ), 1 );
$this->assertSame( preg_match( '|^https://|', $url ), 1, 'Requesting the HTTPS scheme should be respected' );

$args = array( 'scheme' => 'http' );
$url = get_avatar_url( 1, $args );
$this->assertSame( preg_match( '|^https://|', $url ), 1, 'Requesting the HTTP scheme should return an HTTPS URL to avoid redirects' );

$args = array( 'scheme' => 'lolcat' );
$url = get_avatar_url( 1, $args );
$this->assertSame( preg_match( '|^lolcat://|', $url ), 0 );
$this->assertSame( preg_match( '|^lolcat://|', $url ), 0, 'Unrecognized schemes should be ignored' );
$this->assertSame( preg_match( '|^https://|', $url ), 1, 'Unrecognized schemes should return an HTTPS URL' );
}

/**
Expand Down Expand Up @@ -257,7 +267,7 @@ public function test_get_avatar_data_should_return_gravatar_url_when_input_avata
$actual_data = get_avatar_data( $comment );

$this->assertTrue( is_avatar_comment_type( $comment_type ) );
$this->assertMatchesRegularExpression( '|^http?://[0-9]+.gravatar.com/avatar/[0-9a-f]{32}\?|', $actual_data['url'] );
$this->assertMatchesRegularExpression( '|^https?://secure.gravatar.com/avatar/[0-9a-f]{32}\?|', $actual_data['url'] );
}

/**
Expand Down
6 changes: 3 additions & 3 deletions tests/phpunit/tests/rest-api/rest-schema-setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -729,9 +729,9 @@ public function test_build_wp_api_client_fixtures() {
'TagModel.meta.test_multi' => array(),
'TagModel.meta.test_tag_meta' => '',
'UsersCollection.0.link' => 'http://example.org/?author=1',
'UsersCollection.0.avatar_urls.24' => 'http://0.gravatar.com/avatar/96614ec98aa0c0d2ee75796dced6df54?s=24&d=mm&r=g',
'UsersCollection.0.avatar_urls.48' => 'http://0.gravatar.com/avatar/96614ec98aa0c0d2ee75796dced6df54?s=48&d=mm&r=g',
'UsersCollection.0.avatar_urls.96' => 'http://0.gravatar.com/avatar/96614ec98aa0c0d2ee75796dced6df54?s=96&d=mm&r=g',
'UsersCollection.0.avatar_urls.24' => 'https://secure.gravatar.com/avatar/96614ec98aa0c0d2ee75796dced6df54?s=24&d=mm&r=g',
'UsersCollection.0.avatar_urls.48' => 'https://secure.gravatar.com/avatar/96614ec98aa0c0d2ee75796dced6df54?s=48&d=mm&r=g',
'UsersCollection.0.avatar_urls.96' => 'https://secure.gravatar.com/avatar/96614ec98aa0c0d2ee75796dced6df54?s=96&d=mm&r=g',
'UsersCollection.0._links.self.0.href' => 'http://example.org/index.php?rest_route=/wp/v2/users/1',
'UsersCollection.0._links.collection.0.href' => 'http://example.org/index.php?rest_route=/wp/v2/users',
'UsersCollection.1.id' => 2,
Expand Down
36 changes: 18 additions & 18 deletions tests/qunit/fixtures/wp-api-generated.js
Original file line number Diff line number Diff line change
Expand Up @@ -13748,9 +13748,9 @@ mockedApiResponse.UsersCollection = [
"link": "http://example.org/?author=1",
"slug": "admin",
"avatar_urls": {
"24": "http://0.gravatar.com/avatar/96614ec98aa0c0d2ee75796dced6df54?s=24&d=mm&r=g",
"48": "http://0.gravatar.com/avatar/96614ec98aa0c0d2ee75796dced6df54?s=48&d=mm&r=g",
"96": "http://0.gravatar.com/avatar/96614ec98aa0c0d2ee75796dced6df54?s=96&d=mm&r=g"
"24": "https://secure.gravatar.com/avatar/96614ec98aa0c0d2ee75796dced6df54?s=24&d=mm&r=g",
"48": "https://secure.gravatar.com/avatar/96614ec98aa0c0d2ee75796dced6df54?s=48&d=mm&r=g",
"96": "https://secure.gravatar.com/avatar/96614ec98aa0c0d2ee75796dced6df54?s=96&d=mm&r=g"
},
"meta": {
"meta_key": "meta_value"
Expand All @@ -13776,9 +13776,9 @@ mockedApiResponse.UsersCollection = [
"link": "http://example.org/?author=2",
"slug": "restapiclientfixtureuser",
"avatar_urls": {
"24": "http://2.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=24&d=mm&r=g",
"48": "http://2.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=48&d=mm&r=g",
"96": "http://2.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=96&d=mm&r=g"
"24": "https://secure.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=24&d=mm&r=g",
"48": "https://secure.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=48&d=mm&r=g",
"96": "https://secure.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=96&d=mm&r=g"
},
"meta": {
"meta_key": ""
Expand Down Expand Up @@ -13806,9 +13806,9 @@ mockedApiResponse.UserModel = {
"link": "http://example.org/?author=2",
"slug": "restapiclientfixtureuser",
"avatar_urls": {
"24": "http://2.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=24&d=mm&r=g",
"48": "http://2.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=48&d=mm&r=g",
"96": "http://2.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=96&d=mm&r=g"
"24": "https://secure.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=24&d=mm&r=g",
"48": "https://secure.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=48&d=mm&r=g",
"96": "https://secure.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=96&d=mm&r=g"
},
"meta": {
"meta_key": ""
Expand All @@ -13823,9 +13823,9 @@ mockedApiResponse.me = {
"link": "http://example.org/?author=2",
"slug": "restapiclientfixtureuser",
"avatar_urls": {
"24": "http://2.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=24&d=mm&r=g",
"48": "http://2.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=48&d=mm&r=g",
"96": "http://2.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=96&d=mm&r=g"
"24": "https://secure.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=24&d=mm&r=g",
"48": "https://secure.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=48&d=mm&r=g",
"96": "https://secure.gravatar.com/avatar/57cbd982c963c7eb2294e2eee1b4448e?s=96&d=mm&r=g"
},
"meta": {
"meta_key": ""
Expand All @@ -13849,9 +13849,9 @@ mockedApiResponse.CommentsCollection = [
"status": "approved",
"type": "comment",
"author_avatar_urls": {
"24": "http://2.gravatar.com/avatar/bd7c2b505bcf39cc71cfee564c614956?s=24&d=mm&r=g",
"48": "http://2.gravatar.com/avatar/bd7c2b505bcf39cc71cfee564c614956?s=48&d=mm&r=g",
"96": "http://2.gravatar.com/avatar/bd7c2b505bcf39cc71cfee564c614956?s=96&d=mm&r=g"
"24": "https://secure.gravatar.com/avatar/bd7c2b505bcf39cc71cfee564c614956?s=24&d=mm&r=g",
"48": "https://secure.gravatar.com/avatar/bd7c2b505bcf39cc71cfee564c614956?s=48&d=mm&r=g",
"96": "https://secure.gravatar.com/avatar/bd7c2b505bcf39cc71cfee564c614956?s=96&d=mm&r=g"
},
"meta": {
"meta_key": "meta_value"
Expand Down Expand Up @@ -13894,9 +13894,9 @@ mockedApiResponse.CommentModel = {
"status": "approved",
"type": "comment",
"author_avatar_urls": {
"24": "http://2.gravatar.com/avatar/bd7c2b505bcf39cc71cfee564c614956?s=24&d=mm&r=g",
"48": "http://2.gravatar.com/avatar/bd7c2b505bcf39cc71cfee564c614956?s=48&d=mm&r=g",
"96": "http://2.gravatar.com/avatar/bd7c2b505bcf39cc71cfee564c614956?s=96&d=mm&r=g"
"24": "https://secure.gravatar.com/avatar/bd7c2b505bcf39cc71cfee564c614956?s=24&d=mm&r=g",
"48": "https://secure.gravatar.com/avatar/bd7c2b505bcf39cc71cfee564c614956?s=48&d=mm&r=g",
"96": "https://secure.gravatar.com/avatar/bd7c2b505bcf39cc71cfee564c614956?s=96&d=mm&r=g"
},
"meta": {
"meta_key": "meta_value"
Expand Down

0 comments on commit c1ffe33

Please sign in to comment.