Content-type for Pylons Static Content February 6, 2008Posted by PythonGuy in Pylons, Web Technologies.
So I was playing with my shiny new Firefox3 beta 2. I was admiring the wonderful features of the canvas object. And I started to want to really get into SVG.
Well, I ran into a problem. My pylons server wasn’t serving SVG files as SVG files.
I put “test.svg” into my project’s “public” directory. I browsed to the URL http://localhost:5000/test.svg . I noticed that Firefox didn’t recognize the file and asked me to open another app to render it. (eog is nice, and it does a terrific job rendering it, but I wanted to have Firefox do the hard work this time around.)
Just to be sure that Firefox could render the file, I browsed to the absolute path on my local hard drive. That is, “file://home/pythonguy/MyProject/myproject/public/test.svg” Sure enough, it renders fine.
What else to do? Well, I realize by reading the FAQ on SVG for Firefox that if the server doesn’t send the correct Content-type response, then Firefox won’t guess. Sure enough, this telnet session showed me what my server was saying:
$ telnet localhost 5000 GET /test.svg HTTP/1.0 HTTP/1.0 200 OK Server: PasteWSGIServer/0.5 Python/2.5.1 Date: Wed, 06 Feb 2008 03:24:32 GMT content-type: application/octet-stream ...
So there’s the problem. My Pylons server doesn’t recognize the .svg ending on the file.
Digging deeper, I found this part in “config/middleware.py”:
Well, this certainly is interesting. The “Cascade” object lives in “paste/cascade.py”. All it does is try out the different apps until it gets one that doesn’t give an error response. The “StaticURLParser” object is the one that serves the static files.
Looking in “paste/urlparser.py” (thank goodness for explicit imports in Python!), I found a reference to “FileApp” in “paste/fileapp.py”. There, I see that the mime type is determined by the mimetypes module, part of the standard packages for Python.
Poking around mimetypes, I am not surprised to see that files ending in “.svg” are not recognized. (I am surprised, very happily surprised, that Pylons doesn’t try to redesign the wheel when it comes to MIME types.) Reading the documentation, it points out where it learns which file names represent which MIME types. On my system, that is “/etc/mime.types”.
Sure enough, SVG is missing from the list of MIME types in /etc/mime.types. Maybe it is out of date? (Unlikely, but possible.) Nope, it turns out that SVG isn’t registered yet as a valid MIME type.
I hand-edited the file to recognize SVG. Telnet now gives me:
$ telnet localhost 5000 GET /test.svg HTTP/1.0 HTTP/1.0 200 OK Server: PasteWSGIServer/0.5 Python/2.5.1 Date: Wed, 06 Feb 2008 03:24:32 GMT content-type: image/svg+xml ...
But Firefox still doesn’t recognize it. Nuts.