Skip to content
Merged
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
4 changes: 4 additions & 0 deletions .github/changelog/fix-local-inbox-rest-url
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Activities between accounts on the same site are now delivered on sites installed in a subdirectory or using plain permalinks.
6 changes: 3 additions & 3 deletions includes/class-dispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,9 @@ private static function send_to_inboxes( $inboxes, $outbox_item_id ) {
* @return array|\WP_Error The result in the format of a remote post response, or WP_Error on failure.
*/
private static function send_to_local_inbox( $inbox_url, $json ) {
// Parse the inbox URL to extract the REST route.
$path = \wp_parse_url( $inbox_url, PHP_URL_PATH ) ?? '';
$rest_route = \preg_replace( '#^/' . \preg_quote( \rest_get_url_prefix(), '#' ) . '#', '', $path );
// Core resolves the route for subdirectory installs and every permalink setting.
$url_request = \WP_REST_Request::from_url( $inbox_url );
$rest_route = $url_request ? $url_request->get_route() : '';

/*
* The inbox URL comes from a remote actor document, and signature verification is deferred below,
Expand Down
29 changes: 26 additions & 3 deletions tests/phpunit/tests/includes/class-test-dispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -831,12 +831,20 @@ public function test_local_inboxes_skip_http() {
* The inbox URL comes from a remote actor document, and signature verification is deferred
* for local deliveries, so any other route on this site must not be dispatched.
*
* @dataProvider data_local_inbox_installs
* @covers ::send_to_inboxes
* @covers ::send_to_local_inbox
*
* @param string $structure The permalink structure.
* @param string $home_path The path WordPress is installed under.
*/
public function test_local_delivery_only_reaches_inbox_routes() {
// Local delivery reads the route from the URL path, which plain permalinks do not have.
$this->set_permalink_structure( '/%postname%/' );
public function test_local_delivery_only_reaches_inbox_routes( $structure, $home_path ) {
$this->set_permalink_structure( $structure );
// The test config sets WP_HOME, which core applies on `option_home`, so filter after it.
$home = static function ( $url ) use ( $home_path ) {
return $url . $home_path;
};
\add_filter( 'option_home', $home, 11 );

$post_id = self::factory()->post->create( array( 'post_author' => self::$user_id ) );
$outbox_item = $this->get_latest_outbox_item( \add_query_arg( 'p', $post_id, \home_url( '/' ) ) );
Expand Down Expand Up @@ -873,6 +881,7 @@ public function test_local_delivery_only_reaches_inbox_routes() {

\remove_filter( 'rest_pre_dispatch', $record );
\remove_action( 'activitypub_sent_to_inbox', $collect );
\remove_filter( 'option_home', $home, 11 );

$this->assertCount( 2, $dispatched, 'Only the two inboxes should be dispatched.' );

Expand All @@ -882,6 +891,20 @@ public function test_local_delivery_only_reaches_inbox_routes() {
}
}

/**
* Permalink settings and install paths that change the shape of a REST URL.
*
* @return array[] Permalink structure and install path.
*/
public function data_local_inbox_installs() {
return array(
'pretty permalinks' => array( '/%postname%/', '' ),
'plain permalinks' => array( '', '' ),
'index.php' => array( '/index.php/%postname%/', '' ),
'subdirectory' => array( '/%postname%/', '/blog' ),
);
}

/**
* Test that remote inboxes still use HTTP.
*
Expand Down
Loading