+static const struct {
+ const char *extension;
+ int ext_len;
+ const char *mime_type;
+} builtin_mime_types[] = {
+ {"html", 4, "text/html" },
+ {"htm", 3, "text/html" },
+ {"txt", 3, "text/plain" },
+ {"css", 3, "text/css" },
+ {"ico", 3, "image/x-icon" },
+ {"gif", 3, "image/gif" },
+ {"jpg", 3, "image/jpeg" },
+ {"jpeg", 4, "image/jpeg" },
+ {"png", 3, "image/png" },
+ {"svg", 3, "image/svg+xml" },
+ {"torrent", 7, "application/x-bittorrent" },
+ {"wav", 3, "audio/x-wav" },
+ {"mp3", 3, "audio/x-mp3" },
+ {"mid", 3, "audio/mid" },
+ {"m3u", 3, "audio/x-mpegurl" },
+ {"ram", 3, "audio/x-pn-realaudio" },
+ {"ra", 2, "audio/x-pn-realaudio" },
+ {"doc", 3, "application/msword", },
+ {"exe", 3, "application/octet-stream" },
+ {"zip", 3, "application/x-zip-compressed" },
+ {"xls", 3, "application/excel" },
+ {"tgz", 3, "application/x-tar-gz" },
+ {"tar.gz", 6, "application/x-tar-gz" },
+ {"tar", 3, "application/x-tar" },
+ {"gz", 2, "application/x-gunzip" },
+ {"arj", 3, "application/x-arj-compressed" },
+ {"rar", 3, "application/x-arj-compressed" },
+ {"rtf", 3, "application/rtf" },
+ {"pdf", 3, "application/pdf" },
+ {"swf", 3, "application/x-shockwave-flash" },
+ {"mpg", 3, "video/mpeg" },
+ {"mpeg", 4, "video/mpeg" },
+ {"asf", 3, "video/x-ms-asf" },
+ {"avi", 3, "video/x-msvideo" },
+ {"bmp", 3, "image/bmp" },
+ {NULL, 0, NULL }
+};
+
+void
+get_mime_type(struct shttpd_ctx *ctx, const char *uri, int len, struct vec *vec)
+{
+ const char *eq, *p = ctx->options[OPT_MIME_TYPES];
+ int i, n, ext_len;
+
+ /* Firt, loop through the custom mime types if any */
+ FOR_EACH_WORD_IN_LIST(p, n) {
+ if ((eq = memchr(p, '=', n)) == NULL || eq >= p + n || eq == p)
+ continue;
+ ext_len = eq - p;
+ if (len > ext_len && uri[len - ext_len - 1] == '.' &&
+ !my_strncasecmp(p, &uri[len - ext_len], ext_len)) {
+ vec->ptr = eq + 1;
+ vec->len = p + n - vec->ptr;
+ return;
+ }
+ }
+
+ /* If no luck, try built-in mime types */
+ for (i = 0; builtin_mime_types[i].extension != NULL; i++) {
+ ext_len = builtin_mime_types[i].ext_len;
+ if (len > ext_len && uri[len - ext_len - 1] == '.' &&
+ !my_strncasecmp(builtin_mime_types[i].extension,
+ &uri[len - ext_len], ext_len)) {
+ vec->ptr = builtin_mime_types[i].mime_type;
+ vec->len = strlen(vec->ptr);
+ return;
+ }
+ }
+
+ /* Oops. This extension is unknown to us. Fallback to text/plain */
+ vec->ptr = "text/plain";
+ vec->len = strlen(vec->ptr);
+}
+