What is the process by which sinatra's send_file decides what content-type to use?
For example, it seems that it works by the extension of the file passed to send_file, so if it is send_file blah.txt . then when I http to the route, I will get/ the response header will be, content-type: text/plain
, so any html in the txt file will be interpreted by the web browser as plain text. Whereas if the file is blah.html then the server will respond with content-type: text/html
.(and any html in the file is rendered as such)
And of course the route name is irrelevant so you could go to http://127.0.0.1:4567/zzz.html
and it could lead to send_file a.txt and a.txt may contain html tags but since it's a .txt
file send_file will cause sinatra to respond with content-type: text/plain
and the browser won't render any html sent and will show it as plain text. I may be wrong but that seems to be what my quick tests indicate. Where I tried different routes, different filename extensions(.txt, and .html), sometimes files with html in them sometimes not, seeing whether the browser renders the html or not, and seeing what the content-type header was, with wget -d.
So then my question related to that is, is there a list that sinatra's send_file function uses, that relates file extension to content-type? I would like to see that list. And if not, then what is the process it is using.
Note- I understand there is a way to pass in a content-type Sinatra: How to respond with an image with headers "content-type" => "image/jpeg" but i'm asking how/ by what method, send_file determines content-type when no content-type is passed in.
This is the send_file
method in the Sinatra framework (currently v2.0.5), notice it hands off finding out the content type straight away if none has been set:
if opts[:type] or not response['Content-Type']
content_type opts[:type] || File.extname(path), :default => 'application/octet-stream'
end
The content_type
method will either return immediately or hand off to mime_type
, which is a delegate of Rack's mime_type
method (currently v2.0.7). This uses a well known list of extensions to check against.
def mime_type(ext, fallback='application/octet-stream')
MIME_TYPES.fetch(ext.to_s.downcase, fallback)
end
The list begins on line 49:
MIME_TYPES = {
".123" => "application/vnd.lotus-1-2-3",
".3dml" => "text/vnd.in3d.3dml",
".3g2" => "video/3gpp2",
".3gp" => "video/3gpp",
# <snip>
As you can see from the content_type
snippet, the default it falls back on is application/octet-stream
.