This project is archived and is in readonly mode.
Mime type lookup_by_extesion is case sensitive
Reported by Brian Samson | July 8th, 2008 @ 10:07 PM | in 2.x
When reverse resolving extensions to mime types via Mime::Type.lookup_by_extension, the lookup fails unless the extension is of the same case as was registered.
I ran into this bug in code that determines the mime type of a user uploaded file that happened to have the extension JPG:
>> Mime::Type.lookup_by_extension('JPG')
=> #
>> Mime::Type.lookup_by_extension('jpg')
=> #
I had previously registered a mime type like so:
Mime::Type.register 'image/jpeg', :jpg, [], ["jpeg"]
I'm attaching a patch to mime_type.rb that fixes this issue.
Comments and changes to this ticket
-
Brian Samson July 8th, 2008 @ 10:10 PM
Sorry that code snippet didn't come through right because of angle brackets.
>> Mime::Type.lookup_by_extension('JPG')
=> #<Mime::Type:0x18cd970 @synonyms=[], @symbol=nil, @string="JPG>
>> Mime::Type.lookup_by_extension('jpg')
=> #<Mime::Type:0x17ef83c @synonyms=[], @symbol=:jpg, @string="image/jpeg>
-
Ripta Pasay July 17th, 2008 @ 09:21 PM
- no changes were found...
-
Ripta Pasay July 17th, 2008 @ 09:21 PM
- Tag changed from actionpack, mime, patch to actionpack, mime, patch, tested, tests
+1 on this. Attached is a patch that passes all current actionpack tests, with an extra test to verify that #lookup_by_extension is case-insensitive.
-
Pratik July 18th, 2008 @ 12:36 AM
- State changed from new to wontfix
I think it should be upto the dev. to downcase the string :
Mime::Type.lookup_by_extension('JPG'.downcase)
-
Geoff Coffey July 18th, 2008 @ 01:06 AM
I'm curious why we wouldn't want to fix this. File extensions are not considered case sensitive in any way I'm familiar with. Put another way, if I register "jpg" and then lookup "JPG" and get a different result, it implies that "jpg" and "JPG" are different in meaning as file extensions. I'm not a mime expert, but experience tells me this is never the case. So the API is artificially restrictive here.
Next, just "downcase" isn't good enough. You have to match the case it was registered with. This means every call to lookup_by_extension has a (small but real) dependence on some dissociated call to register, which feels dirty. You can "fix" this with a convention to always register lower case, but if you go that route, what's the point in forcing me to downcase all over the place instead of just having the API do it for me?
Also, I suspect this is an easy source of accidental bugs. Consider this case:
Mime::Type.lookup_by_extension(my_file.extname)
Which is probably very common. It will succeed in testing most of the time because programmers tend to favor lower case names and often case sensitive file systems. But in production, it is likely to fail occasionally. I'll bet this bug exists in production code all over the place today.
Is there any good reason to keep this case sensitive?
Geoff
-
Ripta Pasay July 18th, 2008 @ 04:05 AM
I agree with Geoff.
The problem is that we're not calling #lookup_by_extension ourselves. If we were, then we could .downcase before passing into the method. Instead, Rails makes the call for us somewhere deep in the bowels of the framework. As such, even though :css is registered, you can't handle a URL ending in uppercase .CSS because extensions are compared case-sensitively.
Without this patch, the only other way (that I can see anyway) to handle .CSS in addition to .css is to add:
Mime::Type.register_alias "text/css", :css, ["CSS"]
and add the uppercase version of the file extensions in lib/action_controller/mime_types.rb.
If there is no reason to have case-sensitive extensions, handling it centrally as in the patch previously attached, seems like a far better solution.
-
Pratik July 18th, 2008 @ 04:16 AM
Why is the URI ending by .CSS and .css ? Just curious. Going strictly by the rules, URI is case sensitive.
-
Geoff Coffey July 18th, 2008 @ 06:53 AM
Case is significant in URIs, but in practice, it is not so with extensions. For instance, Apache's AddType directive is documented here:
http://httpd.apache.org/docs/2.0...
Where it says, "The extension argument is case-insensitive, and can be specified with or without a leading dot."
-
Brian Samson July 18th, 2008 @ 07:46 AM
Ripta: Thanks for writing that test case, I appreciate it.
Pratik: Like I said in the original post, I noticed this issue mapping user-uploaded files to mime-types which could explain the strange capitalization.
I agree that it is unorthodox to name a
stylesheet "style.CSS"; however that name is still perfectly valid in a URI and I believe rails should recognize it as text/css.
-
RSL July 18th, 2008 @ 12:37 PM
I think this is a problem of Windows devs forgetting that on Unix servers [because hopefully no one is deploying Rails to a Windows server] case does matter. And that you are responsible for managing your own code. It's not a bug in Rails that you were careless enough to mismatch case all over code you control.
-1 from me.
-
Geoff Coffey July 18th, 2008 @ 02:56 PM
case does not matter in the file extension for mime-mapping purposes in any scenario I have ever seen in all my life. And I am not a windows dev.
Extension->mime type mapping is non-case-sensitive in Apache on Linux, and in IIS on Windows. It is not case sensitive in Nautilus on Linux.
Also, this is not a matter of carelessness. As has been said before, the scenario where this arose was related to file uploads from users. We have no control over how our end users name their files.
Finally if dev wants to name a file "something.CSS" and carefully uses this name throughout the code, it should work. It will work in other environments. But it will not work in Rails. Can you find a standard that says the CSS file extension must be lower case?
-
RSL July 18th, 2008 @ 02:59 PM
Re: "We have no control over how our end users name their files."
You do have the ability [if not the responsibility] to rename/downcase/whatever a user's chosen filename when it's placed on your system.
-
Geoff Coffey July 18th, 2008 @ 03:51 PM
On a Unix platform 'foo.css' != 'foo.CSS'.
Of course not. Nobody is arguing that point except you.
On a "unix" platform, though, a mime-type mapping in Apache for ".css" to the CSS mime type does apply to:
.css, .CSS, .Css, .CSs, .CsS, .cSS, .csS. .cSs
This has absolutely nothing to do with file systems. lookup_by_extension is about mapping extensions to mime types. The apparent defacto standard is that such mapping are not case sensitive. But in Rails they are.
Of course we can work around it. That's not the point. The point it we shouldn't have to.
You do have the ability [if not the responsibility] to rename/downcase/whatever a user's chosen filename when it's placed on your system.
Again, not arguing that. Of course in many cases I don't want to rename my user's uploaded files. But I can work around that a dozen ways. So if you're a fan of arbitrary workarounds for behavior that is unexpected, then I suppose you're right. But I like things that just work correctly out of the box.
-
Ripta Pasay July 19th, 2008 @ 08:19 PM
I'm very aware that foo.css != foo.CSS on Unix (and all its derivatives), including OS X which is what I'm on.
In the case of Rails however, I don't think this has strictly to do with the filesystem. If the file exists on the filesystem and requires no further processing, then Rails shouldn't be handling it in the first place.
If you still disagree with the patch, then at the least allow for the configurable option to treat extensions case-insensitively without having to repeat all the mime-types and the upper- and lowercase combinations of every extension.
I have no further opinions to contribute that haven't already been said.
-
jrochkind March 30th, 2010 @ 12:17 AM
Please note that this applies to content-types too, and is definitely not right. In either case. I agree with the original ticket, although it may be too late.
But it may be more convincing to argue it for actual mime content-types. Maybe I'll file a new ticket?
According to W3C standard, actual content-type is case-insensitive:
http://www.w3.org/Protocols/rfc1341/4_Content-Type.html
"The type, subtype, and parameter names are not case sensitive. For example, TEXT, Text, and TeXt are all equivalent."
However, Mime::Type.lookup("TEXT/html") does not work, it does not return the same lookup as Mime::Type.lookup("text/html").
In the case of the original ticket with format suffix's, it's just an unwritten standard, I guess. But in the case of actual content-types, this would seem to be a clear violation of the actual written standard?
-
Brian Samson March 30th, 2010 @ 05:58 PM
Yes I totally agree, the entire system should be case insensitive. However for reasons I do not understand the committers seems to disagree with you, me, apache, the W3C, and countless other people so I don't know what to tell you at this point.
-
trevmex August 1st, 2010 @ 02:27 AM
- Importance changed from to
I wanted to add a bump to this patch. I just ran into this issue myself. I understand the argument for keeping the URI case-sensitive, but it is slightly annoying to have to type this:
Mime::Type.register_alias "image/jpeg", :jpg, ['Jpg', 'jPg', 'jpG', 'JPg', 'JpG', 'jPG', 'JPG']
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>