version 0.1.6
[fms.git] / libs / shttpd / mime_type.c
1 /*
2  * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
3  * All rights reserved
4  *
5  * "THE BEER-WARE LICENSE" (Revision 42):
6  * Sergey Lyubka wrote this file.  As long as you retain this notice you
7  * can do whatever you want with this stuff. If we meet some day, and you think
8  * this stuff is worth it, you can buy me a beer in return.
9  */
10
11 #include "defs.h"
12
13 static const struct mime_type default_mime_types[] = {
14         {"html",        4,      "text/html"                     },
15         {"htm",         3,      "text/html"                     },
16         {"txt",         3,      "text/plain"                    },
17         {"css",         3,      "text/css"                      },
18         {"ico",         3,      "image/x-icon"                  },
19         {"gif",         3,      "image/gif"                     },
20         {"jpg",         3,      "image/jpeg"                    },
21         {"jpeg",        4,      "image/jpeg"                    },
22         {"png",         3,      "image/png"                     },
23         {"svg",         3,      "image/svg+xml"                 },
24         {"torrent",     7,      "application/x-bittorrent"      },
25         {"wav",         3,      "audio/x-wav"                   },
26         {"mp3",         3,      "audio/x-mp3"                   },
27         {"mid",         3,      "audio/mid"                     },
28         {"m3u",         3,      "audio/x-mpegurl"               },
29         {"ram",         3,      "audio/x-pn-realaudio"          },
30         {"ra",          2,      "audio/x-pn-realaudio"          },
31         {"doc",         3,      "application/msword",           },
32         {"exe",         3,      "application/octet-stream"      },
33         {"zip",         3,      "application/x-zip-compressed"  },
34         {"xls",         3,      "application/excel"             },
35         {"tgz",         3,      "application/x-tar-gz"          },
36         {"tar.gz",      6,      "application/x-tar-gz"          },
37         {"tar",         3,      "application/x-tar"             },
38         {"gz",          2,      "application/x-gunzip"          },
39         {"arj",         3,      "application/x-arj-compressed"  },
40         {"rar",         3,      "application/x-arj-compressed"  },
41         {"rtf",         3,      "application/rtf"               },
42         {"pdf",         3,      "application/pdf"               },
43         {"mpg",         3,      "video/mpeg"                    },
44         {"mpeg",        4,      "video/mpeg"                    },
45         {"asf",         3,      "video/x-ms-asf"                },
46         {"avi",         3,      "video/x-msvideo"               },
47         {"bmp",         3,      "image/bmp"                     },
48         {NULL,          0,      NULL                            }
49 };
50
51 const char *
52 get_mime_type(struct shttpd_ctx *ctx, const char *uri, int len)
53 {
54         struct llhead           *lp;
55         const struct mime_type  *mt;
56         struct mime_type_link   *mtl;
57         const char              *s;
58
59         /* Firt, loop through the custom mime types if any */
60         LL_FOREACH(&ctx->mime_types, lp) {
61                 mtl = LL_ENTRY(lp, struct mime_type_link, link);
62                 s = uri + len - mtl->ext_len;
63                 if (s > uri && s[-1] == '.' &&
64                     !my_strncasecmp(mtl->ext, s, mtl->ext_len))
65                         return (mtl->mime);
66         }
67
68         /* If no luck, try built-in mime types */
69         for (mt = default_mime_types; mt->ext != NULL; mt++) {
70                 s = uri + len - mt->ext_len;
71                 if (s > uri && s[-1] == '.' &&
72                     !my_strncasecmp(mt->ext, s, mt->ext_len))
73                         return (mt->mime);
74         }
75
76         /* Oops. This extension is unknown to us. Fallback to text/plain */
77         return ("text/plain");
78 }
79
80 void
81 set_mime_types(struct shttpd_ctx *ctx, const char *path)
82 {
83         FILE    *fp;
84         char    line[512], ext[sizeof(line)], mime[sizeof(line)], *s;
85
86         if ((fp = fopen(path, "r")) == NULL)
87                 elog(E_FATAL, NULL, "set_mime_types: fopen(%s): %s",
88                     path, strerror(errno));
89
90         while (fgets(line, sizeof(line), fp) != NULL) {
91                 /* Skip empty lines */
92                 if (line[0] == '#' || line[0] == '\n')
93                         continue;
94                 if (sscanf(line, "%s", mime)) {
95                         s = line + strlen(mime);
96                         while (*s && *s != '\n' && sscanf(s, "%s", ext)) {
97                                 shttpd_add_mime_type(ctx, ext, mime);
98                                 s += strlen(mime);
99                         }
100                 }
101         }
102
103         (void) fclose(fp);
104 }