.htaccess forward local to remote on 404 - regex

I do all of my development locally on sites that use a CMS. We have a directory that is used to store user-uploaded content, such as images (/assets/). The problem is, when developing locally, I don't want all of the uploaded files from the production site on my machine, so I leave this directory empty, and all of the HTTP requests for files in the /assets/ directory get 404'ed.
What would be great is if I could have a rewrite rule in my .htaccess that detects the 404, and forwards to the external URL of the production site to load the asset from there. The logic would be:
Request localhost/somesite/assets/foo.jpg
200 response ? send the local file /somesite/assets/foo.jpg
404 ? forward to http://www.productionsite.com/assets/foo.jpg
Is this possible?

Have your .htaccess rules like this:
Options +FollowSymlinks -MultiViews
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(assets/.*)$ http://www.productionsite.com/$1 [R,L,NC]
This will make sure that any request matching /assets/ and doesn't already exist on your local webserver will be externally redirected to http://www.productionsite.com/assets/...
btw you should really improve your acceptance rate otherwise you may not many answers here.

Is /assets always on another site, or only if the files are not available locally?
The reason I ask is that it may be simpler to always redirect just /assets to the live with the following (untested) rules in httpd.conf/.htaccess on your development server:
Options +FollowSymLinks
RewriteEngine on
RewriteCond $1 ^(assets) [NC]
RewriteRule ^(.*)$ http://www.livesite.com/$1 [L]

Related

Apache redirect keeping URL

I'm making a JavaScript web app running on an Apache 2 server. I'm wondering if it's possible (either with mod_rewrite or some other mod) to make any path you type load the index.html from the root path, but keeping the URL?
For example: "example.com/blah/blegh" will load "example.com/index.html", but the address bar will still have "example.com/blah/blegh". Same if you tried typing "example.com/everything/is/index" would still load "example.com/index.html" and have "example.com/everything/is/index" in the address bar.
A simple answer about any mods I would need to use and which commands might be best would suffice. Though a code example would be very useful since I'm new to regex's and Apache rewriting.
Thank you for your time :)
Note: I'm doing this since I'm using History.js to parse URLs/titles into the address bar and tab titles while navigating (a one-page dynamic site). I'd like to be able to just load up the root index.html with the user's initial URL request and respond to users' actions that way much like a REST server.
Actually, you want to rewrite without redirecting. This requires enabling mod_proxy and mod_rewrite in Apache's httpd.conf.
Then, the rewrite should look like this:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.html [NC,L,QSA]
Reference:
What exactly does the Multiviews options in .htaccess?
htaccess rewrite without redirect
Apache: RewriteRule Flags

I want to redirect example.com/chapter-foo.php to example.com/chapter.php

I have a site with some pages like that:
example.com/dogs-foo1.php
example.com/dogs-foo2.php
example.com/dogs-foo3.php
And then
example.com/cats-foo1.php
example.com/cats-foo2.php
example.com/cats-foo3.php
Now I have simplified the site with tab menus and I only have
example.com/dogs.php
example.com/cats.php
Now I want the people who try to go to: example.com/cats-foo1.php
be redirected to: example.com/cats.php
instead of getting a 404
Is there anyway, maybe with htaccess?
This probably is what you are looking for:
RewriteEngine on
RewriteRule ^/?cats-.+.php$ /cats.php [R=301]
For this to work you will need to enable the rewriting module into your http server. You should place it in the http servers host configuration. If you decide to use a dynamic configuration files instead (.htaccess) you need to enable their interpretation first (see the AllowOverride directive in the official documentation).
I would recommend however to go a step further and use URLs along the pattern https://example.com/cats, so without the trailing .php as is the standard these days. You need some additional internal rewrite rule for that:
RewriteEngine on
# external redirect from /cats-foo.php to /cats
RewriteRule ^/?cats-.+\.php$ /cats [R=301]
RewriteRule ^/?cats\.php$ /cats [R=301]
# internal rewrite
RewriteRule ^/?cat$ /cats.php [END]
This again can be generalized:
RewriteEngine on
# external redirect from /cats-foo.php to /cats
RewriteRule ^/?(\w+])-.+.php$ /$1 [R=301]
# internal rewrite
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(\w+])$ /$1.php [END]
If you experience a http status 500 with that rule in place chances are you operate a very old version of the apache http server. You will find entries in your http servers error log files complaining about the END flag. In that case replace it with the L flag and try again.
You probably will have to adjust those line, we don't know your specific situation. But the above should get you started along with reading the documentation of the tools you use, which you can start here: http://httpd.apache.org/docs/current/mod/mod_rewrite.html
And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

Apache Rewrite for images on subdomain

I have a webserver and a subdomain. All of my images are stored in /public/images within my site directory for www.mysite.com. However I have a separate site directory for testing beta.mysite.com however on this page with a different git branch all of my images are broken because I did not want to copy all of the images. Is it possible to say for all image requests or for all 404 requests try looking at mysite.com?
I have found an example on another questions
RewriteEngine On
RewriteCond %{HTTP_HOST} ^test.example.com$
RewriteRule ^images/(.*)$ http://example.com/sub_ds/test/images/$1
But since I am rather new to mod_rewrite im not sure what is going on or how to manipulate it to work for me.
You can use this rule in root .htaccess of beta subdomain:
RewriteEngine On
RewriteCond %{HTTP_HOST} =beta.example.com
RewriteRule ^(images/.+)$ http://example.com//public/$1 [L,NC,R=301]

Redirect all requests to index.php except subdomains

I'm using AltoRouter: (http://altorouter.com/) and I modified .htaccess as suggested in the instalation to:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
This is so that index.php can handle all the requests. My problem is that I am using addon domains in cpanel and I am having internal server errors when I try to access one of the domains associated with the addon domain.
Example:
My main domain is mainsite.com.
Then I have several sites:
site1.com that cpanel automatically associates with site1.mainsite.com and creates a folder mainsite.com/site1.com. So if I access site1.com I would see in browser site1.com but the content delivered would be the one inside the mainsite.com/site.com folder.
This works if I don't use the .htaccess rule but I need it for routing. If I have that rule I get internal server errors everytime I access site1.com (I assume that it's a conflict between cpanel rules and .htaccess).
How can I modify the rule so that it only affects maindomain and not subdomains? I am assuming that by doing this there would be no conflict and my problem would be solved.
I am really bad at .htaccess and regex but I am willing to learn if needed. I would still appreciate if you could point me to the right direction. (both in the idea and in good websites that can help me understanding this)
How can I modify the rule so that it only affects maindomain and not subdomains?
You can add a new condition based on host name:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(?:www\.)?mainsite\.com$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]

Redirect from old site on Wordpress to Codeigniter. Domain remain same

I'm preparing for migration from WordPress to site written via Codeigniter. I use htaccess very seldom, and never redirection.
My site is working now and clients visit my site. And I cannot just upload new site.
So I tried to practise with one page for redirection to another created for testing. I tried with encoded and decoded URL but without success; however, as written in the manual, it should be a simple:
Redirect [status] URL-path URL
.htaccess:
RewriteEngine On
Redirect 301 /?wpsc-product=подвеска-сова-медь-duplicate http://domain.com/?page_id=851
Also, Apache has RedirectMatch and RewriteRule [301] and they are loading server, so I prefer to use simple redirects (I have CPU load limitation on my hosting).
I have about 500 links.
Redirect OR RedirectMatch directive from mod_alias cannot match query string. You must use mod_rewrite like this:
RewriteEngine On
RewriteCond %{QUERY_STRING} wpsc-product=подвеска-сова-медь-duplicate [NC]
RewriteRule ^/?$ http://domain.com/?page_id=851 [L,R=301,B]
Make sure to keep this rules on top of your .htaccess.
Reference: Apache mod_rewrite Introduction