Make WordPress Core

Opened 7 years ago

Closed 6 years ago

#43691 closed defect (bug) (fixed)

class-wp-rest-server sends response body regardless of actual response code or result type

Reported by: matthiasthiel's profile matthias.thiel Owned by: timothyblynjacobs's profile TimothyBlynJacobs
Milestone: 5.3 Priority: normal
Severity: normal Version: 4.4
Component: REST API Keywords: has-patch has-unit-tests
Focuses: rest-api Cc:

Description

The WP Rest Server always echoes the result of wp_json_encode unless there is an error.

See line 410 of class-wp-rest-server.php

echo $result;

A use case where this leads to an undesired behaviour is when using the HTTP Status Code 204 which implies no response body being sent. Returning a rest response with a status code 204 will send a body at the moment.

There are two problems with this behaviour:

  1. A response status 204 should not send any body content
  2. A response data of null (new \WP_REST_Response( null, 204 )) will be sent as the (string) null

Most clients are pretty forgiving and will ignore the request body but MacOS Safari will not complete the request in this situation and will try to parse the null response as JSON. I found the behaviour is also server configuration specific as some configurations will strip the response body automatically and some will not.

Since there is no consistency in treating a 204 response by servers and browsers, I would suggest to stick to the spec (https://tools.ietf.org/search/rfc2616#section-4.3) and not return a response at all.

I can see two ways to achieve this:

  1. Consult the response status to decide whether or not to return a response body, which is spec compliant
  2. Consult the response data and treat null by not sending a response body, which honours the semantic of null.

Attachments (3)

43691.diff (846 bytes) - added by andizer 6 years ago.
43691-2.diff (740 bytes) - added by andizer 6 years ago.
Remove the 410, 451 types which actually can have a body.
43691.2.diff (2.0 KB) - added by TimothyBlynJacobs 6 years ago.

Download all attachments as: .zip

Change History (16)

#1 @pento
6 years ago

  • Version trunk deleted

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


6 years ago

#3 @TimothyBlynJacobs
6 years ago

  • Keywords needs-patch added
  • Milestone changed from Awaiting Review to 5.3
  • Owner set to TimothyBlynJacobs
  • Status changed from new to assigned
  • Version set to 4.7

There is a related Gutenberg ticket, https://github.com/WordPress/gutenberg/pull/11208

Handling null is probably the safest way to go. It is hard to see a reason why someone would expect the string "null" to appear in the response body when using the null type in PHP and as such is least likely to cause a BC break.

We could also consider adding a _doing_it_wrong if a response body is sent with a 204 response code.

#4 @TimothyBlynJacobs
6 years ago

  • Version changed from 4.7 to 4.4

@andizer
6 years ago

@andizer
6 years ago

Remove the 410, 451 types which actually can have a body.

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


6 years ago

#6 @TimothyBlynJacobs
6 years ago

  • Keywords needs-unit-tests added

Thanks for the patch @andizer!

After discussing in #core-restapi, I think it makes sense to drop the _doing_it_wrong if people are sending null without using the 204 response code and instead return null there as well.

Do you want to work on unit tests for this?

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


6 years ago

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


6 years ago

#9 @TimothyBlynJacobs
6 years ago

  • Keywords has-patch has-unit-tests added; needs-patch needs-unit-tests removed

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


6 years ago

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


6 years ago

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


6 years ago

#13 @kadamwhite
6 years ago

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

In 45809:

REST API: Do not send response body if status is 204 or body is null.

Status code 204 should indicate no response body is sent. Previously, a "null" string was sent, which MacOS Safari would try to parse as JSON and thereby fail to complete the request.

Props TimothyBlynJacobs, andizer, matthias.thiel.
Fixes #43691.

Note: See TracTickets for help on using tickets.