Allow headers to be replaced
killes@www.drop.org - May 9, 2008 - 09:22
| Project: | Drupal |
| Version: | 7.x-dev |
| Component: | base system |
| Category: | feature request |
| Priority: | normal |
| Assigned: | killes@www.drop.org |
| Status: | patch (code needs work) |
Description
PHP has a feature which allows the scipt to overwrite sent headers. I'd like to implement the same for Drupal. It is for example useful to overwrite the Content-Type header if what you are sending should not be XHTML.
| Attachment | Size |
|---|---|
| header-override.patch | 1.59 KB |

#1
The separation based on space is safe, thanks to the definition of the "field-name" production, which in turn is a "token", the production of which does prohibit white space (RFC2616, §2.2) (see the "separators" production).
However, if $replace is false, the $stored_headers nonetheless contains a single row per field-name, although multiple headers are allowed to define the same field-name, as in:
<?phpdrupal_set_header('WWW-Authenticate: Negotiate');
drupal_set_header('WWW-Authenticate: NTLM', false);
?>
which this implementation does not cover: a drupal_get_header() after this would only return the "NTLM" header, in spite of the "false" passed to drupal_set_header.
#2
How about this one?
#3
I'm not sure there is a guarantee from PHP regarding the order in which the headers are sent when mixing numeric and non-numeric keys as you are doing. But HTTP/1.1 §4.2 specifies that the order in which the headers for the same key are send IS significant, so the code MUST make sure they are output in the order the caller intended, and I think it would be better to make the keys clearer.
Also, if a given key happens to be numeric, like drupal_set_header("0: 42"); I think it will be stored as $stored_headers["1"] and you will probably get the expected result when a repeated header happens, since the real numeric keys do not have the same type, but that really seems relying on an edge behaviour.
What would you think or storing things along the lines of:
<?php$stored_headers[$key][] = $value;
?>
This would allow headers under the same key to be automatically ordered. The order of headers of different keys is NOT significant anyway, as per the same 4.2 section.
#4
I suggest using comma as separator between multiple headers with the same field-name, i.e. "WWW-Authenticate: Negotiate,NTLM". This combined form is equivalent to sending the two headers separately (section 4.2 again).
Note that field-names are case-insensitive, so in the following example, the latter should overwrite the former, and the string "123" should not appear in the output from drupal_get_headers().
drupal_set_header('FOO: 123');drupal_set_header('foo: 456', TRUE);
I believe you should explode on colon rather than space, because the space is optional - i.e. to support calls like this:
drupal_set_header('Foo:Bar');#5
@c960657: good points about explode.
Comma syntax is fine, and actually a bit more bandwidth-efficient, although not by much. But to make things clear, it should only be used when actually outputting the headers, not be a requirement of drupal_set_header, because forcing the app developer to merge his calls is an undue limitation. And since the headers are currently not buffered, but sent with each call, it does not seem feasible unless that "synchronous output" choice is removed.