Fixing Feed Problems with WordPress 2.0.6 and PHP 5.2

Upgraded to WordPress 2.0.6 and now feeds are broken. At least, they’re broken in Firefox, IE7, and KDE (Konqueror & Akregator). Something seems to be interrupting the transfer, causing them to get a blank file. Oddly, they work fine in Opera, the LWP “GET” command-line utility, and Dillo (not that Dillo can do anything but display the source, but it gets the whole file.) Even more oddly, SeaMonkey seems to have no problems. You’d think Firefox and SeaMonkey would have the same issues. Also, I seem to be able to sometimes get it to work on reload.

Anyway, I’m working on it. If you read this site via RSS or Atom, and it is working, let me know (and let me know which feed reader you’re using). I suppose it could be cookie-related, though I’ve already tried clearing cookies. I’ve also tried disabling just about every plugin I use that does something to feeds or headers, to no avail.

Update: I think I’ve got it. By using the Tamper Data extension, I was able to determine that the 304 Not Modified status was not being set properly. Instead of actually issuing the 304 status, it would issue a 200 OK, then send a Status: 304 header later in the response. It never showed any problems on command-line GET or HEAD because they weren’t conditional. That’s also why forcing reload would work.

I looked into wp-includes/functions.php and found the status_header function. Then I looked at the following line:

@header("Status: $header $text");

In theory this should work. Traditionally, setting a “Status” header will replace the actual HTTP status. But that’s not how the PHP manual says to do it. They suggest issuing the actual header that the server would send: HTTP/1.1 304 Not Modified. I noticed that the header function in PHP has some optional parameters, including one to force the HTTP status. That felt a little cleaner than hard-coding the protocol (since an older browser might make an HTTP/1.0 request, and it should get an HTTP/1.0 response), so I changed the line to this:

@header("Status: $header $text", TRUE, $header);

It seems to have fixed the problem.

For the record, this is PHP 5.2.0 on Apache 1.3.37 using the mod_php interface.

Update 2: Simpler fix just removes the if.. statement and else… section so that it’s just the following:

@header("HTTP/1.1 $header $text");

Bug reported as Ticket 3528.

It’s also worth mentioning that I had to apply the workaround in Ticket 3354 for another issue (single-post pages were getting cut off before the comments).

Update 3: Here are the exact changes I made:

Keep in mind that this has only been tested on this config. If feeds still work after you upgrade, don’t change it.

Open the file wp-includes/functions.php and look for this section:

function status_header( $header ) {								
	if ( 200 == $header )
		$text = 'OK';
	elseif ( 301 == $header )
		$text = 'Moved Permanently';
	elseif ( 302 == $header )
		$text = 'Moved Temporarily';
	elseif ( 304 == $header )
		$text = 'Not Modified';
	elseif ( 404 == $header )
		$text = 'Not Found';
	elseif ( 410 == $header )
		$text = 'Gone';

		if ( substr(php_sapi_name(), 0, 3) == 'cgi' )
			@header("HTTP/1.1 $header $text");
		else
			@header("Status: $header $text");
}

In the last four lines (not counting the closing }), disable everything but the one with HTTP/1.1 by adding // to the beginning.

		//if ( substr(php_sapi_name(), 0, 3) == 'cgi' )
			@header("HTTP/1.1 $header $text");
		//else
			//@header("Status: $header $text");

Update 4: Mark Jaquith has posted more on this issue, including a patch and a replacement functions.php.

View Kelson Vibber's LinkedIn profileView Kelson Vibber's profile on LinkedIn

12 thoughts on “Fixing Feed Problems with WordPress 2.0.6 and PHP 5.2

  1. Rialtus

    I use Google Reader and have been getting your updates just fine. It’s currently 12:47 PM Pacific, and the feed updated about 27 minutes ago.

  2. brion

    I haven’t had any luck logging into wordpress’s trac to comment, so I’ll add here. :)

    This is the breaking change:

    – @header(“HTTP/1.1 $header $text”);
    – @header(“Status: $header $text”);
    + if ( substr(php_sapi_name(), 0, 3) == ‘cgi’ )
    + @header(“HTTP/1.1 $header $text”);
    + else
    + @header(“Status: $header $text”);

    Thus instead of hedging its bets by sending both forms to the server, it’s only sending one form depending on how PHP’s set up.

    If I’m not mistaken, the condition should be reversed: the ‘Status’ pseudoheader should be used only for CGI, while Apache/mod_php and other environments want the HTTP/1.x line directly.

    In MediaWiki we use the HTTP/1.x form pretty exclusively, actually, and it’s fine with my lighttpd/FastCGI test box as well as our production apache/mod_php boxes… I’m not entirely sure what it _does_ break with.

  3. Johanna

    If someone isn’t as comfortable in PHP as you are, would you recommend that they wait to upgrade based on this? I get a significant amount of traffic through feeds and would hate to have problems with them. I’m hoping that 2.1 isn’t too far off.

    Thanks for sharing your experiences.

  4. Kelson Post author

    Brion — Thanks, I’ll paste that into the ticket!

    Johanna — Unfortunately, it seems that the security hole could let someone hack into your site, so I wouldn’t recommend waiting at this point. (It would have been nice if they’d made that clear in the original announcement!)

    On the plus side, it’s a really simple change to make. The hard part was finding where to make it. And I suspect it’s dependent on the version of PHP, or possibly the combination of the PHP version and Apache version, so it might not cause problems with your setup.

    Also, I read somewhere in the support forums that upgrading from 2.0.5 to 2.0.6 doesn’t change the database, so you can move back to 2.0.5 just by restoring the files.

    I’ll add the exact changes I made to the post (since comments don’t allow quite the same level of formatting). If you like, I can email you my copy of the file. That way if you upgrade and it breaks the feeds, you can just upload the altered file.

  5. Johanna

    Thanks so much for pointing out why I should upgrade! I agree, more specific information would have been nice. I’ve done the upgrade now, and it went smoothly enough — I used your second update approach, just commenting out the if/then around the problem lines. I very much appreciate your support in this — made me feel much more comfortable.

  6. Pingback: Recommended Update: WordPress 2.0.6 at The Blog Herald

  7. Josh

    Thanks for reporting this. I discovered the problem with Google’s Webmaster tools, where it said my 404 was returning a status of 200 OK. But I have gotten blank feed reports, and also had trouble with FeedBurner. The fix from Mark Jacquith fixed all of this.

  8. Pingback: WordPress 2.0.7 security & feed fix | K-Squared Ramblings

  9. Mark Siedle

    Thanks for this info …I was having feed problems with WP2.0.6, so I upgraded to WP2.1 and all problems fixed. Upgrade went smoothly too, no problems.

    Cheers,
    Mark

  10. Kelson Post author

    Marcus, this bug was breaking feeds handled through FeedBurner too, because it interfered with the data that FeedBurner uses. In any case, it was fixed four months ago, so you’re better off just upgrading to a newer version of WordPress.

Comments are closed.