Apache Set MIME Type Dynamically - apache

We have mutiple files where we need to set MIME type based upon file type. Ex:
/{path}/alpha.woff --> font/woff
/{path}/beta.woff2 --> font/woff2
/{path}/gamma.ttf --> font/ttf
We have added the below snippet in apache config file but not certain how to achieve with one LocationMatch attribute
<LocationMatch "\.(?i:woff|woff2|ttf)$">
Header set Content-Type font/{dynamically set woff OR woff2 OR ttf }
</LocationMatch>
This can be done with multiple LocationMatch (one for each font) but looks not optimized one.
Can anyone suggest better solution to deal with such situation?
Tried with regex which throw an error.
<LocationMatch "\.(?<fonttype>(?i:woff|woff2|ttf))$">
Header set Content-Type font/woff // Work fine but set font/woff for all fonts
</LocationMatch>
Below throw error in config
<LocationMatch "\.(?<fonttype>(?i:woff|woff2|ttf))$">
Header set Content-Type font/%{env:MATCH_FONTTYPE}
</LocationMatch>
Unrecognized header format %

The mime types can be configured in the conf/mime.types configuration file of the Apache HTTP Server, see the example here:
font/woff woff
font/woff2 woff2
font/ttf ttf
If you can't update this file, and LocationMatch directive is your only option, then starting from Apache 2.4.8 you can use named regex capture groups, see documentation.
In the following example, I've named the capture group fonttype, so by convention it will be put into the environment variable MATCH_FONTTYPE. This environment variable can be used in the ForceType expression:
<LocationMatch "\.(?<fonttype>(?i:woff|woff2|ttf))$">
ForceType font/%{env:MATCH_FONTTYPE}
</LocationMatch>

Related

How to modify Content-Type in apache

We are currently having Content-Type: text/html.
We want to modify this to text/javascript or text/css.
We have tried this using rewrite rule, mod_headers and also through mod_mime, but we are unable to modify it.
Any suggestion?
Assuming you have certain text files in a directory say styles add a .htaccess file in the root directory and add the following content:
<Location /styles>
ForceType text/css
</Location>
And use the similar concept for javascript as well
I had solved this by changing the content type in application servers of content.

Enabling CORS .htaccess restrictions

I am encountering some behaviour from a produciton server and I was wondering if someone could confirm if something is possible and how it might have been done.
I have a website www.example.com with SSL enabled and all traffic forwarding to https
On that site I have a font file https://www.example.com/wp-content/assets/fonts/icons.ttf
I have additional campaign sites (e.g www.examplecampaign.com) that use the css file from example.com which loads in a font face using that font file. I am actually adding all the relevant file types woff, etc but will refer to ttf for simplicity. The icon font displays fine on www.example.com but on www.examplecampaign.com because in Firefox I get the error
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.example.com/wp-content/assets/fonts/icons.ttf. This can be fixed by moving the resource to the same domain or enabling CORS.
So here begins my problem. On our stage server which we have full access to I can add
# BEGIN REQUIRED FOR WEBFONTS
AddType font/ttf .ttf
AddType font/eot .eot
AddType font/otf .otf
AddType font/woff .woff
<FilesMatch "\.(ttf|otf|eot|woff)$">
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
# END REQUIRED FOR WEBFONTS
to the .htaccess file and that solves the problem. However on our produciton server which is owned and managed by the client this header modification is ignored. I am using http://web-sniffer.net/ to test this.
To further complicate things I hvae found that if I just added
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
on my stage site the header would appear when requesting any page or resource BUT on the production server if I added that the Access-Control-Allow-Origin would appear on all pages apart from the font files (and possible other resources).
So my question is, is it possible in Apache to disable / ignore header modification for a certain file type(s) and how would that be done. It's weird that it's so specific. We no longer have sudo access and have to request changes to conf files which is one of the reasons im making this change in .htaccess not that I think that would matter where this is set? Also example.com is a wordpress site but I don't think that would affect anything? As it's working on stage but not produciton.
Does anyone know of the Apache configuration that would restrict the use of mod_header in that way?

How to serve compressed/uncompressed files based on request's accepted encoding types by having only compressed files

