Set MIME type for server - ruby-on-rails

i've seen a bunch of topics about setting the MIME types.
But, no one helped me.
He is my problem:
I have a Rails website with bunch of video in .ogv and .mov formats, located in /public folder.
I refer to these files in HTML5 video tag.
There is no problem with .mov files, they are played nice in WebKit browsers.
The problem is with .ogv.
I think, it's because wrong MIME type for .ogv.
Here is what i get for .mov (correct):
$ curl -I http:/mywebsite.com/video.mov
HTTP/1.1 200 OK
Date: Sun, 03 Apr 2011 19:57:41 GMT
ETag: "4d98744c-1bb-87563c0"
Last-Modified: Sun, 03 Apr 2011 13:21:16 GMT
Content-Type: video/quicktime
Content-Length: 443
And here is what i get for .ogv:
$ curl -I http://mywebsite.com/video.ogv
HTTP/1.1 200 OK
Date: Sun, 03 Apr 2011 19:22:20 GMT
ETag: "4d987dcf-379884-81c533dc"
Last-Modified: Sun, 03 Apr 2011 14:01:51 GMT
Content-Type: application/octet-stream
Content-Length: 3643524
Instead of "application/octet-stream" i need "video/ogg".
I have a Mongrel server (no Apache as front-end), as i recently got to know. So, there is no way to use .htaccess.
I need to set MIME-type for regular files, not responses from controller etc.
I've tried several ways, described in my previous question: HTML 5 video (ogv) and MIME types
But i does't works. I still get "application/octet-stream".
My Questions are:
How can i set mime types for regular files, not responses from controller ?
Does Mongrel serves files, located in /public directory, or something else ?

I've figured it out.
All the methods, described in my previous question are setting MIME-types for Rails environment, not Mongrel.
I need additional MIME-types at Mongrel level, not Rails.
So, by starting mongrel via …
/usr/bin/mongrel_rails,
… I need to pass a YAML file to it, that contains additional MIME-types, i want to declare. This YAML file might look like this (mongrel_mime_types.yml):
.ogv: video/ogg
.ogg: application/ogg
.ogx: application/ogg
I keep it in /config/initializers, for convenience.
So, by starting Mongrel, i need to pass this file:
/usr/bin/mongrel_rails -m /path_to_my_project/http/config/initializers/mongrel_mime_types.yml
Now, if i check with curl, I'm getting correct MIME:
$ curl -I http://mywebsite.com/video.ogv
HTTP/1.1 200 OK
Date: Mon, 04 Apr 2011 05:38:01 GMT
ETag: "4d987dcf-379884-81c533dc"
Last-Modified: Sun, 03 Apr 2011 14:01:51 GMT
Content-Type: video/ogg
Content-Length: 3643524

Related

Heroku / Cloudfront / Fonts / Firefox

