/* * Copyright (c) 2021 Omar Polo * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "gmid.h" #include #include #include void init_mime(struct mime *mime) { mime->len = 0; mime->cap = 16; mime->t = calloc(mime->cap, sizeof(struct etm)); if (mime->t == NULL) fatal("calloc: %s", strerror(errno)); } /* register mime for the given extension */ void add_mime(struct mime *mime, const char *mt, const char *ext) { size_t oldcap; if (mime->len == mime->cap) { oldcap = mime->cap; mime->cap *= 1.5; mime->t = recallocarray(mime->t, oldcap, mime->cap, sizeof(struct etm)); if (mime->t == NULL) err(1, "recallocarray"); } mime->t[mime->len].mime = mt; mime->t[mime->len].ext = ext; mime->len++; } /* load a default set of common mime-extension associations */ void load_default_mime(struct mime *mime) { struct etm *i, m[] = { {"application/pdf", "pdf"}, {"image/gif", "gif"}, {"image/jpeg", "jpg"}, {"image/jpeg", "jpeg"}, {"image/png", "png"}, {"image/svg+xml", "svg"}, {"text/gemini", "gemini"}, {"text/gemini", "gmi"}, {"text/markdown", "markdown"}, {"text/markdown", "md"}, {"text/plain", "txt"}, {"text/xml", "xml"}, {NULL, NULL} }; for (i = m; i->mime != NULL; ++i) add_mime(mime, i->mime, i->ext); } static const char * path_ext(const char *path) { const char *end; end = path + strlen(path)-1; for (; end != path; --end) { if (*end == '.') return end+1; if (*end == '/') break; } return NULL; } const char * mime(struct vhost *host, const char *path) { const char *def, *ext; struct etm *t; def = vhost_default_mime(host, path); if ((ext = path_ext(path)) == NULL) return def; for (t = conf.mime.t; t->mime != NULL; ++t) if (!strcmp(ext, t->ext)) return t->mime; return def; }