WordPress.org

Make WordPress Core

Opened 6 months ago

Closed 4 months ago

Last modified 4 months ago

#40886 closed defect (bug) (fixed)

REST API: PUT requests fail on Nginx servers when fancy permalinks aren't enabled

Reported by: Joen Owned by: pento
Milestone: 4.8.1 Priority: normal
Severity: normal Version: 4.4
Component: REST API Keywords: fixed-major
Focuses: rest-api Cc:

Description

Steps to reproduce:

  1. have a web server running nginx, or use wp docker or vvv fresh installs
  2. have fancy permalinks disabled, use the stock ?p=123 ones
  3. install the Gutenberg editor from https://github.com/WordPress/gutenberg as an activated plugin. Be sure to npm install, npm run build etc.
  4. load the Gutenberg menu item in the sidebar
  5. Press Save draft button, then press Update, and you'll see an error message in the console: PUT http://localhost/?rest_route=/wp/v2/posts/6 405 (Not Allowed)

If you go to Settings > Permalinks, and choosing any fancy permalink option, saving works fine.

From @pento:

So, it seems that ngx_http_index_module, the nginx module that redirects / to /index.php ignores all methods except GET, HEAD, and POST.
Editing the post sends a PUT, which is rejected.

See also, trac discussion starting here: https://wordpress.slack.com/archives/C02RQC26G/p1496136902282711

Attachments (3)

405.png (195.6 KB) - added by Joen 6 months ago.
40886.diff (1.5 KB) - added by pento 6 months ago.
40886.2.diff (18.5 KB) - added by pento 6 months ago.

Download all attachments as: .zip

Change History (22)

@Joen
6 months ago

#1 @jnylen0
6 months ago

  • Version changed from 4.7 to 4.4

More discussion at https://github.com/WordPress/gutenberg/pull/862. Sending e.g. any API PUT request to a default install of VVV should be enough to reproduce this.

@pento
6 months ago

#2 @pento
6 months ago

  • Keywords has-patch has-unit-tests added
  • Milestone changed from Awaiting Review to Future Release

While this does affect Gutenberg development, it's fairly edge case-y, with a known workaround (enable pretty permalinks).

Unless there's an urgent need for it otherwise, it can go into 4.9.

#3 @dd32
6 months ago

While working around the issue isn't out of the question (I'd suggest that it shouldn't use the $is_nginx variable, and should just always return that, for consistency), I'm a little concerned that 40886.diff makes it seem like PUT not working isn't an expected behaviour.

It's completely an expected behaviour for a server not to accept a non-GET/HEAD/POST request, it's the exact reason why the `method` overrides are available in both WordPress and many other api platforms. (Also because sometimes in-between proxies/etc mangle requests)

Possibly this is something that could/should be handed by wp.js? If a request is rejected with 405 (Not Allowed) flip the flag and just use the overrides transparently?

#4 @pento
6 months ago

Yah, I agree about $is_nginx, that's a little overkill.

I don't really like fixing it only in wp-api.js, as then it's only fixed there, rather than fixed for anything that talks to the REST API.

Do we have examples of the REST API being broken by the server only accepting HTTP/1.0 methods? If so, we could look at a more generic solution, but otherwise, I think a small change for weird behaviour in a popular web server is appropriate.

@pento
6 months ago

#5 follow-up: @nacin
5 months ago

40886.2.diff is only handles nginx oddies. It doesn't solve about a thousand other things that can go wrong.

I'd pretty strongly argue that WordPress core should always only use GET/POST/HEAD and, as appropriate, the method overrides for any other methods. It's nice that the REST API server will accept PUT, DELETE, or what have you, but we can't expect servers to allow it. I wouldn't even wait for a 405, I'd just use the overrides.

#6 in reply to: ↑ 5 ; follow-up: @jnylen0
5 months ago

Replying to dd32:

I'm a little concerned that 40886.diff makes it seem like PUT not working isn't an expected behaviour.

I don't think this is an expected behavior. Common, or at least known under certain configurations, but still seems broken/buggy to me.

Replying to nacin:

40886.2.diff only handles nginx oddities

Though isn't it only needed for certain permalink structures? Unless I am missing something, the current patch reads as though it will add index.php to pretty permalinks as well.

I'd like to see more testing around different combinations of permalink structures + this issue, and that we don't add index.php unless the current permalink structure dictates that it's necessary.

I'd pretty strongly argue that WordPress core should always only use GET/POST/HEAD

This seems fine to me, though I'd also be in favor of working around what seems to me like buggy behavior.

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


4 months ago

#8 @karmatosed
4 months ago

I experienced this myself whilst testing the live settings plugin. It was fixed by setting to non-default permalinks, but still something really needs fixing.

#9 in reply to: ↑ 6 @pento
4 months ago

  • Keywords commit added
  • Milestone changed from Future Release to 4.8.1
  • Owner set to pento
  • Status changed from new to assigned

Replying to jnylen0:

Though isn't it only needed for certain permalink structures? Unless I am missing something, the current patch reads as though it will add index.php to pretty permalinks as well.

40886.2.diff only adds index.php if permalink_structure is not set.

Unless anyone has further ideological problems with continuing Core's practice of quietly handling odd server behaviour as it crops up, I'm going to sneak this into 4.8.1 tomorrow, because bugging out while testing feature projects does not make for useful feedback.

#10 @jnylen0
4 months ago

Yep, I misread the patch, sorry. This came up again today during Gutenberg development. +1 for commit.

#11 @westonruter
4 months ago

This may be also the issue reported at https://github.com/WordPress/gutenberg/issues/1935

Or it is closely related. Note that there the message is “406 Not Acceptable”.

#12 @pento
4 months ago

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

In 41139:

REST API: Always add index.php to the REST URL when pretty permalinks are disabled.

When pretty permalinks are disabled, the web server will internally forward requests to index.php. Unfortunately, nginx only forwards HTTP/1.0 methods: PUT, PATCH, and DELETE methods will return a 405 error.

To work around this nginx behaviour, including index.php in the REST URL skips the internal redirect.

Fixes #40886.

#13 @pento
4 months ago

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

#14 @pento
4 months ago

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

In 41140:

REST API: Always add index.php to the REST URL when pretty permalinks are disabled.

When pretty permalinks are disabled, the web server will internally forward requests to index.php. Unfortunately, nginx only forwards HTTP/1.0 methods: PUT, PATCH, and DELETE methods will return a 405 error.

To work around this nginx behaviour, including index.php in the REST URL skips the internal redirect.

Merges 41139 to the 4.8 branch.
Fixes #40886.

#15 @pento
4 months ago

  • Keywords has-patch has-unit-tests commit fixed-major removed
  • Resolution fixed deleted
  • Status changed from closed to reopened

Re-opening, I forgot to update wp-api-generated.js.

#16 @pento
4 months ago

In 41154:

REST API: Update the fixture data for wp-api.js tests.

[41139] changed how the REST API URL is generated, but included an incorrect version of wp-api-generated.js.

This updates the generator to create the correct wp-api-generated.js, and updates wp-api-generated.js`.

See #40886.

#17 @pento
4 months ago

  • Keywords fixed-major added

#18 @pento
4 months ago

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

In 41155:

REST API: Update the fixture data for wp-api.js tests.

[41139] changed how the REST API URL is generated, but included an incorrect version of wp-api-generated.js.

This updates the generator to create the correct wp-api-generated.js, and updates wp-api-generated.js`.

Repeat of [41154], in the 4.8 branch.
Fixes #40886.

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


4 months ago

Note: See TracTickets for help on using tickets.