Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ wp-tests-config.php

# Files for local environment config
/docker-compose.override.yml
/tools/local-env/default.local.template
/tools/local-env/php-config.local.ini

# Visual regression test diffs
tests/visual-regression/specs/__snapshots__
4 changes: 2 additions & 2 deletions src/wp-admin/includes/class-wp-list-table.php
Original file line number Diff line number Diff line change
Expand Up @@ -1045,7 +1045,7 @@ protected function pagination( $which ) {
$current = $this->get_pagenum();
$removable_query_args = wp_removable_query_args();

$current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
$current_url = wp_get_current_request_url();

$current_url = remove_query_arg( $removable_query_args, $current_url );

Expand Down Expand Up @@ -1399,7 +1399,7 @@ public function get_column_count() {
public function print_column_headers( $with_id = true ) {
list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();

$current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
$current_url = wp_get_current_request_url();
$current_url = remove_query_arg( 'paged', $current_url );

// When users click on a column header to sort by other columns.
Expand Down
2 changes: 1 addition & 1 deletion src/wp-admin/includes/misc.php
Original file line number Diff line number Diff line change
Expand Up @@ -1391,7 +1391,7 @@ function wp_admin_canonical_url() {
}

// Ensure we're using an absolute URL.
$current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
$current_url = wp_get_current_request_url();
$filtered_url = remove_query_arg( $removable_query_args, $current_url );

/**
Expand Down
2 changes: 1 addition & 1 deletion src/wp-includes/admin-bar.php
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ function wp_admin_bar_customize_menu( $wp_admin_bar ) {
return;
}

$current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$current_url = wp_get_current_request_url();
if ( is_customize_preview() && $wp_customize->changeset_uuid() ) {
$current_url = remove_query_arg( 'customize_changeset_uuid', $current_url );
}
Expand Down
8 changes: 2 additions & 6 deletions src/wp-includes/blocks/loginout.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,8 @@
*/
function render_block_core_loginout( $attributes ) {

/*
* Build the redirect URL. This current url fetching logic matches with the core.
*
* @see https://github.com/WordPress/wordpress-develop/blob/6bf62e58d21739938f3bb3f9e16ba702baf9c2cc/src/wp-includes/general-template.php#L528.
*/
$current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
// Build the redirect URL.
$current_url = wp_get_current_request_url();

$user_logged_in = is_user_logged_in();

Expand Down
6 changes: 2 additions & 4 deletions src/wp-includes/canonical.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,9 @@ function redirect_canonical( $requested_url = null, $do_redirect = true ) {
return;
}

if ( ! $requested_url && isset( $_SERVER['HTTP_HOST'] ) ) {
if ( ! $requested_url && isset( $_SERVER['REQUEST_URI'] ) ) {
// Build the URL in the address bar.
$requested_url = is_ssl() ? 'https://' : 'http://';
$requested_url .= $_SERVER['HTTP_HOST'];
$requested_url .= $_SERVER['REQUEST_URI'];
$requested_url = wp_get_current_request_url();
}

$original = parse_url( $requested_url );
Expand Down
4 changes: 1 addition & 3 deletions src/wp-includes/class-wp-recovery-mode.php
Original file line number Diff line number Diff line change
Expand Up @@ -462,9 +462,7 @@ protected function redirect_protected() {
require_once ABSPATH . WPINC . '/pluggable.php';
}

$scheme = is_ssl() ? 'https://' : 'http://';

$url = "{$scheme}{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
$url = wp_get_current_request_url();
wp_safe_redirect( $url );
exit;
}
Expand Down
9 changes: 1 addition & 8 deletions src/wp-includes/feed.php
Original file line number Diff line number Diff line change
Expand Up @@ -668,14 +668,7 @@ function rss2_site_icon() {
* @return string Correct link for the atom:self element.
*/
function get_self_link() {
$parsed = parse_url( home_url() );

$domain = $parsed['host'];
if ( isset( $parsed['port'] ) ) {
$domain .= ':' . $parsed['port'];
}

return set_url_scheme( 'http://' . $domain . wp_unslash( $_SERVER['REQUEST_URI'] ) );
return wp_get_current_request_url();
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/wp-includes/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -1923,7 +1923,7 @@ function wp_nonce_field( $action = -1, $name = '_wpnonce', $referer = true, $dis
* @return string Referer field HTML markup.
*/
function wp_referer_field( $display = true ) {
$request_url = remove_query_arg( '_wp_http_referer' );
$request_url = remove_query_arg( '_wp_http_referer', wp_get_current_request_url() );
$referer_field = '<input type="hidden" name="_wp_http_referer" value="' . esc_url( $request_url ) . '" />';

if ( $display ) {
Expand Down Expand Up @@ -7464,7 +7464,7 @@ function wp_auth_check_load() {
*/
function wp_auth_check_html() {
$login_url = wp_login_url();
$current_domain = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'];
$current_domain = network_home_url();
$same_domain = str_starts_with( $login_url, $current_domain );

/**
Expand Down
2 changes: 1 addition & 1 deletion src/wp-includes/general-template.php
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ function wp_login_form( $args = array() ) {
$defaults = array(
'echo' => true,
// Default 'redirect' value takes the user back to the request URI.
'redirect' => ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'],
'redirect' => wp_get_current_request_url(),
'form_id' => 'loginform',
'label_username' => __( 'Username or Email Address' ),
'label_password' => __( 'Password' ),
Expand Down
50 changes: 50 additions & 0 deletions src/wp-includes/link-template.php
Original file line number Diff line number Diff line change
Expand Up @@ -3817,6 +3817,56 @@ function network_home_url( $path = '', $scheme = null ) {
return apply_filters( 'network_home_url', $url, $path, $orig_scheme );
}

/**
* Builds a full URL for the current request using the site's configured host.
*
* Replaces raw `$_SERVER['HTTP_HOST']` with the host from `home_url()`, which
* respects the DB-configured site address. This is important behind reverse
* proxies or load balancers where `HTTP_HOST` may not match the public host.
*
* If the request URI already contains the home path (standard setup), only the
* scheme and host are swapped. If the home path is missing from the request URI
* (e.g. a reverse proxy stripped a path prefix), the home path is prepended
* automatically.
*
* @since 6.9.0
*
* @see https://core.trac.wordpress.org/ticket/53998
*
* @param string|null $request_uri Optional. The request URI to use. Defaults to
* `$_SERVER['REQUEST_URI']`.
* @return string Full URL of the current request.
*/
function wp_get_current_request_url( $request_uri = null ) {
if ( null === $request_uri ) {
$request_uri = $_SERVER['REQUEST_URI'];
}

$home = home_url( '/' );
$home_path = wp_parse_url( $home, PHP_URL_PATH );

if ( ! $home_path ) {
$home_path = '/';
}

if ( str_starts_with( $request_uri, $home_path ) ) {
// Standard case: REQUEST_URI already includes the home path.
// Just replace scheme + host, keep the request URI as-is.
$parsed = wp_parse_url( $home );
$host = isset( $parsed['host'] ) ? $parsed['host'] : $_SERVER['HTTP_HOST'];
if ( isset( $parsed['port'] ) ) {
$host .= ':' . $parsed['port'];
}
$url = set_url_scheme( 'http://' . $host . $request_uri );
} else {
// Reverse-proxy case: REQUEST_URI is missing the home path prefix.
// Let home_url() prepend it.
$url = home_url( $request_uri );
}

return $url;
}

/**
* Retrieves the URL to the admin area for the network.
*
Expand Down
4 changes: 2 additions & 2 deletions src/wp-includes/nav-menu-template.php
Original file line number Diff line number Diff line change
Expand Up @@ -474,15 +474,15 @@ function _wp_menu_item_classes_by_context( &$menu_items ) {
$active_parent_item_ids[] = (int) $menu_item->menu_item_parent;

// If the menu item corresponds to the currently requested URL.
} elseif ( 'custom' === $menu_item->object && isset( $_SERVER['HTTP_HOST'] ) ) {
} elseif ( 'custom' === $menu_item->object && isset( $_SERVER['REQUEST_URI'] ) ) {
$_root_relative_current = untrailingslashit( $_SERVER['REQUEST_URI'] );

// If it's the customize page then it will strip the query var off the URL before entering the comparison block.
if ( is_customize_preview() ) {
$_root_relative_current = strtok( untrailingslashit( $_SERVER['REQUEST_URI'] ), '?' );
}

$current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_root_relative_current );
$current_url = wp_get_current_request_url( $_root_relative_current );
$raw_item_url = strpos( $menu_item->url, '#' ) ? substr( $menu_item->url, 0, strpos( $menu_item->url, '#' ) ) : $menu_item->url;
$item_url = set_url_scheme( untrailingslashit( $raw_item_url ) );
$_indexless_current = untrailingslashit( preg_replace( '/' . preg_quote( $wp_rewrite->index, '/' ) . '$/', '', $current_url ) );
Expand Down
23 changes: 6 additions & 17 deletions src/wp-includes/pluggable.php
Original file line number Diff line number Diff line change
Expand Up @@ -1287,13 +1287,8 @@ function auth_redirect() {

// If https is required and request is http, redirect.
if ( $secure && ! is_ssl() && str_contains( $_SERVER['REQUEST_URI'], 'wp-admin' ) ) {
if ( str_starts_with( $_SERVER['REQUEST_URI'], 'http' ) ) {
wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) );
exit;
} else {
wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
exit;
}
wp_safe_redirect( set_url_scheme( wp_get_current_request_url(), 'https' ) );
exit;
}

/**
Expand All @@ -1318,30 +1313,24 @@ function auth_redirect() {

// If the user wants ssl but the session is not ssl, redirect.
if ( ! $secure && get_user_option( 'use_ssl', $user_id ) && str_contains( $_SERVER['REQUEST_URI'], 'wp-admin' ) ) {
if ( str_starts_with( $_SERVER['REQUEST_URI'], 'http' ) ) {
wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) );
exit;
} else {
wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
exit;
}
wp_safe_redirect( set_url_scheme( wp_get_current_request_url(), 'https' ) );
exit;
}

return; // The cookie is good, so we're done.
}

// The cookie is no good, so force login.
nocache_headers();

if ( str_contains( $_SERVER['REQUEST_URI'], '/options.php' ) && wp_get_referer() ) {
$redirect = wp_get_referer();
} else {
$redirect = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
$redirect = wp_get_current_request_url();
}

$login_url = wp_login_url( $redirect, true );

wp_redirect( $login_url );
wp_safe_redirect( $login_url );
exit;
}
endif;
Expand Down
9 changes: 2 additions & 7 deletions src/wp-login.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@

// Redirect to HTTPS login if forced to use SSL.
if ( force_ssl_admin() && ! is_ssl() ) {
if ( str_starts_with( $_SERVER['REQUEST_URI'], 'http' ) ) {
wp_safe_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) );
exit;
} else {
wp_safe_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
exit;
}
wp_safe_redirect( set_url_scheme( wp_get_current_request_url(), 'https' ) );
exit;
}

/**
Expand Down
127 changes: 127 additions & 0 deletions tests/phpunit/tests/feed/getSelfLink.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?php

/**
* Tests for the get_self_link() function.
*
* @group feed
*
* @covers ::get_self_link
*/
class Tests_Feed_GetSelfLink extends WP_UnitTestCase {

/**
* The original value of `$_SERVER['REQUEST_URI']`.
*
* @var string
*/
private $original_request_uri;

public function set_up() {
parent::set_up();

$this->original_request_uri = $_SERVER['REQUEST_URI'];
}

public function tear_down() {
$_SERVER['REQUEST_URI'] = $this->original_request_uri;
unset( $_SERVER['HTTPS'] );

parent::tear_down();
}

/**
* Tests that get_self_link() returns a full URL using the home host.
*
* @ticket 53998
*/
public function test_returns_full_url() {
$_SERVER['REQUEST_URI'] = '/feed/';

$url = get_self_link();

$this->assertStringStartsWith( 'http', $url );
$this->assertStringContainsString( '/feed/', $url );
}

/**
* Tests that get_self_link() uses the host from home_url().
*
* @ticket 53998
*/
public function test_host_from_home_url() {
$original_home = get_option( 'home' );
update_option( 'home', 'http://feeds.example.com' );

$_SERVER['REQUEST_URI'] = '/feed/';

$url = get_self_link();

update_option( 'home', $original_home );

$this->assertStringContainsString( 'feeds.example.com', $url );
}

/**
* Tests that get_self_link() reflects the current request scheme.
*
* @ticket 53998
*/
public function test_scheme_follows_is_ssl() {
$_SERVER['REQUEST_URI'] = '/feed/';
$_SERVER['HTTPS'] = 'on';

$url = get_self_link();

$this->assertStringStartsWith( 'https://', $url );
}

/**
* Tests that get_self_link() preserves query strings.
*
* @ticket 53998
*/
public function test_preserves_query_string() {
$_SERVER['REQUEST_URI'] = '/feed/?cat=1&paged=2';

$url = get_self_link();

$this->assertStringContainsString( 'cat=1', $url );
$this->assertStringContainsString( 'paged=2', $url );
}

/**
* Tests that get_self_link() includes the subdirectory prefix.
*
* @ticket 53998
*/
public function test_includes_subdirectory_prefix() {
$original_home = get_option( 'home' );
update_option( 'home', 'http://' . WP_TESTS_DOMAIN . '/blog' );

$_SERVER['REQUEST_URI'] = '/blog/feed/';

$url = get_self_link();

update_option( 'home', $original_home );

$this->assertSame( 'http://' . WP_TESTS_DOMAIN . '/blog/feed/', $url );
}

/**
* Tests the reverse-proxy case where the path prefix is stripped.
*
* @ticket 53998
*/
public function test_reverse_proxy_prepends_home_path() {
$original_home = get_option( 'home' );
update_option( 'home', 'http://' . WP_TESTS_DOMAIN . '/subsite' );

$_SERVER['REQUEST_URI'] = '/feed/';

$url = get_self_link();

update_option( 'home', $original_home );

$this->assertSame( 'http://' . WP_TESTS_DOMAIN . '/subsite/feed/', $url );
}
}
Loading
Loading