diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-09-10 01:46:02 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-09-10 01:46:02 +0200 |
commit | 33d8d08f7818a6d10e14ad8397c61adfcd377a6f (patch) | |
tree | 8653ac3a95e6cd5a23138392e9b9a091df799e3e | |
parent | d069e5398d7538bdcf0e97c357c28aade3d01a28 (diff) | |
download | busybox-w32-33d8d08f7818a6d10e14ad8397c61adfcd377a6f.tar.gz busybox-w32-33d8d08f7818a6d10e14ad8397c61adfcd377a6f.tar.bz2 busybox-w32-33d8d08f7818a6d10e14ad8397c61adfcd377a6f.zip |
httpd: shrink mime type matching code (suggested by Bernhard)
function old new delta
static.suffixTable 100 231 +131
send_file_and_exit 625 658 +33
handle_incoming_and_exit 2749 2745 -4
send_cgi_and_exit 936 901 -35
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/2 up/down: 164/-39) Total: 125 bytes
text data bss dec hex filename
824631 458 6956 832045 cb22d busybox_old
824550 458 6956 831964 cb1dc busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | libbb/isdirectory.c | 2 | ||||
-rw-r--r-- | networking/httpd.c | 97 |
2 files changed, 56 insertions, 43 deletions
diff --git a/libbb/isdirectory.c b/libbb/isdirectory.c index 28ed3ec29..4a2961e0d 100644 --- a/libbb/isdirectory.c +++ b/libbb/isdirectory.c | |||
@@ -15,7 +15,7 @@ | |||
15 | * Return TRUE if fileName is a directory. | 15 | * Return TRUE if fileName is a directory. |
16 | * Nonexistent files return FALSE. | 16 | * Nonexistent files return FALSE. |
17 | */ | 17 | */ |
18 | int FAST_FUNC is_directory(const char *fileName, const int followLinks, struct stat *statBuf) | 18 | int FAST_FUNC is_directory(const char *fileName, int followLinks, struct stat *statBuf) |
19 | { | 19 | { |
20 | int status; | 20 | int status; |
21 | struct stat astatBuf; | 21 | struct stat astatBuf; |
diff --git a/networking/httpd.c b/networking/httpd.c index 07dcd71ff..a2a52b58a 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -20,14 +20,14 @@ | |||
20 | * httpd -p 80 -u 80 -h /www -c /etc/httpd.conf -r "Web Server Authentication" | 20 | * httpd -p 80 -u 80 -h /www -c /etc/httpd.conf -r "Web Server Authentication" |
21 | * | 21 | * |
22 | * | 22 | * |
23 | * When a url starts by "/cgi-bin/" it is assumed to be a cgi script. The | 23 | * When an url starts by "/cgi-bin/" it is assumed to be a cgi script. The |
24 | * server changes directory to the location of the script and executes it | 24 | * server changes directory to the location of the script and executes it |
25 | * after setting QUERY_STRING and other environment variables. | 25 | * after setting QUERY_STRING and other environment variables. |
26 | * | 26 | * |
27 | * Doc: | 27 | * Doc: |
28 | * "CGI Environment Variables": http://hoohoo.ncsa.uiuc.edu/cgi/env.html | 28 | * "CGI Environment Variables": http://hoohoo.ncsa.uiuc.edu/cgi/env.html |
29 | * | 29 | * |
30 | * The applet can also be invoked as a url arg decoder and html text encoder | 30 | * The applet can also be invoked as an url arg decoder and html text encoder |
31 | * as follows: | 31 | * as follows: |
32 | * foo=`httpd -d $foo` # decode "Hello%20World" as "Hello World" | 32 | * foo=`httpd -d $foo` # decode "Hello%20World" as "Hello World" |
33 | * bar=`httpd -e "<Hello World>"` # encode as "<Hello World>" | 33 | * bar=`httpd -e "<Hello World>"` # encode as "<Hello World>" |
@@ -1325,10 +1325,8 @@ static void send_cgi_and_exit( | |||
1325 | /* Check for [dirs/]script.cgi/PATH_INFO */ | 1325 | /* Check for [dirs/]script.cgi/PATH_INFO */ |
1326 | script = (char*)url; | 1326 | script = (char*)url; |
1327 | while ((script = strchr(script + 1, '/')) != NULL) { | 1327 | while ((script = strchr(script + 1, '/')) != NULL) { |
1328 | struct stat sb; | ||
1329 | |||
1330 | *script = '\0'; | 1328 | *script = '\0'; |
1331 | if (!is_directory(url + 1, 1, &sb)) { | 1329 | if (!is_directory(url + 1, 1, NULL)) { |
1332 | /* not directory, found script.cgi/PATH_INFO */ | 1330 | /* not directory, found script.cgi/PATH_INFO */ |
1333 | *script = '/'; | 1331 | *script = '/'; |
1334 | break; | 1332 | break; |
@@ -1504,32 +1502,8 @@ static void send_cgi_and_exit( | |||
1504 | */ | 1502 | */ |
1505 | static NOINLINE void send_file_and_exit(const char *url, int what) | 1503 | static NOINLINE void send_file_and_exit(const char *url, int what) |
1506 | { | 1504 | { |
1507 | static const char *const suffixTable[] = { | ||
1508 | /* Warning: shorter equivalent suffix in one line must be first */ | ||
1509 | ".htm.html", "text/html", | ||
1510 | ".jpg.jpeg", "image/jpeg", | ||
1511 | ".gif", "image/gif", | ||
1512 | ".png", "image/png", | ||
1513 | ".txt.h.c.cc.cpp", "text/plain", | ||
1514 | ".css", "text/css", | ||
1515 | ".wav", "audio/wav", | ||
1516 | ".avi", "video/x-msvideo", | ||
1517 | ".qt.mov", "video/quicktime", | ||
1518 | ".mpe.mpeg", "video/mpeg", | ||
1519 | ".mid.midi", "audio/midi", | ||
1520 | ".mp3", "audio/mpeg", | ||
1521 | #if 0 /* unpopular */ | ||
1522 | ".au", "audio/basic", | ||
1523 | ".pac", "application/x-ns-proxy-autoconfig", | ||
1524 | ".vrml.wrl", "model/vrml", | ||
1525 | #endif | ||
1526 | NULL | ||
1527 | }; | ||
1528 | |||
1529 | char *suffix; | 1505 | char *suffix; |
1530 | int fd; | 1506 | int fd; |
1531 | const char *const *table; | ||
1532 | const char *try_suffix; | ||
1533 | ssize_t count; | 1507 | ssize_t count; |
1534 | 1508 | ||
1535 | fd = open(url, O_RDONLY); | 1509 | fd = open(url, O_RDONLY); |
@@ -1547,22 +1521,61 @@ static NOINLINE void send_file_and_exit(const char *url, int what) | |||
1547 | * (happens if you abort downloads from local httpd): */ | 1521 | * (happens if you abort downloads from local httpd): */ |
1548 | signal(SIGPIPE, SIG_IGN); | 1522 | signal(SIGPIPE, SIG_IGN); |
1549 | 1523 | ||
1550 | suffix = strrchr(url, '.'); | 1524 | /* If not found, default is "application/octet-stream" */ |
1551 | |||
1552 | /* If not found, set default as "application/octet-stream"; */ | ||
1553 | found_mime_type = "application/octet-stream"; | 1525 | found_mime_type = "application/octet-stream"; |
1526 | suffix = strrchr(url, '.'); | ||
1554 | if (suffix) { | 1527 | if (suffix) { |
1528 | static const char suffixTable[] ALIGN1 = | ||
1529 | /* Shorter suffix must be first: | ||
1530 | * ".html.htm" will fail for ".htm" | ||
1531 | */ | ||
1532 | ".txt.h.c.cc.cpp\0" "text/plain\0" | ||
1533 | /* .htm line must be after .h line */ | ||
1534 | ".htm.html\0" "text/html\0" | ||
1535 | ".jpg.jpeg\0" "image/jpeg\0" | ||
1536 | ".gif\0" "image/gif\0" | ||
1537 | ".png\0" "image/png\0" | ||
1538 | /* .css line must be after .c line */ | ||
1539 | ".css\0" "text/css\0" | ||
1540 | ".wav\0" "audio/wav\0" | ||
1541 | ".avi\0" "video/x-msvideo\0" | ||
1542 | ".qt.mov\0" "video/quicktime\0" | ||
1543 | ".mpe.mpeg\0" "video/mpeg\0" | ||
1544 | ".mid.midi\0" "audio/midi\0" | ||
1545 | ".mp3\0" "audio/mpeg\0" | ||
1546 | #if 0 /* unpopular */ | ||
1547 | ".au\0" "audio/basic\0" | ||
1548 | ".pac\0" "application/x-ns-proxy-autoconfig\0" | ||
1549 | ".vrml.wrl\0" "model/vrml\0" | ||
1550 | #endif | ||
1551 | /* compiler adds another "\0" here */ | ||
1552 | ; | ||
1555 | Htaccess *cur; | 1553 | Htaccess *cur; |
1556 | for (table = suffixTable; *table; table += 2) { | 1554 | |
1557 | try_suffix = strstr(table[0], suffix); | 1555 | /* Examine built-in table */ |
1558 | if (try_suffix) { | 1556 | const char *table = suffixTable; |
1559 | try_suffix += strlen(suffix); | 1557 | const char *table_next; |
1560 | if (*try_suffix == '\0' || *try_suffix == '.') { | 1558 | for (; *table; table = table_next) { |
1561 | found_mime_type = table[1]; | 1559 | const char *try_suffix; |
1562 | break; | 1560 | const char *mime_type; |
1563 | } | 1561 | mime_type = table + strlen(table) + 1; |
1562 | table_next = mime_type + strlen(mime_type) + 1; | ||
1563 | try_suffix = strstr(table, suffix); | ||
1564 | if (!try_suffix) | ||
1565 | continue; | ||
1566 | try_suffix += strlen(suffix); | ||
1567 | if (*try_suffix == '\0' || *try_suffix == '.') { | ||
1568 | found_mime_type = mime_type; | ||
1569 | break; | ||
1564 | } | 1570 | } |
1571 | /* Example: strstr(table, ".av") != NULL, but it | ||
1572 | * does not match ".avi" after all and we end up here. | ||
1573 | * The table is arranged so that in this case we know | ||
1574 | * that it can't match anything in the following lines, | ||
1575 | * and we stop the search: */ | ||
1576 | break; | ||
1565 | } | 1577 | } |
1578 | /* ...then user's table */ | ||
1566 | for (cur = mime_a; cur; cur = cur->next) { | 1579 | for (cur = mime_a; cur; cur = cur->next) { |
1567 | if (strcmp(cur->before_colon, suffix) == 0) { | 1580 | if (strcmp(cur->before_colon, suffix) == 0) { |
1568 | found_mime_type = cur->after_colon; | 1581 | found_mime_type = cur->after_colon; |
@@ -1919,7 +1932,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
1919 | 1932 | ||
1920 | /* If URL is a directory, add '/' */ | 1933 | /* If URL is a directory, add '/' */ |
1921 | if (urlp[-1] != '/') { | 1934 | if (urlp[-1] != '/') { |
1922 | if (is_directory(urlcopy + 1, 1, &sb)) { | 1935 | if (is_directory(urlcopy + 1, 1, NULL)) { |
1923 | found_moved_temporarily = urlcopy; | 1936 | found_moved_temporarily = urlcopy; |
1924 | } | 1937 | } |
1925 | } | 1938 | } |
@@ -1933,7 +1946,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
1933 | while (ip_allowed && (tptr = strchr(tptr + 1, '/')) != NULL) { | 1946 | while (ip_allowed && (tptr = strchr(tptr + 1, '/')) != NULL) { |
1934 | /* have path1/path2 */ | 1947 | /* have path1/path2 */ |
1935 | *tptr = '\0'; | 1948 | *tptr = '\0'; |
1936 | if (is_directory(urlcopy + 1, 1, &sb)) { | 1949 | if (is_directory(urlcopy + 1, 1, NULL)) { |
1937 | /* may have subdir config */ | 1950 | /* may have subdir config */ |
1938 | parse_conf(urlcopy + 1, SUBDIR_PARSE); | 1951 | parse_conf(urlcopy + 1, SUBDIR_PARSE); |
1939 | ip_allowed = checkPermIP(); | 1952 | ip_allowed = checkPermIP(); |