This commit is contained in:
2026-07-29 13:24:36 +02:00
parent 7e26cfd6d3
commit f5f6a1e143
8 changed files with 1041 additions and 888 deletions
+32 -62
View File
@@ -4,76 +4,46 @@
racket/contract
racket-mimetypes))
@title{MIME Types}
@title{racket-mimetypes}
@author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]]
@defmodule[racket-mimetypes]
The @racketmodname[racket-mimetypes] library maps file extensions to MIME type
strings. It uses a built-in table and does not inspect the contents of a file.
The @racketmodname[racket-mimetypes] library maps file extensions to MIME
types. It uses a built-in fallback table and keeps a validated copy of
Apache's @tt{mime.types} in Racket's user cache directory.
The cache file is stored below @racket[(find-system-path 'cache-dir)] in the
@tt{racket-mimetypes} directory.
The first lookup that finds an expired cache starts a background update.
Lookups never wait for the download. After a successful update, the next
check is performed after seven days. After a failed update, the next attempt
is made after one day. Both outcomes are written as debug messages through
the @racketmodname[simple-log] logging system.
The downloaded file is parsed and validated before it replaces the cache.
If downloading, parsing, validation, or replacement fails, the existing
cache remains available. If Apache assigns an extension more than once, the
last assignment in the file is used.
@defproc[(mimetype-for-ext
[ext (or/c path-string? symbol?)]
[#:default default string? "application/octet-stream"]
[#:context context
(or/c #f
'application
'audio
'example
'font
'haptics
'image
'message
'model
'multipart
'text
'video)
#f])
[ext (or/c path? string? symbol?)]
[#:default default string? "application/octet-stream"])
string?]{
Returns the MIME type associated with @racket[ext]. The argument can be an
extension, a path string, or a path. Symbols are accepted for extensions.
Returns the MIME type associated with @racket[ext], or @racket[default] when
the extension is unknown.
The following forms are accepted:
@racket[ext] can be an extension, a file name, or a path. Strings and symbols
can contain an extension with or without a leading dot. For a file name or
path, the text after the last dot in the last path component is used.
Matching is case-insensitive.
@itemlist[
#:style 'compact
@item{A string containing a bare extension, such as @racket["mp3"] or
@racket[".MP3"].}
@item{A symbol containing a bare extension, such as @racket['mp3].}
@item{A string containing a file name or path, such as
@racket["track.flac"], @racket["/music/track.flac"], or
@racket["c:\\music\\track.flac"].}
@item{A Racket path value, such as
@racket[(string->path "/music/track.flac")].}
]
The procedure does not parse URLs and does not inspect file contents.
The final path component is used and the text following its last dot is taken
as the extension. A leading dot on a bare extension is therefore ignored.
Both slash and backslash are recognized as path separators, independent of the
current operating system. The resulting extension is converted to lowercase
and stored internally as a symbol.
A string without a dot is treated as a bare extension. Consequently,
@racket["README"] is looked up as the extension @racket['readme]. A name ending
in a dot has no recognized extension and normally produces @racket[default].
The procedure accepts file-system paths, not URLs. Query strings and fragments
are not removed. The contents of a file are not inspected.
An extension can have more than one MIME type. Without @racket[context], the
first and most common type is returned. A context selects a MIME type whose
top-level type matches the context. For example,
@racket[(mimetype-for-ext "track.mp4")] returns @racket["video/mp4"], while
@racket[(mimetype-for-ext "track.mp4" #:context 'audio)] returns
@racket["audio/mp4"].
If the extension is unknown, or no type matches the supplied context,
@racket[default] is returned.
For example, @racket[(mimetype-for-ext "MP3")] returns
@racket["audio/mpeg"], @racket[(mimetype-for-ext ".flac")] returns
@racket["audio/flac"], and
@racket[(mimetype-for-ext "unknown" #:default "text/plain")]
returns @racket["text/plain"].
}
@racketblock[
(mimetype-for-ext 'mp3)
(mimetype-for-ext ".PNG")
(mimetype-for-ext "music/track.opus")
(mimetype-for-ext "unknown" #:default "unknown/type")
]}