documentcloud / jammit

Industrial Strength Asset Packaging for Rails
http://documentcloud.github.com/jammit/
MIT License
1.16k stars 197 forks source link

Content Negotiation not working under Apache #46

Closed yxmatic closed 14 years ago

yxmatic commented 14 years ago

Unfortunately Content Negotiation using MultiViews requires the requested file to not exist on the filesystem. This was already pointed out in the comment by Ches Martin to this post: http://afreshcup.com/home/2010/1/18/notes-on-using-jammit-with-rails.html.

So in other words, in order for asset pre-caching to work under Apache the URLs generated by Jammit should omit the file extension.

This can be tested using the following .htaccess in the assets folder:

AddEncoding x-gzip .gz
Options +MultiViews

<FilesMatch "\.css.gz$">
  ForceType text/css
</FilesMatch>

<FilesMatch "\.js.gz$">
  ForceType text/javascript
</FilesMatch>

Here is an example request:

% curl -I -H 'Accept-Encoding:gzip,deflate' http://site.local/assets/style   
HTTP/1.1 200 OK
Date: Thu, 27 May 2010 09:56:03 GMT
Server: Apache/2.2.14 (Unix) mod_ssl/2.2.14 Phusion_Passenger/2.2.11
Content-Location: style.css.gz
Last-Modified: Thu, 27 May 2010 09:45:28 GMT
ETag: "75aef2-120f-4878c0f420a00;4878c75f4eec0"
Accept-Ranges: bytes
Content-Length: 4623
Cache-Control: max-age=31536000
Expires: Fri, 27 May 2011 09:56:03 GMT
Content-Type: text/css
Content-Encoding: gzip

I think a possible solution could be the addition of a configuration option to omit filename extensions in production.

documentcloud commented 14 years ago

It seems quite risky to remove (or rename) the actual asset file, and assume that the gzip version is always going to work. What happens when the user agent says that it doesn't accept gzipping?

I guess that the other half of it would be to rename all of your files with an Apache-language-specific extension, like:

public/assets/package.js.en
public/assets/package.js.en.gz

But does Apache even do language extensions for JavaScript and CSS?

documentcloud commented 14 years ago

After digging around a bit, and asking in #httpd, it looks like the Apache way to accomplish this is by adding a RewriteRule. If you've got an example of one that's working for you, I'd be glad to add it to the Jammit documentation.

yxmatic commented 14 years ago

Thanks for the insight. I think I'll stick with mod_deflate for the time being, given that apparently Passenger doesn't support MultiViews. I did a few tests with MultiViews on and everything seemed to work fine, but I'd hate to see some crazy bug pop up when I least expect it.