Using .htaccess to serve static files via a subdomain - performance

Right, excuse my stupidity, I've looked through a load of examples on t'interweb but I don't think I've found what I'm looking for.
I have a website, photography.example.com is the main site but I also want to have another subdomain to serve static files, for example static.photography.example.com.
If I request a file (e.g. http://static.photography.example.com/js/jquery.js) I want that file to be retrieved from the non-static domain, allowing me to keep my file structure completely untouched but using multiple domains to allow more concurrent http requests.
I don't want to throw any http responses that would make the browser thing the file has been moved, I just want to mirror the files from the normal domain to the static domain. After this I would proceed to set far future expired to improve caching etc.
How do I achieve this using .htaccess?
EDIT 1
So after a bit of messing around I have come up with this:
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^(.*)$ http://photography.example.com/$1 [L]
But this actually redirects to the domain I'm trying to read, I want it to serve the file up under the static domain name, any help with modifying this script would be greatly appreciated.
EDIT 2
So I've amended my DNS and waited a few days for it to propagate but the CNAME technique doesn't work either. Here's the entry:

In your question, you're talking about:
Adding Expire headers for caching
Splitting resources across domains
For Item #1, you can edit your httpd.conf/.htaccess file on your main domain (it doesn't hurt doing it on your whole website, no?)
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType application/x-javascript A2592000
ExpiresByType image/gif A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/png A2592000
</IfModule>
Item #2 doesn't need any Apache configuration - just configure your static.photography.example.com DNS entry with CNAME photography.example.com. That should do the trick.
Or you can edit your httpd.conf and add a ServerAlias
<VirtualHost xx.xxx.xxx.xx:80>
DocumentRoot /
ServerName photography.example.com
ServerAlias static.photography.example.com
</VirtualHost>
So for now, you don't need a separate virtual host with dedicated Apache configuration.
Here are a few other reasons why you'd want a separate domain, and a separate virtual host with dedicated configuration:
Your main domain has cookies and you want to use a cookie-free domain
You actually want to use a CDN (or your Amazon S3 account to reduce bandwith on your primary hosting)
If you want one of those, or if your caching needs are too complex (you don't want to cache all JS/CSS/images, but rather a subset of it), then your only solution is: get your hands on your httpd.conf and write separate configurations for each domain

My understanding to the question is to REDIRECT
http://static.photography.example.com/js/jquery.js
to get the file from following address (without changing the URL on the browser):
http://photography.example.com/js/jquery.js
But keep URL to all existing files like the following to NOT REDIRECTED:
http://static.photography.example.com/images.jpg
If it is true then this .htaccess should work:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(.*)?.photography.example.com$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) http://photography.example.com/$1 [P]
Moreover you can also use MAPPING if you have a complex rules like:
RewriteRule ^/file1\.js$ http://photography.example.com/file.js?q=444 [P]
RewriteRule ^/file2\.js$ http://photography.example.com/file.js?q=345 [P]
RewriteRule ^/file3\.js$ http://photography.example.com/file.js?q=999 [P]
create a text document (e.g. map.txt) in the folder with .htaccess and put in the following:
file1 444
file2 345
file3 999
The .htaccess will have the following look:
# Set a variable ("map") to access map.txt from config
RewriteMap map txt:map.txt
# Use tolower function to convert string to lowercase
RewriteMap lower int:tolower
# Get requested file name
RewriteCond %{REQUEST_URI} ^/([^/.]+)\.js$ [NC]
# Seek file name in map-file
RewriteCond ${map:${lower:%1}|NOT_FOUND} !NOT_FOUND
# Perform rewriting if the record was found in map-file
RewriteRule .? http://photography.example.com/file.js?q=${map:${lower:%1}} [P]

I think you would need the CNAME record to pass the request for static.photography.example.com to your server and the have .htaccess parse requests for static.photography.example.com in a special manner.
Adding the following rewrite rule to .htaccess should do the trick
RewriteCond %{HTTP_HOST} !^(www\.)?photography.example.com$ [NC]

Related

Use both subdomains and subdirectories in Magento multistore?

I currently have a store in Magento with several store views for different languages as example.com/sv/, example.com/fi/ etc. Now I want to add a store to a subdomain as test.example.com but I can't make it work.
I added a new store and a new store view for the subdomain and then changed the Base URL for this. I have created the subdomain and it points to the location of the magento installation. I have also added different lines in the .htaccess file, tried some variations of the ones below.
SetEnvIf Host .*newstore.* MAGE_RUN_CODE=newstore
SetEnvIf Host .*newstore.* MAGE_RUN_TYPE=website
RewriteCond %{HTTP_HOST} .*newstore\.com [NC]
RewriteRule .* - [E=MAGE_RUN_CODE:newstore]
RewriteCond %{HTTP_HOST} .*newstore\.com [NC]
RewriteRule .* - [E=MAGE_RUN_TYPE:website]
But nothing works. When I try to access the subdomain I get redirected to the main store. But I can access the new store as a subdirectory, it's supposed to be like this test.example.com but I have to write example.com/test.
Is what I want to do even possible?
Update 15-04-09
I found a redirect in the .htaccess file that caused the subdomain to be redirected to the main store. I removed it and now I can access the subdomain but the page is just white and it says "Index of /" etc. so I don't get the magento store view.
I use this code in my .htaccess that does what you want:
SetEnvIfNoCase Host "^it\.mystore\.com$" MAGE_RUN_TYPE=website MAGE_RUN_CODE=ws_it
SetEnvIfNoCase Host "^pt\.mystore\.com$" MAGE_RUN_TYPE=website MAGE_RUN_CODE=ws_pt
SetEnvIfNoCase Host "^fr\.mystore\.be$" MAGE_RUN_TYPE=store MAGE_RUN_CODE=fr_be
SetEnvIfNoCase Host "^nl\.mystore\.be$" MAGE_RUN_TYPE=store MAGE_RUN_CODE=nl_be
Also make sure you have properly defined the Base URL (in your example: test.example.com) in System > Configuration > General Web > Secure and Unsecure for your new website or store

Laravel pretty URL

I'm going crazy here! I'm trying to learn Laravel and pretty URLs just don't work.
I have enabled mod_rewrite from my apache config file, I have set AllowOverride to All in my user config file and I have the following in my .htaccess file in public folder of Laravel installation:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [L]
I enter http://localhost/~user/lara/public/index.php/users it works, but with http://localhost/~user/lara/public/users I get 404 Not Found error
The requested URL /Users/user/Sites/lara/public/index.php/users was not found on this server.
You can see that the redirection works fine, as public/users have turned into public/index.php/users but it says not found, even though when I manually enter public/index.php/users it show me the output.
I have read all the related questions on SO, none of the worked for me!
This is most likely caused by the fact that you are changing the document root during a request. From the looks of your URL (with the ~user segment) you are using mod_userdir or something similar, and what these types of plugins do it allow you to map a given URL prefix to a document root that is not the normal one for the server.
As such, you sometimes run into issues like this where the right .htaccess file is found, but its rewritten URL is against the original document root rather than the modified one and so your index.php file cannot be found (maybe, to be honest I don't really know, this is all conjecture). This is also why going directly to index.php/users works - the problem isn't the setup per se, but the mixing of rewrite rules and the change of the document root.
As such, the fix is to use a RewriteBase line, ad the following to the .htccess file:
RewriteBase /~user/lara/public/

mod_rewrite to shorten url files path

I am having a bit of difficulty getting mod_rewrite to do what I need it to do.
We have a group of virtual subdomains in a Drupal install. So, academics.univ.edu, about.univ.edu, etc are all part of the same core Drupal install.
File access currently is academics.univ.edu/sites/all/academics/files/myfile.jpg. However this path will also work as about.univ.edu/sitse/all/about/files/myfile.jpg or any other valid subdomain.
We'd like to use mod_rewrite to accept academics.univ.edu/files/myfile.jpg and deliver the file from the above location.
Here's what I've tried:
RewriteCond %{REQUEST_URI} ^(about|academics|bursar|calendar)\.univ\.edu\/files\/(.*)$ [NC]
RewriteRule ^/sites/all/files/$1/$2 [L,NC]
I'm probably going about this the wrong way, but I wanted to check on it. I can get the subdomains to work by making separate rules using HTTP_HOST, but I wanted less rules in the file. Also, I can't get HTTP_HOST to work on sites that exist as a subdirectory in a subdomian. For instance, undergrad.univ.edu/biology/files/myfile.jpg should deliver /sites/all/biology/files/myfile.jpg
You can't match a host in the %{REQUEST_URI}, you need to use %{HTTP_HOST}, then use the %1 backrefernce to access that match. The actual URI can be matched in the rule itself. Something like this:
RewriteCond %{HTTP_HOST} ^(about|academics|bursar|calendar)\.univ\.edu$ [NC]
RewriteRule ^files/(.*)$ /sites/all/files/%1/%2 [L,NC]
The %1 references the match (about|academics|bursar|calendar) in the RewriteCond and the $1 references the match (.*) in the RewriteRule. So that example will take a request to http://about.univ.edu/files/foo.html and rewrite the request to /sites/all/files/about/foo.html.
Also, if this is in a virtualhost or server config, you need a "/" in between "^" and "files" in the RewriteRule.

mod_rewrite: directing a domain into a subfolder (without vhost)

I have two domains that are aliases, domain1.com and domain2.com
Currently they are both directed into the same place, the root of my web space. However, I wish to separate them into independent pages and direct domain2.com into a subfolder with different content.
I understand that the correct way to do this is using Apache Virtual Hosts. However, my service provider does not allow me access to that functionality so I'll have to solve it using mod_rewrite.
What I need is something that directs www.domain2.com and domain2.com to subfolder/ (which should trigger index.php). Also, www.domain2.com/file.txt should go to subfolder/file.txt, etc... This is what I came up with:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} domain2\.com [NC]
RewriteRule ^(.*)$ subfolder/$1 [L]
</IfModule>
However, when I run it and go to domain2.com, I get 500 Internal Server Error and the log file says:
Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
To test what's going on I made a small php script that prints out the string that it gets.
I also modified the rule:
RewriteRule ^(.*)$ subfolder/test.php?string=$1 [L]
Now when I go to domain2.com or domain2.com/asd, it prints out: subfolder/test.php
Somehow it gets into recursion and prints itself. Whereas, if I use the following rule:
RewriteRule ^abc(.*)$ subfolder/test.php?string=$1 [L]
Then domain2.com/abcdef prints: def
I can't figure out what I'm doing wrong. Do you have any suggestions?
Thanks!
It could be that the rewrite rule applies to subfolders of the one whose .htaccess it appears in. Does it help to add a condition that blocks the rewrite for URLs that already start with subfolder/?

mod_rewrite positioning and wording

I renamed about 50 pages of my website. I want to make an internal rewrite from the old pages to the new pages. This is the example that Apache gives.
RewriteEngine on
RewriteBase /~quux/
RewriteRule ^foo\.html$ bar.html
I am not sure if I need the rewriteBase /. I have only individual webpages (no subs).
I understand the terms "foo" and "bar" and "quux" are universal words for examples. If I have only one domain on this server, and the rewrite rule will apply to the root directory, do I need to include rewriteBase /, rewriteBase /~quux/, or do I even need rewriteBase?
I assume that when using rewriteBase /~quux/, the actual subdirectory is inserted were /~quux/ is. Even though I don't have subdirectories, is this correct?
Can someone please arrange the correct script illustrated above?
Also, I understand that this script would be placed BEFORE other .htaccess directives, such as non-www to www and index to /. Is this correct?
RewriteEngine on
Options +FollowSymLinks
#rewrite old to new pages internaly
RewriteBase /~quux/
RewriteRule ^foo\.html$ bar.html
#non-www to www
RewriteCond
RewriteRule ...
#index to /
RewriteCond
RewriteRule ...
RewriteBase:
If your page is like:
http://mydomain.com/subdir/index.html
and your .htaccess file is in subdir/, then you need to set it:
RewriteBase /subdir/
This lets you make your rules ignore the subdirectory, so
RewriteRule ^old_index.html$ new_index.html
would redirect subdir/old_index.html to subdir/new_index.html
Positioning:
The positioning of the rules only matter if you are not using the [L] flag after your rules. This modifier tells mod_rewrite to stop rewriting and make the redirect. Not using it will let the rewrite engine do everything it can with your url in one go. So if your url is like this:
http://mydomain.com/old_index.html
It will be converted to
http://www.mydomain.com/new_index.html
No matter which rule comes first, the one that adds the www. or the one that points to the new pages. But if there is an [L] flag, then it may be done in 2 redirects.

Resources