There are quite a few SO questions (1, 2, 3, etc.) that go over the same problem I am having (fonts are not displaying on FireFox due to CORS issue). I have tried all of the proposed solutions in the above questions as well as various blog posts that come up when Googling the issue.
In my specific case I am using Cloudfront on Heroku but I am not using S3 (my assets are pulled to the CDN on first request). I am also using site-wide SSL (and I'm not sure if this is what is causing my issues as all the other examples seem to be for http:// sites). Currently I am trying to use the font_assets gem but when I curl one of my font files (or even a jpg file) I am getting a 301 Moved Permanently instead of a 200.
curl -i https://d2loy3ox2q4ikr.cloudfront.net/assets/fontawesome-webfont-9a3b8f90662fe9149f07a059f1a4c782.woff
HTTP/1.1 301 Moved Permanently
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Date: Wed, 09 Apr 2014 12:27:33 GMT
Location: https://www.transdraft.com/assets/fontawesome-webfont-9a3b8f90662fe9149f07a059f1a4c782.woff
Status: 301 Moved Permanently
X-Cache: Miss from cloudfront
Via: 1.1 1316c66c042cd4b103a533bbf48877a5.cloudfront.net (CloudFront)
X-Amz-Cf-Id: NciaYbAYVS7OpY6ORzjeZMurd_cyBo-B1WfN1QZbSexbM2DoD0vWqg==
curl -i https://d2loy3ox2q4ikr.cloudfront.net/assets/transdraft-hp-2-0fa26dc608ff6a3ea83a093dce8e6338.jpg
HTTP/1.1 301 Moved Permanently
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Date: Wed, 09 Apr 2014 12:28:47 GMT
Location: https://www.transdraft.com/assets/transdraft-hp-2-0fa26dc608ff6a3ea83a093dce8e6338.jpg
Status: 301 Moved Permanently
X-Cache: Miss from cloudfront
Via: 1.1 c8b893f88c46deef2c0f22aefa2d3ecc.cloudfront.net (CloudFront)
X-Amz-Cf-Id: 897u3X7te5f167cZlJiBME1UlBp5NYtGrKm18D4FWOHlTEFMITYTLw==
Any idea what I might be doing wrong?
I fixed this same issue by modifying my application.css.scss to use SCSS imports instead of requires.
From:
//= require font-awesome
To:
#import 'font-awesome';
This may not work for you if you're not using SCSS.

Weird mmap failed size 2147483648 with AVPlayer for mp3 link

I am using AVPlayer to play some mp3 link, the file is just 1.8MB and I could download it, browser can also play it, but the app crashes (for other mp3 links it works) with the following information:
(951,0xac82aa28) malloc: * mmap(size=2147483648) failed (error
code=12)
error: can't allocate region
** set a breakpoint in malloc_error_break to debug
It fails even if the mp3 links is played first (ie there is no previous players created and not released in memory), so why do I still get the memory not enough error? I was thinking that it might be caused by the HTTP header when getting the stream, but the header looks fine:
HTTP/1.1 200 OK
Content-Length: 1872792
Date: Mon, 05 Aug 2013 00:19:10 GMT
Server: Apache/2.2.3 (CentOS)
Last-Modified: Thu, 25 Jul 2013 02:06:19 GMT
Etag: "1c9398"
Accept-Ranges: bytes
Cache-Control: max-age=0
Expires: Mon, 05 Aug 2013 00:19:10 GMT
Connection: close
Content-Type: audio/mpeg
Can anyone help?
Thanks

Heroku production setting Cache-Control differently from local production

I have an app running on heroku at http://chesseng.herokuapp.com/ when I visit the page with chrome and its caching disabled I get a response header for application-fingerprint.css that is something like
Cache-Control:private
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/css
Date:Wed, 17 Oct 2012 00:17:19 GMT
Last-Modified:Tue, 16 Oct 2012 03:13:38 GMT
Status:200 OK
transfer-encoding:chunked
Vary:Accept-Encoding
X-Rack-Cache:miss
However if I start up a local instance with rails s -e production and visit it the response header for application-fingerprint.css is something like
Age:5119
Cache-Control:public, max-age=31536000
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:95828
Content-Type:application/javascript
Date:Tue, 16 Oct 2012 23:01:27 GMT
Etag:"0bf9e9837d421c2e28be1ef4f0794a48"
Last-Modified:Tue, 16 Oct 2012 01:07:17 GMT
Server:WEBrick/1.3.1 (Ruby/1.9.3/2012-04-20)
Vary:Accept-Encoding
X-Content-Digest:add442e2036c1e6e9f4860dcc44496582a5c91b1
X-Rack-Cache:fresh
X-Request-Id:b89de17e397ac7b60acfe500e8d15df9
X-Runtime:0.001632
X-Ua-Compatible:IE=Edge,chrome=1
Why are the caching related fields like Cache-Control, Etag so different compared to heroku? Presumably I want heroku to return Cache-Control:public, max-age=31536000. But I need to first understand why Cache-Control:public, max-age=31536000 is being set in my local production mode. Its puzzling because if I set config.static_cache_control = "public, max-age=3600" in config/environments/production.rb and start up a local server in production it still gives back max-age=31536000 and seems to ignore max-age=3600
From the X-Rack-Cache headers it looks like you’re using the rack-cache middleware which would affect the caching headers. Since locally your resource is in the cache (X-Rack-Cache:fresh), but on Heroku it isn’t (X-Rack-Cache:miss) that would explain the difference.
Try removing rack-cache from your middleware stack and see if the differences go away.

BlackBerry Browser (4.5) refuses to cache CSS. Is there a workaround?

I develop an internal web application for my company. It is used by our field technicians, all of whom carry a BlackBerry 8330 running 4.5. I would consider myself fortunate to have such a consistent target platform, if it wasn't BB 4.5...
I've noticed a lot of request overhead in loading the site, and know that if only my CSS resources were cached, the load time would be cut dramatically. The BB always requests a full copy of the CSS file, no matter if the Expires, Cache-Control, or Last-Modified headers are set. It doesn't hit its cache, it doesn't send an If-Modified-Since, nothing.
Anyone run into this or know what I can do to workaround it? I'd really like to avoid inlining my CSS if I don't have to.
EDIT: I just noticed that it is always requesting the page twice. Below are diffs between to 2 requests
GET /css/bb.css HTTP/1.1 |GET /css/bb.css HTTP/1.1
User-Agent: BlackBerry8330/4.5.0.77|User-Agent: BlackBerry8330/4.5.0.77
profile: http://www.blackberry.net/|profile: http://www.blackberry.net/
-----------------------------------|Accept: application/vnd.rim.html,te
-----------------------------------|Connection: close
Referer: http://10.7.2.167/page.php|Referer: http://10.7.2.167/page.php
-----------------------------------|Accept-Charset: ISO-8859-1,UTF-8,US
Host: 10.7.2.167 |Host: 10.7.2.167
-----------------------------------|Accept-Language: en-US,en;q=0.5
-----------------------------------|x-wap-profile: "http://www.blackber
Cookie: PHPSESSID=xxxxxxxx; token=x|Cookie: PHPSESSID=xxxxxxxx; token=x
-----------------------------------|Via: MDS_5.0.0.86
|
HTTP/1.1 200 OK |HTTP/1.1 200 OK
Date: Sun, 05 Sep 2010 09:34:52 GMT|Date: Sun, 05 Sep 2010 09:34:54 GMT
Server: Apache/2.2.15 (Debian) |Server: Apache/2.2.15 (Debian)
Last-Modified: Sat, 04 Sep 2010 02:|Last-Modified: Sat, 04 Sep 2010 02:
ETag: "10426-d64-48f65ab39bf80" |ETag: "10426-d64-48f65ab39bf80"
Accept-Ranges: bytes |Accept-Ranges: bytes
Content-Length: 3428 |Content-Length: 3428
Cache-Control: max-age=12960000 |Cache-Control: max-age=12960000
Expires: Wed, 02 Feb 2011 09:34:52 |Expires: Wed, 02 Feb 2011 09:34:54
Vary: Accept-Encoding |Vary: Accept-Encoding
-----------------------------------|Connection: close
Content-Type: text/css |Content-Type: text/css

Passenger/Apache: Can't set expire headers for versioned resources (rewrite rule not recognized)

I'm trying to set the expire headers for Rails' auto-versioned resources, like whatever.css?1234567890 . (I don't want to set the expire headers for unversioned resources.) The only method I could find online involved two steps: 1) rewrite all urls that end in 10 digits to load from /public/add_expires_header instead of from /public, where add_expires_header is a symlink that points to /public 2) Add an expiry date to all files from add_expires_header.
Seems like a good idea -- but passenger doesn't seem to recognize the rewrite rule, as indicated by the below curl results.
(Note: a lot of people seemed to think they could accomplish my goal using FilesMatch, but I read elsewhere that FilesMatch can't see the query string.)
#from sites_enabled/sitename in the tags
...
RewriteCond %{QUERY_STRING} ^[0-9]{10}$
RewriteRule ^(.*)$ /add_expires_header%{REQUEST_URI} [QSA]
ExpiresActive On
ExpiresDefault "access plus 1 years"
...
-----
#curl indicates that rewrite rule isn't taking effect
manu#Blade-Server:~$ curl -I -L "http://x.com/stylesheets/style.css?1249092148"
HTTP/1.1 200 OK
Date: Tue, 11 Aug 2009 04:07:49 GMT
Server: Apache/2.2.11 (Ubuntu) Phusion_Passenger/2.2.4 PHP/5.2.6-3ubuntu4.1 with Suhosin-Patch
Last-Modified: Sat, 01 Aug 2009 02:02:28 GMT
ETag: "455b-2fbb-4700aedc5f500"
Accept-Ranges: bytes
Content-Length: 12219
Vary: Accept-Encoding
Content-Type: text/css
manu#Blade-Server:~$ curl -I -L "http://x.com/add_expires_header/stylesheets/style.css?1249092148"
HTTP/1.1 200 OK
Date: Tue, 11 Aug 2009 04:07:55 GMT
Server: Apache/2.2.11 (Ubuntu) Phusion_Passenger/2.2.4 PHP/5.2.6-3ubuntu4.1 with Suhosin-Patch
Last-Modified: Sat, 01 Aug 2009 02:02:28 GMT
ETag: "455b-2fbb-4700aedc5f500"
Accept-Ranges: bytes
Content-Length: 12219
Cache-Control: max-age=31536000
Expires: Wed, 11 Aug 2010 04:07:55 GMT
Vary: Accept-Encoding
Content-Type: text/css
I've also tried including the rewrite stuff in apache2.conf, httpd.conf, and public/.htacess
I prefer to do this by combining it with using an assets host on a separate subdomain to avoid the whole rewrite issue. That way you can set the expire headers for everything on that subdomain. You can activate this in rails in environments/production.rb.
If you don't want to go with a separate subdomain I think the code below should do it, although I have not tested it myself:
ExpiresActive On
<FilesMatch "\.(ico|gif|jpe?g|png|js|css)$">
ExpiresDefault "access plus 1 year"
</FilesMatch>

Resources