Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version number as URL parameter breaks Content-Type detection #174

Closed
czj opened this issue Jun 20, 2016 · 8 comments
Closed

Version number as URL parameter breaks Content-Type detection #174

czj opened this issue Jun 20, 2016 · 8 comments

Comments

@czj
Copy link

czj commented Jun 20, 2016

First, sorry if this issue is a dupe, I've check the gem's documentation and previous issues to make to try to find a solution.


Generated assets include a version number at the number like :

@font-face {
    font-family: 'FontAwesome';
    src: url("/assets/fontawesome-webfont-50bbe9192697e791e2ee4ef73917aeb1b03e727dff08a1fc8d74f00e4aa812e1.eot?v=4.6.3");
 }

A page monitoring service we use detected that the Content-Type for this particular asset is returned as application/octet-stream instead of application/font-woff2 for other font assets we use.

As this gem is made to be used with Rails and Sprockets, which generates checksum/hash suffixed assets during compilation that allows for efficient caching, is there a reason for this version parameter ?

Thanks a lot.

@rmm5t
Copy link
Collaborator

rmm5t commented Jun 20, 2016

A page monitoring service we use detected that the Content-Type for this particular asset is returned as application/octet-stream instead of application/font-woff2 for other font assets we use.

Sounds like your web server or CDN isn't properly configured to respond with the correct mime-types per request. Here's example output from a server I manage (running on Heroku with nginx serving the static assets):

$ curl -I "http://{{domain}}/assets/fontawesome-webfont-c812ddc9e475d3e65d68a6b3b589ce598a2a5babb7afc55477d59215c4a38a40.woff?v=4.5.0"
Server: nginx/1.8.0
Content-Type: application/font-woff

$ curl -I "http://{{domain}}/assets/fontawesome-webfont-e219ece8f4d3e4ac455ef31cd3a7c7b5057ea68a109937fc26b03c6e99ee9322.eot?v=4.5.0"
Server: nginx/1.8.0
Content-Type: application/vnd.ms-fontobject

As this gem is made to be used with Rails and Sprockets, which generates checksum/hash suffixed assets during compilation that allows for efficient caching, is there a reason for this version parameter ?

It's a reasonable question, but the cache-busting version query parameter exists for a few reasons. The main/original reason is because the underlying source CSS from the core FontAwesome library includes it (example).

Also, we used to get more support requests than I'd care to handle because those submitting the requests never seemed to understand how to manage or debug their cache correctly when upgrading font-awesome-rails in their development environment. The cache-busting query param helps in both development environments and when someone turns off the digests during the assets:precompile task.

Overall, the version query parameter shouldn't cause Content-Type mismatches if things are properly configured in your production environment.

@rmm5t rmm5t closed this as completed Jun 20, 2016
@czj
Copy link
Author

czj commented Jun 21, 2016

I understand @rmm5t ; that's why I was suspecting (the support requests side of things).
We'll upgrade nginx & Debian soon, hopefully managing to get the proper Content-Type like you do.

Thanks for your answer, and thanks for you great maintainer work :-)

@coreyward
Copy link

This is a broader FontAwesome issue, but it's especially disruptive in Rails applications that already use the asset pipeline. It also requires special handling on Amazon CloudFront.

FortAwesome/Font-Awesome#3286

@rmm5t
Copy link
Collaborator

rmm5t commented Jun 22, 2016

Re-opening for further discussion. Willing to consider options. However, if we veer from core FontAwesome behavior, I just want to cover the bases.

  • Is it possible that anyone relies on the version in the query string?
  • Why don't major CDNs handle static query strings properly? Do we have documentation to support this?
  • If we remove the query string from production, I'd like to see it (or something similar) remain in development mode (to help cache bust and reduce the number of false bug reports here).

@rmm5t rmm5t reopened this Jun 22, 2016
@coreyward
Copy link

The way I prefer to use a static-asset CDN with Rails apps, especially on Heroku, is to setup the application as the “origin” for the assets but use the CDN as the host for visitors. I use the asset fingerprinting / hashing provided by the asset pipeline, and per best practices, serve assets with a far-future cache control header. The CDN respects the cache-control headers from the application, and can fetch a resource from the application as needed for distributions around the world.

Asset versioning, in this sense, is handled automatically by asset fingerprinting. This is very pragmatic for code that is not released publicly. There's rarely a need for me to internally reference an image, font, or stylesheet by a version number, so easy communication of it isn't relevant — the source commit version is sufficient, and an asset fingerprint would work in a pinch.

Further, with the asset pipeline, vendor provided versioning isn't necessary. Junior members of my team don't need to know that FontAwesome uses a query string with a v parameter, or that some other library we use includes the version number in the filename. We can update the assets, leave the names as something plain (e.g. zepto.js) and they'll be served appropriately without any cache busting needs.

Back to CDNs, efficient use necessitates similar or identical requests. Query strings communicate variance. CloudFront used to ignore them altogether; now they support treating them as dynamic (though it requires additional setup). The recommendation is to only use query strings if your server returns different content based on the query string—which is the expectation.

In development, Rails uses asset fingerprinting along with cache control headers to manage asset caching:

screen shot 2016-06-22 at 12 56 36 pm

In short, while FontAwesome needs to contend with things like Wordpress usage (where appropriate asset management is the rare exception, not the norm), font-awesome-rails is able to address a specific, narrow scope with well adopted tools and techniques that eliminate the need for query string based caching.

@rmm5t
Copy link
Collaborator

rmm5t commented Jun 22, 2016

@coreyward Strong, convincing arguments. Thank you.

I just pushed a branch and PR to test this. See #175.

@czj @coreyward If you can please both test this branch in your environments, that would help a bunch. Once I get positive confirmation that the changes work well for both of you, I'll release a new official version eliminating the need for the version in the query strings of the font asset references.

i.e. To test, please temporarily update your Gemfile as such:

gem "font-awesome-rails", github: "bokmann/font-awesome-rails", branch: "174-remove-version-query-string"

@czj
Copy link
Author

czj commented Jun 23, 2016

@rmm5t tested the branch and it works, solves our issue — that was also fixed by configuring nginx.

The removal of the FontAwesome version number is scheduled for their 5.0 branch, as it looks like on FortAwesome/Font-Awesome#3286 (Milestone 5.0). You both seem to be converging to this solution.

@rmm5t
Copy link
Collaborator

rmm5t commented Jun 23, 2016

v4.6.3.1 was just released with the version query strings removed from font assets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants