WordPress.org

Make WordPress Core

Opened 5 months ago

Closed 4 months ago

#39066 closed defect (bug) (fixed)

`fetch_feed()` changes REST API response `Content-Type`

Reported by: dlh Owned by: rmccue
Milestone: 4.7.1 Priority: normal
Severity: normal Version:
Component: Feeds Keywords: has-patch commit fixed-major
Focuses: rest-api Cc:

Description

I have a custom endpoint that returns data derived from widgets. WP_Widget_RSS::widget() calls fetch_feed(), which sends a Content-type: text/html header via SimplePie::handle_content_type(). So, if I don't send another application/json header at the end of my callback, the response content type ends up text/html.

This could be "fixed" by resending the application/json header after running a route callback. But any function could still change the headers later, so resending the header seems a little arbitrary.

Another approach would be to, case-by-case, catch core functions that could inadvertantly change headers during an API response. The attached patch would implement this approach for fetch_feed(). But having to apply the same fix to multiple functions over time could also get inefficient.

Of course, a third approach could be to call it a wontfix based on nothing being "wrong" in either fetch_feed() or the API.

Attachments (3)

39066.diff (619 bytes) - added by dlh 5 months ago.
39066.2.diff (746 bytes) - added by mboynes 5 months ago.
Update patch to also check ajax and xmlrpc requests
39066.3.diff (475 bytes) - added by stevenkword 4 months ago.
Remove SimplePie::handle_content_type()

Download all attachments as: .zip

Change History (14)

@dlh
5 months ago

#1 @rachelbaker
5 months ago

  • Component changed from REST API to Feeds
  • Focuses rest-api added

#2 @mboynes
5 months ago

It seems like it would be worth also checking if the request is an ajax or xmlrpc request, since this bug could impact those responses as well.

@mboynes
5 months ago

Update patch to also check ajax and xmlrpc requests

#3 @stevenkword
5 months ago

I like this, but am wondering how many other places this is going to pop up. I'm in favor of performing the check just for feeds for now and am taking a stab at writing some tests around it.

Last edited 5 months ago by stevenkword (previous) (diff)

#4 follow-up: @rmccue
4 months ago

  • Keywords needs-patch added
  • Milestone changed from Awaiting Review to 4.7.1

I would rather we simply not call handle_content_type(). This only exists to set the charset in the header to match the feed, but we already set the charset to get_option( 'blog_charset' ) above, so it's not necessary. At best, it's redundant already.

@stevenkword
4 months ago

Remove SimplePie::handle_content_type()

#5 in reply to: ↑ 4 ; follow-up: @stevenkword
4 months ago

Replying to rmccue:

I would rather we simply not call handle_content_type(). This only exists to set the charset in the header to match the feed, but we already set the charset to get_option( 'blog_charset' ) above, so it's not necessary. At best, it's redundant already.

I can confirm this resolves the header "Content-type:" issue and have attached 39066.3.diff

I used to code below to verify functionality. However, I am questioning whether it is okay to force the character set from a 3rd party to the same one used by the WP instance.

<?php
/**
 * Grab 3rd party feed
 *
 * @param array $data Options for the function.
 * @return string URI of the feed.
 */
function my_custom_rest_endpoint( $data ) {

	$uri = 'https://make.wordpress.org/core/feed/';
	$feed = fetch_feed( $uri );

	return $uri;
}

// e.g.) http://src.wordpress-develop.dev/wp-json/custom/v1/feed
add_action( 'rest_api_init', function () {
	register_rest_route( 'custom/v1', '/feed/', array(
		'methods' => 'GET',
		'callback' => 'my_custom_rest_endpoint',
	) );
} );
Last edited 4 months ago by stevenkword (previous) (diff)

#6 @rachelbaker
4 months ago

  • Keywords has-patch added; needs-patch removed
  • Owner set to rmccue
  • Status changed from new to reviewing

@rmccue Can you review @stevenkword's patch and decide if this is committable or needs to be punted to 4.7.2?

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


4 months ago

#8 in reply to: ↑ 5 @rmccue
4 months ago

  • Keywords commit added

Replying to stevenkword:

However, I am questioning whether it is okay to force the character set from a 3rd party to the same one used by the WP instance.

This already happens (and has done so since we originally added SimplePie, I think) with the set_output_encoding call. Internally, SimplePie uses mbstring/iconv to handle encodings, so I don't forsee any issues with it really.

#9 @rmccue
4 months ago

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

In 39681:

Feeds: Don't override the Content-Type header inside fetc_feed()

SimplePie can set the Content-Type header automatically with the correct charset for convenience, but we already force the charset to match the site's, making it redundant at best. At worst, SimplePie incorrectly overrides the content-type for non-HTML content (such as API requests).

Props dlh, stevenkword.
Fixes #39066.

#10 @rmccue
4 months ago

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

#11 @dd32
4 months ago

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

In 39683:

Feeds: Don't override the Content-Type header inside fetch_feed().

SimplePie can set the Content-Type header automatically with the correct charset for convenience, but we already force the charset to match the site's, making it redundant at best. At worst, SimplePie incorrectly overrides the content-type for non-HTML content (such as API requests).

Props dlh, stevenkword, rmccue.
Merges [39681] to the 4.7 branch.
Fixes #39066.

Note: See TracTickets for help on using tickets.