aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-09-10 01:46:02 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-09-10 01:46:02 +0200
commit33d8d08f7818a6d10e14ad8397c61adfcd377a6f (patch)
tree8653ac3a95e6cd5a23138392e9b9a091df799e3e
parentd069e5398d7538bdcf0e97c357c28aade3d01a28 (diff)
downloadbusybox-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.c2
-rw-r--r--networking/httpd.c97
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 */
18int FAST_FUNC is_directory(const char *fileName, const int followLinks, struct stat *statBuf) 18int 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 "&#60Hello&#32World&#62" 33 * bar=`httpd -e "<Hello World>"` # encode as "&#60Hello&#32World&#62"
@@ -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 */
1505static NOINLINE void send_file_and_exit(const char *url, int what) 1503static 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();