httpd: shrink mime type matching code (suggested by Bernhard)
No binary (build failed)
—
(log yok)
| @@ -15,7 +15,7 @@ | |
| * Return TRUE if fileName is a directory. | |
| * Nonexistent files return FALSE. | |
| */ | |
| - | int FAST_FUNC is_directory(const char *fileName, const int followLinks, struct stat *statBuf) |
| + | int FAST_FUNC is_directory(const char *fileName, int followLinks, struct stat *statBuf) |
| { | |
| int status; | |
| struct stat astatBuf; | |
| @@ -20,14 +20,14 @@ | |
| * httpd -p 80 -u 80 -h /www -c /etc/httpd.conf -r "Web Server Authentication" | |
| * | |
| * | |
| - | * When a url starts by "/cgi-bin/" it is assumed to be a cgi script. The |
| + | * When an url starts by "/cgi-bin/" it is assumed to be a cgi script. The |
| * server changes directory to the location of the script and executes it | |
| * after setting QUERY_STRING and other environment variables. | |
| * | |
| * Doc: | |
| * "CGI Environment Variables": http://hoohoo.ncsa.uiuc.edu/cgi/env.html | |
| * | |
| - | * The applet can also be invoked as a url arg decoder and html text encoder |
| + | * The applet can also be invoked as an url arg decoder and html text encoder |
| * as follows: | |
| * foo=`httpd -d $foo` # decode "Hello%20World" as "Hello World" | |
| * bar=`httpd -e "<Hello World>"` # encode as "<Hello World>" | |
| @@ -1325,10 +1325,8 @@ static void send_cgi_and_exit( | |
| /* Check for [dirs/]script.cgi/PATH_INFO */ | |
| script = (char*)url; | |
| while ((script = strchr(script + 1, '/')) != NULL) { | |
| - | struct stat sb; |
| - | |
| *script = '\0'; | |
| - | if (!is_directory(url + 1, 1, &sb)) { |
| + | if (!is_directory(url + 1, 1, NULL)) { |
| /* not directory, found script.cgi/PATH_INFO */ | |
| *script = '/'; | |
| break; | |
| @@ -1504,32 +1502,8 @@ static void send_cgi_and_exit( | |
| */ | |
| static NOINLINE void send_file_and_exit(const char *url, int what) | |
| { | |
| - | static const char *const suffixTable[] = { |
| - | /* Warning: shorter equivalent suffix in one line must be first */ |
| - | ".htm.html", "text/html", |
| - | ".jpg.jpeg", "image/jpeg", |
| - | ".gif", "image/gif", |
| - | ".png", "image/png", |
| - | ".txt.h.c.cc.cpp", "text/plain", |
| - | ".css", "text/css", |
| - | ".wav", "audio/wav", |
| - | ".avi", "video/x-msvideo", |
| - | ".qt.mov", "video/quicktime", |
| - | ".mpe.mpeg", "video/mpeg", |
| - | ".mid.midi", "audio/midi", |
| - | ".mp3", "audio/mpeg", |
| - | #if 0 /* unpopular */ |
| - | ".au", "audio/basic", |
| - | ".pac", "application/x-ns-proxy-autoconfig", |
| - | ".vrml.wrl", "model/vrml", |
| - | #endif |
| - | NULL |
| - | }; |
| - | |
| char *suffix; | |
| int fd; | |
| - | const char *const *table; |
| - | const char *try_suffix; |
| ssize_t count; | |
| fd = open(url, O_RDONLY); | |
| @@ -1547,22 +1521,61 @@ static NOINLINE void send_file_and_exit(const char *url, int what) | |
| * (happens if you abort downloads from local httpd): */ | |
| signal(SIGPIPE, SIG_IGN); | |
| - | suffix = strrchr(url, '.'); |
| - | |
| - | /* If not found, set default as "application/octet-stream"; */ |
| + | /* If not found, default is "application/octet-stream" */ |
| found_mime_type = "application/octet-stream"; | |
| + | suffix = strrchr(url, '.'); |
| if (suffix) { | |
| + | static const char suffixTable[] ALIGN1 = |
| + | /* Shorter suffix must be first: |
| + | * ".html.htm" will fail for ".htm" |
| + | */ |
| + | ".txt.h.c.cc.cpp\0" "text/plain\0" |
| + | /* .htm line must be after .h line */ |
| + | ".htm.html\0" "text/html\0" |
| + | ".jpg.jpeg\0" "image/jpeg\0" |
| + | ".gif\0" "image/gif\0" |
| + | ".png\0" "image/png\0" |
| + | /* .css line must be after .c line */ |
| + | ".css\0" "text/css\0" |
| + | ".wav\0" "audio/wav\0" |
| + | ".avi\0" "video/x-msvideo\0" |
| + | ".qt.mov\0" "video/quicktime\0" |
| + | ".mpe.mpeg\0" "video/mpeg\0" |
| + | ".mid.midi\0" "audio/midi\0" |
| + | ".mp3\0" "audio/mpeg\0" |
| + | #if 0 /* unpopular */ |
| + | ".au\0" "audio/basic\0" |
| + | ".pac\0" "application/x-ns-proxy-autoconfig\0" |
| + | ".vrml.wrl\0" "model/vrml\0" |
| + | #endif |
| + | /* compiler adds another "\0" here */ |
| + | ; |
| Htaccess *cur; | |
| - | for (table = suffixTable; *table; table += 2) { |
| - | try_suffix = strstr(table[0], suffix); |
| - | if (try_suffix) { |
| - | try_suffix += strlen(suffix); |
| - | if (*try_suffix == '\0' || *try_suffix == '.') { |
| - | found_mime_type = table[1]; |
| - | break; |
| - | } |
| + | |
| + | /* Examine built-in table */ |
| + | const char *table = suffixTable; |
| + | const char *table_next; |
| + | for (; *table; table = table_next) { |
| + | const char *try_suffix; |
| + | const char *mime_type; |
| + | mime_type = table + strlen(table) + 1; |
| + | table_next = mime_type + strlen(mime_type) + 1; |
| + | try_suffix = strstr(table, suffix); |
| + | if (!try_suffix) |
| + | continue; |
| + | try_suffix += strlen(suffix); |
| + | if (*try_suffix == '\0' || *try_suffix == '.') { |
| + | found_mime_type = mime_type; |
| + | break; |
| } | |
| + | /* Example: strstr(table, ".av") != NULL, but it |
| + | * does not match ".avi" after all and we end up here. |
| + | * The table is arranged so that in this case we know |
| + | * that it can't match anything in the following lines, |
| + | * and we stop the search: */ |
| + | break; |
| } | |
| + | /* ...then user's table */ |
| for (cur = mime_a; cur; cur = cur->next) { | |
| if (strcmp(cur->before_colon, suffix) == 0) { | |
| found_mime_type = cur->after_colon; | |
| @@ -1919,7 +1932,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |
| /* If URL is a directory, add '/' */ | |
| if (urlp[-1] != '/') { | |
| - | if (is_directory(urlcopy + 1, 1, &sb)) { |
| + | if (is_directory(urlcopy + 1, 1, NULL)) { |
| found_moved_temporarily = urlcopy; | |
| } | |
| } | |
| @@ -1933,7 +1946,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |
| while (ip_allowed && (tptr = strchr(tptr + 1, '/')) != NULL) { | |
| /* have path1/path2 */ | |
| *tptr = '\0'; | |
| - | if (is_directory(urlcopy + 1, 1, &sb)) { |
| + | if (is_directory(urlcopy + 1, 1, NULL)) { |
| /* may have subdir config */ | |
| parse_conf(urlcopy + 1, SUBDIR_PARSE); | |
| ip_allowed = checkPermIP(); | |