2

I'm trying to load a RSS feed with Wordpress's built-in SimplePie.

include_once(ABSPATH . WPINC . '/feed.php');
$rssURL = 'http://missionstkitts.blogspot.com//feeds/posts/default';
$rss = fetch_feed($rssURL);

To debug, I used print_r($rss); and I get a WordPress error object:

WP_Error Object
(
    [errors] => Array
        (
            [simplepie-error] => Array
                (
                    [0] => WP HTTP Error: A valid URL was not provided.
                )

        )

    [error_data] => Array
        (
        )

)

But, frustratingly, if I print $rssURL and then copy and paste it it goes straight to the correct feed. What is going on?

3 Answers3

4

Since this is the first hit in google, probably worth me adding this possible solution:

For our instance - an intranet site, pulling an rss feed from another internal page, which in-turn resolves to an RFC1918 private address the feed was being blocked by Wordpress's URL checker for security reasons.

The easiest fix in my instance was to add the following to functions.php, but this does have security implications so be sure you understand it before you add it:

add_filter( 'http_request_args', function( $args ) {
   $args['reject_unsafe_urls'] = false;
   return $args;
} );

Further discussion and more information at - https://core.trac.wordpress.org/ticket/24646

Jona
  • 305
  • 1
  • 4
  • 15
  • this solution worked perfectly for me. the problem was occurring for me on a strict firewalled server where one site was requesting an rss feed from one of it's subdomain on the same server. the fact that the firewall replies back on the private address for internal transmissions is what triggers the wordpress security policy. which happened suddenly after a wordpress update to version 4.4. thank you! – aequalsb May 25 '16 at 17:58
  • It would be nice to know what the security implications are. I would like to let through a particular url as a whitelist but leave the security in place as it is thought needed by the dev team. Removing it feels like a hammer solution when we need something that works for subdomains on our own network. – landed Jul 18 '16 at 16:28
1

By adding preg_match for specific urls we can minimize the amount of parsed unsafed urls:

function http_request_local( $args, $url ) {
   if ( preg_match('/xml|rss|feed/', $url) ){
      $args['reject_unsafe_urls'] = false;      
   }
   return $args;
}
add_filter( 'http_request_args', 'http_request_local', 5, 2 );
steffanjj
  • 881
  • 9
  • 10
0

So, while the above answers work, I think that there's a way to do this that is better to make sure that you're limiting the scope of where you're making the URL request to instead of allowing everything to go. So I'm proving the following information to anyone who stumbles across this just in case it helps.

This answer is useful if the resulting calls are to internal servers cross-communicating on private IPs but are still publicly accessible.

The snippet below is to be run on the site that's calling the RSS feed. The site that is providing the feed does not need this.

add_filter('http_request_host_is_external', function($bool, $host, $url){
        if($url === 'https://www.example.com/news/feed/' && $host === 'www.example.com'){
                return true;
        }
}, 10, 3);
Saucey
  • 11
  • 4