Implement --no-server-id

Suggested by: T.Ramirez
This commit is contained in:
Emil Mikulic 2013-04-29 00:55:08 +10:00
parent ccf0dbd809
commit 5a0291f47e
4 changed files with 73 additions and 26 deletions

View File

@ -271,7 +271,8 @@ static char *logfile_name = NULL; /* NULL = no logging */
static FILE *logfile = NULL; static FILE *logfile = NULL;
static char *pidfile_name = NULL; /* NULL = no pidfile */ static char *pidfile_name = NULL; /* NULL = no pidfile */
static int want_chroot = 0, want_daemon = 0, want_accf = 0, static int want_chroot = 0, want_daemon = 0, want_accf = 0,
want_keepalive = 1; want_keepalive = 1, want_server_id = 1;
static char *server_hdr = NULL;
static uint64_t num_requests = 0, total_in = 0, total_out = 0; static uint64_t num_requests = 0, total_in = 0, total_out = 0;
static int running = 1; /* signal handler sets this to false */ static int running = 1; /* signal handler sets this to false */
@ -888,6 +889,9 @@ static void usage(const char *argv0) {
"\t\tRequests to the host are redirected to the corresponding url.\n" "\t\tRequests to the host are redirected to the corresponding url.\n"
"\t\tThe option may be specified multiple times, in which case\n" "\t\tThe option may be specified multiple times, in which case\n"
"\t\tthe host is matched in order of appearance.\n\n"); "\t\tthe host is matched in order of appearance.\n\n");
printf("\t--no-server-id\n"
"\t\tDon't identify the server type in headers\n"
"\t\tor directory listings.\n");
} }
/* Returns 1 if string is a number, 0 otherwise. Set num to NULL if /* Returns 1 if string is a number, 0 otherwise. Set num to NULL if
@ -1009,6 +1013,9 @@ static void parse_commandline(const int argc, char *argv[]) {
url = argv[i]; url = argv[i];
add_forward_mapping(host, url); add_forward_mapping(host, url);
} }
else if (strcmp(argv[i], "--no-server-id") == 0) {
want_server_id = 0;
}
else else
errx(1, "unknown argument `%s'", argv[i]); errx(1, "unknown argument `%s'", argv[i]);
} }
@ -1285,6 +1292,19 @@ static const char *keep_alive(const struct connection *conn)
return (conn->conn_close ? "Connection: close\r\n" : keep_alive_field); return (conn->conn_close ? "Connection: close\r\n" : keep_alive_field);
} }
/* "Generated by " + pkgname + " on " + date + "\n"
* 1234567890123 1234 2 ('\n' and '\0')
*/
static char _generated_on_buf[13 + sizeof(pkgname) - 1 + 4 + DATE_LEN + 2];
static const char *generated_on(const char date[DATE_LEN]) {
if (!want_server_id)
return "";
snprintf(_generated_on_buf, sizeof(_generated_on_buf),
"Generated by %s on %s\n",
pkgname, date);
return _generated_on_buf;
}
/* A default reply for any (erroneous) occasion. */ /* A default reply for any (erroneous) occasion. */
static void default_reply(struct connection *conn, static void default_reply(struct connection *conn,
const int errcode, const char *errname, const char *format, ...) const int errcode, const char *errname, const char *format, ...)
@ -1306,21 +1326,21 @@ static void default_reply(struct connection *conn,
"<h1>%s</h1>\n" /* errname */ "<h1>%s</h1>\n" /* errname */
"%s\n" /* reason */ "%s\n" /* reason */
"<hr>\n" "<hr>\n"
"Generated by %s on %s\n" "%s" /* generated on */
"</body></html>\n", "</body></html>\n",
errcode, errname, errname, reason, pkgname, date); errcode, errname, errname, reason, generated_on(date));
free(reason); free(reason);
conn->header_length = xasprintf(&(conn->header), conn->header_length = xasprintf(&(conn->header),
"HTTP/1.1 %d %s\r\n" "HTTP/1.1 %d %s\r\n"
"Date: %s\r\n" "Date: %s\r\n"
"Server: %s\r\n" "%s" /* server */
"Accept-Ranges: bytes\r\n" "Accept-Ranges: bytes\r\n"
"%s" /* keep-alive */ "%s" /* keep-alive */
"Content-Length: %llu\r\n" "Content-Length: %llu\r\n"
"Content-Type: text/html\r\n" "Content-Type: text/html\r\n"
"\r\n", "\r\n",
errcode, errname, date, pkgname, keep_alive(conn), errcode, errname, date, server_hdr, keep_alive(conn),
llu(conn->reply_length)); llu(conn->reply_length));
conn->reply_type = REPLY_GENERATED; conn->reply_type = REPLY_GENERATED;
@ -1345,21 +1365,21 @@ static void redirect(struct connection *conn, const char *format, ...) {
"<h1>Moved Permanently</h1>\n" "<h1>Moved Permanently</h1>\n"
"Moved to: <a href=\"%s\">%s</a>\n" /* where x 2 */ "Moved to: <a href=\"%s\">%s</a>\n" /* where x 2 */
"<hr>\n" "<hr>\n"
"Generated by %s on %s\n" "%s" /* generated on */
"</body></html>\n", "</body></html>\n",
where, where, pkgname, date); where, where, generated_on(date));
conn->header_length = xasprintf(&(conn->header), conn->header_length = xasprintf(&(conn->header),
"HTTP/1.1 301 Moved Permanently\r\n" "HTTP/1.1 301 Moved Permanently\r\n"
"Date: %s\r\n" "Date: %s\r\n"
"Server: %s\r\n" "%s" /* server */
/* "Accept-Ranges: bytes\r\n" - not relevant here */ /* "Accept-Ranges: bytes\r\n" - not relevant here */
"Location: %s\r\n" "Location: %s\r\n"
"%s" /* keep-alive */ "%s" /* keep-alive */
"Content-Length: %llu\r\n" "Content-Length: %llu\r\n"
"Content-Type: text/html\r\n" "Content-Type: text/html\r\n"
"\r\n", "\r\n",
date, pkgname, where, keep_alive(conn), llu(conn->reply_length)); date, server_hdr, where, keep_alive(conn), llu(conn->reply_length));
free(where); free(where);
conn->reply_type = REPLY_GENERATED; conn->reply_type = REPLY_GENERATED;
@ -1693,15 +1713,13 @@ static void generate_dir_listing(struct connection *conn, const char *path) {
free(list); free(list);
free(spaces); free(spaces);
rfc1123_date(date, now);
append(listing, append(listing,
"</pre></tt>\n" "</pre></tt>\n"
"<hr>\n" "<hr>\n");
"Generated by ");
append(listing, pkgname); rfc1123_date(date, now);
append(listing, " on "); append(listing, generated_on(date));
append(listing, date); append(listing, "</body>\n</html>\n");
append(listing, "\n</body>\n</html>\n");
conn->reply = listing->str; conn->reply = listing->str;
conn->reply_length = (off_t)listing->length; conn->reply_length = (off_t)listing->length;
@ -1710,13 +1728,13 @@ static void generate_dir_listing(struct connection *conn, const char *path) {
conn->header_length = xasprintf(&(conn->header), conn->header_length = xasprintf(&(conn->header),
"HTTP/1.1 200 OK\r\n" "HTTP/1.1 200 OK\r\n"
"Date: %s\r\n" "Date: %s\r\n"
"Server: %s\r\n" "%s" /* server */
"Accept-Ranges: bytes\r\n" "Accept-Ranges: bytes\r\n"
"%s" /* keep-alive */ "%s" /* keep-alive */
"Content-Length: %llu\r\n" "Content-Length: %llu\r\n"
"Content-Type: text/html\r\n" "Content-Type: text/html\r\n"
"\r\n", "\r\n",
date, pkgname, keep_alive(conn), llu(conn->reply_length)); date, server_hdr, keep_alive(conn), llu(conn->reply_length));
conn->reply_type = REPLY_GENERATED; conn->reply_type = REPLY_GENERATED;
conn->http_code = 200; conn->http_code = 200;
@ -1833,11 +1851,11 @@ static void process_get(struct connection *conn) {
conn->header_length = xasprintf(&(conn->header), conn->header_length = xasprintf(&(conn->header),
"HTTP/1.1 304 Not Modified\r\n" "HTTP/1.1 304 Not Modified\r\n"
"Date: %s\r\n" "Date: %s\r\n"
"Server: %s\r\n" "%s" /* server */
"Accept-Ranges: bytes\r\n" "Accept-Ranges: bytes\r\n"
"%s" /* keep-alive */ "%s" /* keep-alive */
"\r\n", "\r\n",
rfc1123_date(date, now), pkgname, keep_alive(conn)); rfc1123_date(date, now), server_hdr, keep_alive(conn));
conn->reply_length = 0; conn->reply_length = 0;
conn->reply_type = REPLY_GENERATED; conn->reply_type = REPLY_GENERATED;
conn->header_only = 1; conn->header_only = 1;
@ -1894,7 +1912,7 @@ static void process_get(struct connection *conn) {
conn->header_length = xasprintf(&(conn->header), conn->header_length = xasprintf(&(conn->header),
"HTTP/1.1 206 Partial Content\r\n" "HTTP/1.1 206 Partial Content\r\n"
"Date: %s\r\n" "Date: %s\r\n"
"Server: %s\r\n" "%s" /* server */
"Accept-Ranges: bytes\r\n" "Accept-Ranges: bytes\r\n"
"%s" /* keep-alive */ "%s" /* keep-alive */
"Content-Length: %llu\r\n" "Content-Length: %llu\r\n"
@ -1903,7 +1921,7 @@ static void process_get(struct connection *conn) {
"Last-Modified: %s\r\n" "Last-Modified: %s\r\n"
"\r\n" "\r\n"
, ,
rfc1123_date(date, now), pkgname, keep_alive(conn), rfc1123_date(date, now), server_hdr, keep_alive(conn),
llu(conn->reply_length), llu(from), llu(to), llu(conn->reply_length), llu(from), llu(to),
llu(filestat.st_size), mimetype, lastmod llu(filestat.st_size), mimetype, lastmod
); );
@ -1918,7 +1936,7 @@ static void process_get(struct connection *conn) {
conn->header_length = xasprintf(&(conn->header), conn->header_length = xasprintf(&(conn->header),
"HTTP/1.1 200 OK\r\n" "HTTP/1.1 200 OK\r\n"
"Date: %s\r\n" "Date: %s\r\n"
"Server: %s\r\n" "%s" /* server */
"Accept-Ranges: bytes\r\n" "Accept-Ranges: bytes\r\n"
"%s" /* keep-alive */ "%s" /* keep-alive */
"Content-Length: %llu\r\n" "Content-Length: %llu\r\n"
@ -1926,7 +1944,7 @@ static void process_get(struct connection *conn) {
"Last-Modified: %s\r\n" "Last-Modified: %s\r\n"
"\r\n" "\r\n"
, ,
rfc1123_date(date, now), pkgname, keep_alive(conn), rfc1123_date(date, now), server_hdr, keep_alive(conn),
llu(conn->reply_length), mimetype, lastmod llu(conn->reply_length), mimetype, lastmod
); );
conn->http_code = 200; conn->http_code = 200;
@ -2439,6 +2457,10 @@ int main(int argc, char **argv) {
*/ */
sort_mime_map(); sort_mime_map();
xasprintf(&keep_alive_field, "Keep-Alive: timeout=%d\r\n", idletime); xasprintf(&keep_alive_field, "Keep-Alive: timeout=%d\r\n", idletime);
if (want_server_id)
xasprintf(&server_hdr, "Server: %s\r\n", pkgname);
else
server_hdr = xstrdup("");
init_sockin(); init_sockin();
/* open logfile */ /* open logfile */
@ -2518,6 +2540,7 @@ int main(int argc, char **argv) {
free(forward_map); free(forward_map);
free(keep_alive_field); free(keep_alive_field);
free(wwwroot); free(wwwroot);
free(server_hdr);
} }
/* usage stats */ /* usage stats */

View File

@ -23,7 +23,7 @@ rm -f darkhttpd.gcda darkhttpd.log
./a.out >/dev/null ./a.out >/dev/null
# run tests against a basic instance (generates darkhttpd.gcda) # run tests against a basic instance (generates darkhttpd.gcda)
./a.out $DIR --port $PORT --log darkhttpd.log & ./a.out $DIR --port $PORT --log darkhttpd.log >/dev/null &
PID=$! PID=$!
kill -0 $PID || exit 1 kill -0 $PID || exit 1
python test.py python test.py
@ -32,12 +32,19 @@ kill $PID
# run forward tests # run forward tests
./a.out $DIR --port $PORT \ ./a.out $DIR --port $PORT \
--forward example.com http://www.example.com \ --forward example.com http://www.example.com \
--forward secure.example.com https://www.example.com/secure & --forward secure.example.com https://www.example.com/secure >/dev/null &
PID=$! PID=$!
kill -0 $PID || exit 1 kill -0 $PID || exit 1
python test_forward.py python test_forward.py
kill $PID kill $PID
# run no-server-id tests
./a.out $DIR --port $PORT --no-server-id >/dev/null &
PID=$!
kill -0 $PID || exit 1
python test_server_id.py
kill $PID
echo generating darkhttpd.c.gcov report echo generating darkhttpd.c.gcov report
gcov darkhttpd gcov darkhttpd
rm -rf $DIR rm -rf $DIR

View File

@ -195,6 +195,7 @@ class TestFileGet(TestHelper):
self.assertEquals(hdrs["Accept-Ranges"], "bytes") self.assertEquals(hdrs["Accept-Ranges"], "bytes")
self.assertEquals(hdrs["Content-Length"], str(self.datalen)) self.assertEquals(hdrs["Content-Length"], str(self.datalen))
self.assertEquals(hdrs["Content-Type"], "image/jpeg") self.assertEquals(hdrs["Content-Type"], "image/jpeg")
self.assertContains(hdrs["Server"], "darkhttpd/")
self.assertEquals(body, self.data) self.assertEquals(body, self.data)
def test_file_head(self): def test_file_head(self):

16
devel/test_server_id.py Executable file
View File

@ -0,0 +1,16 @@
#!/usr/bin/env python
import unittest
from test import TestHelper, Conn, parse
class TestForward(TestHelper):
def test_no_server_id(self):
resp = Conn().get("/", method = 'BOGUS')
status, hdrs, body = parse(resp)
self.assertContains(status, "400 Bad Request")
self.assertFalse(hdrs.has_key("Server"))
self.assertFalse("Generated by darkhttpd/" in body)
if __name__ == '__main__':
unittest.main()
# vim:set ts=4 sw=4 et: