[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#388443: apache2: MUST NOT send data in an 304 reply



Package: apache2
Version: 2.0.55-4.1
Severity: normal
Tags: upstream

A php script may set the http reply code to 304 i.e. "not modified".
Then Apache happily forwards that code to the caller and also all other
data supplied by that script, for example:

| <?php
| header('HTTP/1.0 304 Not Modified');
| ?>
| Hello World
[ foo.php ]

yields

| $ telnet localhost 80
| Trying 127.0.0.1...
| Connected to localhost.localdomain.
| Escape character is '^]'.
| GET /foo.php HTTP/1.0
|
| HTTP/1.1 304 Not Modified
| Date: Wed, 20 Sep 2006 08:56:51 GMT
| Server: Apache/2.0.55 (Debian) PHP/4.4.2-1.1
| Connection: close
|
| Hello World
|
| Connection closed by foreign host.

which is an "absolute prohibition" of the RfC 2616

| 4.3 Message Body
| (...)
|                                                     All 1xx
|    (informational), 204 (no content), and 304 (not modified) responses
|    MUST NOT include a message-body.

| 10.3.5 304 Not Modified
| (...)
|                                   The 304 response MUST NOT contain a
|    message-body, and thus is always terminated by the first empty line
|    after the header fields.
(RfC 1945 regarding HTTP/1.0 tells basically the same)

Therefore, apache has to chop the data supplied by a script and must not
send any data beyond the header.

Things are worse: Even if a script behaves well e.g. it basically does

| <?php
| header('HTTP/1.0 304 Not Modified');
| ?>

there is still a body of a single empty line. If compression/deflate is
enabled, the null string is blown up to 20 bytes of undeclared(!)
gzip'ed data.

Therefore this report is assigned to apache by intention. This is not a
real bug in php, although php /should/ not not send such superflous
data. But the same misbehaviour of apache be be triggered when calling a
cgi-bin script like

| #!/bin/sh
| echo "Status: 304 Not Modified"
| echo "Content-Type: text/plain"
| echo ""
| echo "Hello World."


The effect of this bug becomes visible if such a generated page is
accessed via the squid proxy server. Probably the most popular case is
reading the rss file of a blog powered by serendipidy (s9y)[1]. This php
script sets the http reply code 304 to indicate there are no new entries
but apache with compression still sends the null body gzip'ed. As a
result squid logs messages like

| squid[2678]: httpReadReply: Excess data from "GET http://blog.$DOMAIN.de/feeds/index.rss1";

    Christoph

[1] I'd like to emphasize s9y is not to blame here. It sets the 304 code
    and does not send any additional data.

-- System Information:
Debian Release: testing/unstable
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.17.13
Locale: LANG=en_US, LC_CTYPE=en_US (charmap=ISO-8859-1)

Versions of packages apache2 depends on:
ii  apache2-mpm-prefork           2.0.55-4.1 traditional model for Apache2

Attachment: signature.asc
Description: Digital signature


Reply to: