Ticket #517 (new defect)

Opened 2 years ago

Last modified 2 years ago

Headers not preserved

Reported by: boredzo Assigned to: gallir
Priority: normal Component: wp-cache
Severity: normal Keywords: patch headers callbacks shutdown
Cc:

Description

WP-Cache does not preserve any headers in cached output — not even known headers such as Content-Type. (Among other things, this causes feeds to be delivered as text/html.)

There are two reasons why the headers are dropped.

Cause #1

In some environments, such as FastCGI (an Apache extension, which TextDrive uses by default), apache_response_headers is not available. WP-Cache relies on this function to get the headers in order to cache them.

Fix

PHP 5 provides headers_list, but it returns an ordered array instead of an associative array. Still, something is better than nothing; when apache_response_headers is not available; headers_list should be used.

Cause #2

WP-Cache registers two callbacks:

  • An output buffer callback, wp_cache_ob_callback.
  • A shutdown callback, wp_callback_ob_end.

Contrary to the name of the shutdown callback, it has nothing to do with the output buffer. It is called when php finishes executing, and calls ob_end_clean (or ob_end_flush), causing the output buffer callback to be called. Thus, “*_ob_end” is called before*_ob_callback”.

That part is cosmetic, however; it doesn't directly cause any bugs. What does is the fact that *_ob_end relies on the $meta_object object, but this object is not created until *_ob_callback. *_ob_end dutifully sets up all the headers into the meta object, but since the meta object is undefined until ob_end_flush is called, none of that has any effect, so the headers have in fact not been put into anything.

Fix

Move the creation of $meta_object from *_ob_callback to *_ob_end, and for clarity's sake, rename *_ob_end to *_shutdown_callback.


The attached patch addresses both causes by implementing both fixes. I include a function, of my own creation, which tries apache_response_headers first, followed by headers_list (gathering the headers therefrom into a new associative array), followed by returning null. The opposite order of preference may be desired. headers_list will only be tried if it exists, which preserves workingness on PHP versions before 5.

Attachments

patch-headers.diff (4.0 kB) - added by boredzo on 12/31/06 09:41:57.
Patch implementing a replacement for apache_response_headers, renaming the shutdown callback, and relocating the creation of $meta_object.

Change History

12/31/06 09:41:57 changed by boredzo

  • attachment patch-headers.diff added.

Patch implementing a replacement for apache_response_headers, renaming the shutdown callback, and relocating the creation of $meta_object.

12/31/06 09:43:50 changed by boredzo

I had to reupload the patch because I did not include the call to the new function in the patch.

This is what I get for making two fixes at once and then splitting them out into separate patches. ;)

12/31/06 09:49:47 changed by boredzo

And I meant #516, not #536, in that “ob_end_flush” link.