Dear Maintainer,

I've tried to reproduce the problem in Debian sid, and it still exists. I've looked at the source code, and the problem should be easy to fix.

Actually, the "charset=%s" problem are two different, but closely related problems.

The entire source code contains "charset=%s" only three times:

(1) In do_file() starting at line 1593, "charset=%s" may be returned by figure_mime() into mime_type, it is then passed to snprintf(fixed_mime_type, sizeof(fixed_mime_type), mime_type, charset) to expand %s to the default charset in fixed_mime_type, and a few lines below, fixed_mime_type is passed to add_headers().

This seems to be the way that "charset=%s" was intended to be used.

No problem here.

(2) In do_dir() starting at line 1731, "charset=%s" is directly passed to add_headers(), without any call to snprintf().

To me, this looks like a little oversight, I would gess the "charset=%s" was added in assuming that add_headers() would expand "%s" (which is does not).

Looking up a few lines (line 1678), the generated HTML response sets the charset to UTF-8 via a META element, so it makes no sense to use any other charset than UTF-8 in do_dir().

So the fix for do_dir() is simple: Replace "charset=%s" with "charset=UTF-8" in line 1731.

This actually makes the META element in line 1678 redundant, so the entire line 1678 should be removed.

(3) In send_error() a line 2465, add_headers() is againg called with a literal "charset=%s", without any call to snprintf().

This seems to be the same little oversight as in do_dir().

send_error() is always called with a fixed title and a fixed error message, and except for the call in send_authenticate() line 2431, the extra_header parameter is always empty. It is very tempting to just use a hardcoded "charset=UTF-8" as in do_dir(), but send_error() has one extra trick: It calls send_error_body(), which in turn calls send_error_file to handle custom error pages. They should be encoded in the default charset, which may be something else than UTF-8.

So send_error() needs to follow the behaviour of do_file(): Use a buffer and snprintf() to expand %s to the default charset. In other words:

Replace  starting at line 2465 ...

    add_headers(s, title, extra_header, "", "text/html; charset=%s", (off_t) -1, (time_t) -1);

... with ...

    char fixed_mime_type[500];
    (void) snprintf(
        fixed_mime_type, sizeof(fixed_mime_type), "text/html; charset=%s", charset );
    add_headers(
        s, title, extra_header, "", fixed_mime_type, (off_t) -1, (time_t) -1 );

... and remove the hardcoded META element emitted by send_error_body() in line 2511.


Testing in a default installation of mini-httpd can be done from the shell:

root@debian-sid:~# mkdir -p /var/www/html/directory
root@debian-sid:~# echo -en 'GET /no/such/file HTTP/1.0\r\n\r\n' | nc 127.0.0.1 80 | grep -i Content-Type
Content-Type: text/html; charset=%s
    <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
root@debian-sid:~# echo -en 'GET /directory/ HTTP/1.0\r\n\r\n' | nc 127.0.0.1 80 | grep -i Content-Type
Content-Type: text/html; charset=%s
    <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
root@debian-sid:~#


Best regards,

Alexander Foken

--

Alexander Foken
mailto:alexan...@foken.de

Reply via email to