From 9feb8a6925c78b89ba8782961e5978df1e5e4ca6 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Sat, 4 May 2024 19:25:10 +0000 Subject: [PATCH] Bootstrap/Load: Add support for custom ports in multisite site addresses. This allows a Multisite network to use an address that includes a port name, such as `example.com:1234`, and adds support for this to the local development environment too. You can now run a Multisite installation on the local development environment, for example at `localhost:8889`. This also fixes some bugs with running a single site installation on a port, and updates the testing infrastructure so that the whole test suite runs both with and without a port number. Props djzone, scribu, nacin, ipstenu, F J Kaiser, jeremyfelt, johnjamesjacoby, spacedmonkey, PerS, Clorith, Blackbam, enrico.sorcinelli, Jules Colle, obliviousharmony, desrosj, johnbillion Fixes #21077, #52088 Built from https://develop.svn.wordpress.org/trunk@58097 git-svn-id: http://core.svn.wordpress.org/trunk@57562 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/includes/network.php | 22 ++-------------------- wp-admin/network/site-info.php | 14 +++++++++++--- wp-includes/embed.php | 3 ++- wp-includes/feed.php | 10 ++++++++-- wp-includes/media.php | 13 +++++++++++-- wp-includes/ms-site.php | 6 +----- wp-includes/version.php | 2 +- 7 files changed, 36 insertions(+), 34 deletions(-) diff --git a/wp-admin/includes/network.php b/wp-admin/includes/network.php index 67a9e0289e..9577172a80 100644 --- a/wp-admin/includes/network.php +++ b/wp-admin/includes/network.php @@ -148,26 +148,8 @@ function network_step1( $errors = false ) { die(); } - $hostname = get_clean_basedomain(); - $has_ports = strstr( $hostname, ':' ); - if ( ( false !== $has_ports && ! in_array( $has_ports, array( ':80', ':443' ), true ) ) ) { - wp_admin_notice( - '' . __( 'Error:' ) . ' ' . __( 'You cannot install a network of sites with your server address.' ), - array( - 'additional_classes' => array( 'error' ), - ) - ); - - echo '

' . sprintf( - /* translators: %s: Port number. */ - __( 'You cannot use port numbers such as %s.' ), - '' . $has_ports . '' - ) . '

'; - echo '' . __( 'Go to Dashboard' ) . ''; - echo ''; - require_once ABSPATH . 'wp-admin/admin-footer.php'; - die(); - } + // Strip standard port from hostname. + $hostname = preg_replace( '/(?::80|:443)$/', '', get_clean_basedomain() ); echo '
'; diff --git a/wp-admin/network/site-info.php b/wp-admin/network/site-info.php index defcc26e44..46f67cced5 100644 --- a/wp-admin/network/site-info.php +++ b/wp-admin/network/site-info.php @@ -66,8 +66,14 @@ if ( isset( $_REQUEST['action'] ) && 'update-site' === $_REQUEST['action'] ) { } $blog_data['scheme'] = $update_parsed_url['scheme']; + + // Make sure to not lose the port if it was provided. $blog_data['domain'] = $update_parsed_url['host']; - $blog_data['path'] = $update_parsed_url['path']; + if ( isset( $update_parsed_url['port'] ) ) { + $blog_data['domain'] .= ':' . $update_parsed_url['port']; + } + + $blog_data['path'] = $update_parsed_url['path']; } $existing_details = get_site( $id ); @@ -88,16 +94,18 @@ if ( isset( $_REQUEST['action'] ) && 'update-site' === $_REQUEST['action'] ) { $old_home_url = trailingslashit( esc_url( get_option( 'home' ) ) ); $old_home_parsed = parse_url( $old_home_url ); + $old_home_host = $old_home_parsed['host'] . ( isset( $old_home_parsed['port'] ) ? ':' . $old_home_parsed['port'] : '' ); - if ( $old_home_parsed['host'] === $existing_details->domain && $old_home_parsed['path'] === $existing_details->path ) { + if ( $old_home_host === $existing_details->domain && $old_home_parsed['path'] === $existing_details->path ) { $new_home_url = untrailingslashit( sanitize_url( $blog_data['scheme'] . '://' . $new_details->domain . $new_details->path ) ); update_option( 'home', $new_home_url ); } $old_site_url = trailingslashit( esc_url( get_option( 'siteurl' ) ) ); $old_site_parsed = parse_url( $old_site_url ); + $old_site_host = $old_site_parsed['host'] . ( isset( $old_site_parsed['port'] ) ? ':' . $old_site_parsed['port'] : '' ); - if ( $old_site_parsed['host'] === $existing_details->domain && $old_site_parsed['path'] === $existing_details->path ) { + if ( $old_site_host === $existing_details->domain && $old_site_parsed['path'] === $existing_details->path ) { $new_site_url = untrailingslashit( sanitize_url( $blog_data['scheme'] . '://' . $new_details->domain . $new_details->path ) ); update_option( 'siteurl', $new_site_url ); } diff --git a/wp-includes/embed.php b/wp-includes/embed.php index 6c767cfcab..915314a767 100644 --- a/wp-includes/embed.php +++ b/wp-includes/embed.php @@ -627,12 +627,13 @@ function get_oembed_response_data_for_url( $url, $args ) { wp_parse_url( $url ), array( 'host' => '', + 'port' => null, 'path' => '/', ) ); $qv = array( - 'domain' => $url_parts['host'], + 'domain' => $url_parts['host'] . ( $url_parts['port'] ? ':' . $url_parts['port'] : '' ), 'path' => '/', 'update_site_meta_cache' => false, ); diff --git a/wp-includes/feed.php b/wp-includes/feed.php index 4532697ea5..ec7c3ca9a9 100644 --- a/wp-includes/feed.php +++ b/wp-includes/feed.php @@ -660,8 +660,14 @@ function rss2_site_icon() { * @return string Correct link for the atom:self element. */ function get_self_link() { - $host = parse_url( home_url() ); - return set_url_scheme( 'http://' . $host['host'] . wp_unslash( $_SERVER['REQUEST_URI'] ) ); + $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'] ) ); } /** diff --git a/wp-includes/media.php b/wp-includes/media.php index b360c6dd34..76fb2b63c7 100644 --- a/wp-includes/media.php +++ b/wp-includes/media.php @@ -1363,8 +1363,17 @@ function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac * If currently on HTTPS, prefer HTTPS URLs when we know they're supported by the domain * (which is to say, when they share the domain name of the current request). */ - if ( is_ssl() && ! str_starts_with( $image_baseurl, 'https' ) && parse_url( $image_baseurl, PHP_URL_HOST ) === $_SERVER['HTTP_HOST'] ) { - $image_baseurl = set_url_scheme( $image_baseurl, 'https' ); + if ( is_ssl() && ! str_starts_with( $image_baseurl, 'https' ) ) { + // Since the `Host:` header might contain a port we should + // compare it against the image URL using the same port. + $parsed = parse_url( $image_baseurl ); + $domain = $parsed['host']; + if ( isset( $parsed['port'] ) ) { + $domain .= ':' . $parsed['port']; + } + if ( $_SERVER['HTTP_HOST'] === $domain ) { + $image_baseurl = set_url_scheme( $image_baseurl, 'https' ); + } } /* diff --git a/wp-includes/ms-site.php b/wp-includes/ms-site.php index 65e7d8d78d..6e19758790 100644 --- a/wp-includes/ms-site.php +++ b/wp-includes/ms-site.php @@ -524,11 +524,7 @@ function wp_prepare_site_data( $data, $defaults, $old_site = null ) { function wp_normalize_site_data( $data ) { // Sanitize domain if passed. if ( array_key_exists( 'domain', $data ) ) { - $data['domain'] = trim( $data['domain'] ); - $data['domain'] = preg_replace( '/\s+/', '', sanitize_user( $data['domain'], true ) ); - if ( is_subdomain_install() ) { - $data['domain'] = str_replace( '@', '', $data['domain'] ); - } + $data['domain'] = preg_replace( '/[^a-z0-9\-.:]+/i', '', $data['domain'] ); } // Sanitize path if passed. diff --git a/wp-includes/version.php b/wp-includes/version.php index d401253c50..491205e70c 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.6-alpha-58096'; +$wp_version = '6.6-alpha-58097'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.