WordPress.org

Make WordPress Core

Opened 10 months ago

Closed 8 months ago

Last modified 8 months ago

#39432 closed defect (bug) (fixed)

index.php/wp-json/ does not work

Reported by: ccprog Owned by: rmccue
Milestone: 4.7.3 Priority: normal
Severity: normal Version: 4.7
Component: REST API Keywords: has-patch fixed-major
Focuses: Cc:

Description

While you need mod_rewrite for discovery via http://example.com/wp-json/ to work, I run into problems without it. The Link resonse header then says

<http://example.com/index.php/wp-json/>; rel="https://api.w.org/"

but calling this results in

{"code":"rest_no_route","message":"No route was found matching the URL and request method","data":{"status":404}}

The same error is returned on my public site https://browser-unplugged.net/index.php/wp-json/ where rewrite is working. The response is obviously given by the REST API. The REST API plugin was never installed, and I did flush the rewrite rules as proposed in 39424

For sites like developer.wordpress.org or demo.wp-api.org, the address works.

http://example.com/index.php/index.php/?rest_route=/, http://example.com/index.php/wp-json/wp/v2/ and all endpoints work as expected.

Attachments (1)

39432.diff (995 bytes) - added by rmccue 9 months ago.
Correctly determine rest_route on the index

Download all attachments as: .zip

Change History (14)

#1 @ccprog
10 months ago

The error can be traced to WP_Rest_Server::serve_request:

if ( empty( $path ) ) {
        if ( isset( $_SERVER['PATH_INFO'] ) ) {
                $path = $_SERVER['PATH_INFO'];
        } else {
                $path = '/';
        }
}

$_SERVER['PATH_INFO'] contains /wp-json/ on my setup.

While this is plausible if mod_rewrite is not active, the success on developer.wordpress.org raises the question if a webserver rewrite may or may not change the content of PATH_INFO?

#2 @rachelbaker
10 months ago

  • Keywords reporter-feedback added

@ccprog Can you provide details on your server and mod_rewrite configuration?

FYI: Discovery does work even if mod_rewrite is not enabled via https://browser-unplugged.net/index.php?rest_route=/

#3 @ccprog
10 months ago

The public website has PHP 5.6.27, Apache/2.2.31 (Unix) with this .htaccess:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress 

cgi-fcgi settings:

cgi.check_shebang_line	1	1
cgi.discard_path	0	0
cgi.fix_pathinfo	1	1
cgi.force_redirect	0	0
cgi.ignore_repeated_errors	1	1
cgi.nph	0	0
cgi.redirect_status_env	no value	no value
cgi.rfc2616_headers	0	0
fastcgi.logging	1	1

Permalinks settings are "Month and name", Link header points to /wp-json/.

My development system is a PHP 5.6.29-0+deb8u1, lighttpd/1.4.35, no equivalent to .htaccess.

cgi-fcgi settings:

cgi.check_shebang_line	1	1
cgi.discard_path	0	0
cgi.fix_pathinfo	1	1
cgi.force_redirect	1	1
cgi.nph	0	0
cgi.redirect_status_env	no value	no value
cgi.rfc2616_headers	0	0
fastcgi.logging	1	1

Permalinks settings are "Post name", Link header points to /index.php/wp-json/.

I am aware that ?rest_route=/ works, but that is not what the Link header and rest_url('') deliver, and therefore autodiscovery fails. For example in the REST API Console plugin, the reference panel remains empty.

The essence is, as I understand it now, there are setups where

$_SERVER[REQUEST_URI] = '/index.php/wp-json/'
$_SERVER[PATH_INFO] = '/wp-json/'

The uri is then run through wp_rewrite, but PATH_INFO is not.

#4 @ccprog
10 months ago

  • Keywords reporter-feedback removed

#5 @rmccue
9 months ago

  • Milestone changed from Awaiting Review to 4.7.2
  • Owner set to rmccue
  • Status changed from new to accepted

This appears to be a bug. /wp-json/ should be stripped from PATH_INFO when we use that. However, it's strange that it's using that rather than the rest_route query var which is already available.

This requires further investigation.

@rmccue
9 months ago

Correctly determine rest_route on the index

#6 @rmccue
9 months ago

  • Keywords has-patch added

The issue was that the $path being passed in was empty due to untrailingslashit, but PATH_INFO was not empty. We can fix this by ensuring $path is never empty: the only case this can happen is when the index is being requested.

39432.diff ensures $path is never empty. Note the empty check at the start of rest_api_loaded() already determines that $path can't actually be empty.

#7 @rmccue
9 months ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 39923:

REST API: Correctly serve the index with PATH_INFO

When hitting the index, untrailingslashit() would make the REST route empty, which would then use the fallback inside WP_REST_Server. This isn't a problem most of the time, but WP_REST_Server contains a fallback to PATH_INFO. Combined with PATH_INFO permalinks, this would give a 404 on the API index, as it attempts to look up a route for "/wp-json/".

Props ccprog.
Fixes #39432.

#8 @rmccue
9 months ago

  • Keywords fixed-major added
  • Resolution fixed deleted
  • Status changed from closed to reopened

Reopening for backporting to 4.7.2.

We should also consider removing the PATH_INFO fallback, which really only existed for a very old legacy use case (a separate wp-json.php file). Technically, that may break backwards compatibility, but I highly doubt anyone is actually able to use it right now, so I don't think it would break any real code.

This ticket was mentioned in Slack in #core by jeffpaul. View the logs.


8 months ago

This ticket was mentioned in Slack in #core-restapi by rmccue. View the logs.


8 months ago

This ticket was mentioned in Slack in #core-restapi by jaschaio. View the logs.


8 months ago

#12 @rachelbaker
8 months ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 40079:

REST API: Correctly serve the index with PATH_INFO

When hitting the index, untrailingslashit() would make the REST route empty, which would then use the fallback inside WP_REST_Server. This isn't a problem most of the time, but WP_REST_Server contains a fallback to PATH_INFO. Combined with PATH_INFO permalinks, this would give a 404 on the API index, as it attempts to look up a route for "/wp-json/".

Props ccprog.
Merges [39923] to the 4.7 branch.
Fixes #39432.

#13 @lkraav
8 months ago

I can confirm this fixed the index on my nginx setup.

Note: See TracTickets for help on using tickets.