Line data Source code
1 : //
2 : // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/cppalliance/http
8 : //
9 :
10 : #include <boost/http/server/mime_db.hpp>
11 : #include <algorithm>
12 : #include <cctype>
13 :
14 : namespace boost {
15 : namespace http {
16 : namespace mime_db {
17 :
18 : namespace {
19 :
20 : // Static database of common MIME types
21 : // Sorted by type for binary search
22 : constexpr mime_type_entry db[] = {
23 : { "application/gzip", "", false },
24 : { "application/javascript", "UTF-8", true },
25 : { "application/json", "UTF-8", true },
26 : { "application/octet-stream", "", false },
27 : { "application/pdf", "", false },
28 : { "application/rtf", "UTF-8", true },
29 : { "application/wasm", "", false },
30 : { "application/x-7z-compressed", "", false },
31 : { "application/x-bzip", "", false },
32 : { "application/x-bzip2", "", false },
33 : { "application/x-tar", "", false },
34 : { "application/xhtml+xml", "UTF-8", true },
35 : { "application/xml", "UTF-8", true },
36 : { "application/zip", "", false },
37 : { "audio/aac", "", false },
38 : { "audio/flac", "", false },
39 : { "audio/mp4", "", false },
40 : { "audio/mpeg", "", false },
41 : { "audio/ogg", "", false },
42 : { "audio/wav", "", false },
43 : { "audio/webm", "", false },
44 : { "font/otf", "", false },
45 : { "font/ttf", "", false },
46 : { "font/woff", "", false },
47 : { "font/woff2", "", false },
48 : { "image/avif", "", false },
49 : { "image/bmp", "", false },
50 : { "image/gif", "", false },
51 : { "image/jpeg", "", false },
52 : { "image/png", "", false },
53 : { "image/svg+xml", "UTF-8", true },
54 : { "image/tiff", "", false },
55 : { "image/webp", "", false },
56 : { "image/x-icon", "", false },
57 : { "text/cache-manifest", "UTF-8", true },
58 : { "text/calendar", "UTF-8", true },
59 : { "text/css", "UTF-8", true },
60 : { "text/csv", "UTF-8", true },
61 : { "text/html", "UTF-8", true },
62 : { "text/javascript", "UTF-8", true },
63 : { "text/markdown", "UTF-8", true },
64 : { "text/plain", "UTF-8", true },
65 : { "text/xml", "UTF-8", true },
66 : { "video/mp4", "", false },
67 : { "video/mpeg", "", false },
68 : { "video/ogg", "", false },
69 : { "video/webm", "", false },
70 : };
71 :
72 : constexpr std::size_t db_size = sizeof( db ) / sizeof( db[0] );
73 :
74 : // Case-insensitive comparison
75 : int
76 0 : compare_icase( core::string_view a, core::string_view b ) noexcept
77 : {
78 0 : auto const n = ( std::min )( a.size(), b.size() );
79 0 : for( std::size_t i = 0; i < n; ++i )
80 : {
81 : auto const ca = static_cast<unsigned char>(
82 0 : std::tolower( static_cast<unsigned char>( a[i] ) ) );
83 : auto const cb = static_cast<unsigned char>(
84 0 : std::tolower( static_cast<unsigned char>( b[i] ) ) );
85 0 : if( ca < cb )
86 0 : return -1;
87 0 : if( ca > cb )
88 0 : return 1;
89 : }
90 0 : if( a.size() < b.size() )
91 0 : return -1;
92 0 : if( a.size() > b.size() )
93 0 : return 1;
94 0 : return 0;
95 : }
96 :
97 : } // (anon)
98 :
99 : mime_type_entry const*
100 0 : lookup( core::string_view type ) noexcept
101 : {
102 : // Binary search
103 0 : std::size_t lo = 0;
104 0 : std::size_t hi = db_size;
105 0 : while( lo < hi )
106 : {
107 0 : auto const mid = lo + ( hi - lo ) / 2;
108 0 : auto const cmp = compare_icase( db[mid].type, type );
109 0 : if( cmp < 0 )
110 0 : lo = mid + 1;
111 0 : else if( cmp > 0 )
112 0 : hi = mid;
113 : else
114 0 : return &db[mid];
115 : }
116 0 : return nullptr;
117 : }
118 :
119 : } // mime_db
120 : } // http
121 : } // boost
|