2 n__http__mime_8c
gullradriel edited this page 2026-10-29 20:54:40 +01:00

src/n_http_mime.c

Media type of a file from its extension (see n_http_mime.h). More...

Attributes

Name
const struct @242055217114105150047231111160250133146166323032[] _mime_table

Detailed Description

Media type of a file from its extension (see n_http_mime.h).

Author: Castagnier Mickael

Version: 1.0

Date: 2026

Attributes Documentation

variable _mime_table

static const struct @242055217114105150047231111160250133146166323032[] _mime_table = {
    {"7z", "application/x-7z-compressed"},
    {"apk", "application/vnd.android.package-archive"},
    {"avif", "image/avif"},
    {"bmp", "image/bmp"},
    {"css", "text/css"},
    {"csv", "text/csv"},
    {"data", "application/octet-stream"},
    {"deb", "application/vnd.debian.binary-package"},
    {"exe", "application/vnd.microsoft.portable-executable"},
    {"gif", "image/gif"},
    {"gz", "application/gzip"},
    {"htm", "text/html"},
    {"html", "text/html"},
    {"ico", "image/vnd.microsoft.icon"},
    {"jpeg", "image/jpeg"},
    {"jpg", "image/jpeg"},
    {"js", "text/javascript"},
    {"json", "application/json"},
    {"map", "application/json"},
    {"md", "text/markdown"},
    {"md5", "text/plain"},
    {"mjs", "text/javascript"},
    {"mp3", "audio/mpeg"},
    {"mp4", "video/mp4"},
    {"oga", "audio/ogg"},
    {"ogg", "audio/ogg"},
    {"ogv", "video/ogg"},
    {"otf", "font/otf"},
    {"pdf", "application/pdf"},
    {"png", "image/png"},
    {"rss", "application/rss+xml"},
    {"svg", "image/svg+xml"},
    {"tar", "application/x-tar"},
    {"ttf", "font/ttf"},
    {"txt", "text/plain"},
    {"wasm", "application/wasm"},
    {"wav", "audio/wav"},
    {"webm", "video/webm"},
    {"webmanifest", "application/manifest+json"},
    {"webp", "image/webp"},
    {"woff", "font/woff"},
    {"woff2", "font/woff2"},
    {"xml", "application/xml"},
    {"zip", "application/zip"},
};

Source code

/*
 * Nilorea Library
 * Copyright (C) 2005-2026 Castagnier Mickael
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 */


#include "nilorea/n_http_mime.h"

#include <string.h>

/* Sorted by extension (lowercase, bytewise) for the binary search below;
 * ex_http_mime checks the order. */
static const struct {
    const char* ext;
    const char* type;
} _mime_table[] = {
    {"7z", "application/x-7z-compressed"},
    {"apk", "application/vnd.android.package-archive"},
    {"avif", "image/avif"},
    {"bmp", "image/bmp"},
    {"css", "text/css"},
    {"csv", "text/csv"},
    {"data", "application/octet-stream"},
    {"deb", "application/vnd.debian.binary-package"},
    {"exe", "application/vnd.microsoft.portable-executable"},
    {"gif", "image/gif"},
    {"gz", "application/gzip"},
    {"htm", "text/html"},
    {"html", "text/html"},
    {"ico", "image/vnd.microsoft.icon"},
    {"jpeg", "image/jpeg"},
    {"jpg", "image/jpeg"},
    {"js", "text/javascript"},
    {"json", "application/json"},
    {"map", "application/json"},
    {"md", "text/markdown"},
    {"md5", "text/plain"},
    {"mjs", "text/javascript"},
    {"mp3", "audio/mpeg"},
    {"mp4", "video/mp4"},
    {"oga", "audio/ogg"},
    {"ogg", "audio/ogg"},
    {"ogv", "video/ogg"},
    {"otf", "font/otf"},
    {"pdf", "application/pdf"},
    {"png", "image/png"},
    {"rss", "application/rss+xml"},
    {"svg", "image/svg+xml"},
    {"tar", "application/x-tar"},
    {"ttf", "font/ttf"},
    {"txt", "text/plain"},
    {"wasm", "application/wasm"},
    {"wav", "audio/wav"},
    {"webm", "video/webm"},
    {"webmanifest", "application/manifest+json"},
    {"webp", "image/webp"},
    {"woff", "font/woff"},
    {"woff2", "font/woff2"},
    {"xml", "application/xml"},
    {"zip", "application/zip"},
};

const char* n_http_mime_type(const char* path, size_t len) {
    char ext[16];
    size_t i, end, seg = 0, dot = (size_t)-1, elen, lo, hi;
    if (!path)
        return NULL;
    for (end = 0; end < len && path[end] != '?' && path[end] != '#'; end++);
    for (i = 0; i < end; i++) {
        if (path[i] == '/')
            seg = i + 1;
        else if (path[i] == '.')
            dot = i;
    }
    /* no dot in the last segment, a leading dot (".htaccess") or a trailing one */
    if (dot == (size_t)-1 || dot < seg || dot == seg || dot + 1 >= end)
        return NULL;
    elen = end - dot - 1;
    if (elen >= sizeof(ext))
        return NULL;
    for (i = 0; i < elen; i++) {
        unsigned char c = (unsigned char)path[dot + 1 + i];
        ext[i] = (char)(c >= 'A' && c <= 'Z' ? c - 'A' + 'a' : c);
    }
    ext[elen] = '\0';
    lo = 0;
    hi = sizeof(_mime_table) / sizeof(_mime_table[0]);
    while (lo < hi) {
        size_t mid = lo + (hi - lo) / 2;
        int cmp = strcmp(ext, _mime_table[mid].ext);
        if (cmp == 0)
            return _mime_table[mid].type;
        if (cmp < 0)
            hi = mid;
        else
            lo = mid + 1;
    }
    return NULL;
}

int n_http_mime_table_check(void) {
    size_t i;
    for (i = 1; i < sizeof(_mime_table) / sizeof(_mime_table[0]); i++)
        if (strcmp(_mime_table[i - 1].ext, _mime_table[i].ext) >= 0)
            return 0;
    return 1;
}