.htaccess redirects based on date and time

A useful trick for implementing maintenance windows and redirects without having to use a php or similar script is to check date and time in .htaccess files or use it to build a redirect url.

Date and time values in .htaccess come in the form %{TIME_XXXX} where XXXX is the type of date or time you want.

So if you want to redirect a generic url to one which contains today’s date, you might use:

RewriteRule ^posts/today$ /posts/%{TIME_YEAR}-%{TIME_MON}-%{TIME_DAY}

That would result in /posts/today being redirected to something like /posts/2015-08-27

If you wanted redirect a page after a date (and time) is passed you could use something like the following, where if the date and time is passed 9am on 27th August 2015 the redirect will happen. We use a simple number comparison of turning the date into an integer and then comparing it.

RewriteCond %{TIME_YEAR}%{TIME_MON}%{TIME_DAY}%{TIME_HOUR} >2015082709
RewriteRule ^$ /destination/url.html [R=301,L]

The following would only redirect until a specific time (10.22am on 27th August 2015)

RewriteCond %{TIME_YEAR}%{TIME_MON}%{TIME_DAY}%{TIME_HOUR}%{TIME_MIN} <201508271022
RewriteRule ^$ /destination/url.html [R=301,L]

The following would only redirect between two specific dates (20th July 2015 and 27th August 2015)

RewriteCond %{TIME_YEAR}%{TIME_MON}%{TIME_DAY} <20150828
RewriteCond %{TIME_YEAR}%{TIME_MON}%{TIME_DAY} >20150719
RewriteRule ^$ /destination/url.html [R=301,L]

The options you have for %{TIME_XXXX} values are:

TIME_YEAR // current four-digit year
TIME_MON // current month
TIME_DAY // current day of month
TIME_HOUR // current hour (24 hour clock) of day
TIME_MIN // current minute of hour
TIME_SEC // current second of minute
TIME_WDAY // current week-day
TIME // a formatted string representing the date and time down to seconds. e.g. 20150827112234

Fix apache after upgrading to Mountain Lion

Every time I upgrade OS X something breaks with apache or php or both.

The steps for me to fix it this time was…

* Open your httpd.conf file
* uncomment the Load php5 module
* uncomment the load vhosts module

in etc/apache2/users

* duplicate Guest.conf to harrybailey.conf – replace harrybailey with your username obviously
* edit harrybailey.conf to read:

<Directory "/Users/harrybailey/Sites/">
    Options Indexes MultiViews
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>

Note: as Michal mentions below you may want to add +FollowSymLinks to your options too. This allows the system to follow any symbolic links you have set up.

AGAIN – replace harrybailey with your username.

* save the file

You may also get a php error which includes…

“It is not safe to rely on the system’s timezone settings”

The fix for that is
* navigate to /etc/ and rename php.ini.default to php.ini
* edit your new php.ini file – find “;date.timezone = ” (no brackets)
* update it to read “date.timezone = Europe/London” (no brackets) – if you aren’t on GMT then find your relevant timezone string and use that
* save the file

* open terminal
* submit the line:
sudo apachectl restart

That did it for me. Hopefully it will do it for you too.

I was first seeing the default html file in the /Library/Webserver/Documents folder
I was then seeing 403 errors for all vhosts that I has setup
Personally I saw these problems after upgrading from Lion (10.7) to Mountain Lion (10.8)

Move your Sites folder in OS X with a SymLink NOT an Alias

Two hours of my life were wasted on this one, even though I’ve done it before. So…

If you want to move your ~/Sites folder into say Dropbox or AeroFS or Google Drive or SkyDrive and then you still want to point to it from its default location don’t use an alias.

I know an alias is only a ctrl-click away, but it means all sorts of pain.

Instead, move the folder to dropbox by dragging it (yes you can do this), then open Terminal and type:

ln -s ~/Dropbox/Sites ~/Sites

Replace Dropbox with whatever the folder of your service is called.

Restart Apache either by restarting Web Sharing in System Preference -> Sharing or by using Terminal and typing:

apachectl graceful

Cross your fingers and open a virtual host in your web browser. I fought with an Alias and all sorts of folder settings and httpd.conf lines to try and get it working, and then all I needed was to use a SymLink in its place.

Don’t worry about no longer having a ‘real’ ~/Sites folder. You don’t actually need one.

Cheers to James Galley, my desk neighbour for helping my brain to click on this one.

Getting Apache 2 to play nice with Virtual Hosts

If you’re a web developer and you can only get the first Virtual Host to work in your new Apache 2 local setup, it’s very simple to resolve.

Thanks to Alex King for the solution to fix Apache 2 only serving the first virtual host.

Basically the NameVirtualHost must match the value you use in your virtual host declaration, be it *, 1.2.3.4 or example.local

NameVirtualHost *
<VirtualHost *>
</VirtualHost>

You get the gist.