In apache htdocs, i want to only have compressed files (gzip file) and based on request's accepted encoding types, if gzip encoding is enabled, I want apache to serve the compressed file and if gzip encoding is not supported, then I want apache to serve by uncompressing the gzip files.
I don't want to keep uncompressed files and use deflate to compress when accessed as this will be inefficient and as by default all clients support gzip encoding.
By having both the compressed and uncompressed files (example.js and example.jsgz both in htdocs directory), I was able to make this work by using RedirectCond on request's accepted encoding and RedirectRules. But this needs two files to be stored (compressed and normal ones). Below is the configuration i used with redirect rules.
<Directory /var/www/app>
AddEncoding gzip .jsgz .cssgz .htmlgz
AddType text/javascript .jsgz
AddType text/css .cssgz
AddType text/html .htmlgz
SetEnv force-no-vary
Header set Cache-Control "private"
RewriteEngine on
# If client accepts compressed files
RewriteCond %{HTTP:Accept-Encoding} gzip
# and if compressed file exists
RewriteCond %{REQUEST_FILENAME}gz -f
# send .htmlgz instead of .html
RewriteRule ^(.+)\.(html|css|js)$ $1.$2gz [L]
</Directory>
I dont want to do as above as I have to keep both versions of each file.
For example:
Contents of app directory inside htdocs
ls app/
example.jsgz
Server side apache configuration for app directory
In this case with MultiView option, I am able to server example.jsgz when request file is example.js as example.js is not present. And the configuration on my apache side is as below:
<Directory /var/www/htdocs/app>
AddEncoding gzip .jsgz .cssgz .htmlgz
AddType text/javascript .jsgz
AddType text/css .cssgz
AddType text/html .htmlgz
Options +Multiviews
SetEnv force-no-vary
Header set Cache-Control "private"
</Directory>
Case 1:
Request headers say gzip encoding is supported. And requested url is example.js and not example.jsgz. This is working and example.jsgz file is served with content encoding as gzip and client is able to decompress and use the js file.
Request URL:http://A.B.C.D/app/example.js
Request Method:GET
Request HTTP headers:
Accept-Encoding:gzip,deflate,sdch
Response Headers:
Content-Encoding:gzip
Case 2:
Request headers say gzip encoding is not supported. And requested url is example.js and not example.jsgz. This is not working as apache is serving example.jsgz and client is failing as gzip encoding is not supported.
Request URL:http://A.B.C.D/app/example.js
Request Method:GET
Request HTTP headers:
Response Headers:
Content-Encoding:gzip
Is there a way to handle case 2 when client doesn't support gzip encoding by just having compressed file in htdocs ?
I have read about inflate and deflate options. Also about Multiviews option. But I didn't find example at a directory level when the directory contains multiple types of content (javascript, css, html) in compressed format (gzip encoded).
Thanks in advance
Looks like that's what you need http://www.innerjoin.org/apache-compression/howto.html
Though I haven't tried it in any way.
Another option might be to use some script language to run decompression and respond (php, ruby, perl...)
As for performance, having both versions is the best option as it doesn't require any extra efforts.

My scripts and styles get served as text/html

Since the update to Mac OS Mavericks all my styles and scripts get served as text/html
I have no idea where I can change this behavior. I'm using the built in apache service
EDIT: I forgot to mention that static files works as expected. The files above get parsed by a php script to get served cached and compressed. I'm using header("Content-type: text/css") to define the content type
In your server/vhost config try adding:
AddType text/javascript .js
AddType text/css .css
If something else is already setting the type, you can try adding this instead:
<Files "*.js">
ForceType text/javascript
</Files>
<Files "*.css">
ForceType text/css
</Files>
After further digging into the cacheing script I found a flush() method forces PHP to add a text/html content type in the header. This happens right before I add headers like header("Content-type: text/css")
I've rewritten my class method and the output is now correct. Strange is that it doesn't cause the problem on my live server with the same cacheing class

Apache always returning js as text/plain

I have an Apache install which always returns .js files as text/plain.
I've disabled mod_negotioation, and checked the MIME is set in /etc/mime.types. I know this is the correct file, as I added application/font-woff, which is working as expected.
I've also disabled mod_pagespeed, and renamed /etc/apache2/magic to /etc/apache2/magic.disabled, even though mod_mime_magic isn't enabled.
Even adding AddType application/javascript .js to the .htaccess results in the same text/plain.
Where else can I force the type to be set?
Use the other JavaScript mime types:
AddType application/x-javascript .js
#AddType application/x-ecmascript .js
#AddType application/ecmascript .js
#AddType text/javascript .js
#AddType text/ecmascript .js
Try one at a time until you find a match.
References
RFC 4329: Scripting Media Types
Reducing MIME type security risks (Windows)