htaccess mojo

From: CHYRON (DSMITHHFX) 1 Sep 2015 20:38
To: ALL1 of 50
I want a rewrite rule for a new website to redirect all [old] urls to index page. Got this offa stack overflow:

RewriteEngine on
RewriteCond %{REQUEST_URI} !^/index.html$
RewriteCond %{REQUEST_URI} !\.(gif|jpe?g|png|css|js|pdf)$
RewriteRule .* /index.html [L,R=302]

I dunno if the shared remote host has mod rewrite enabled (I only have ftp access), but when I put that up the server throws an error.

May I therefore assume that mod rewrite is enabled, but the htaccess code given is defective?
From: Peter (BOUGHTONP) 1 Sep 2015 21:20
To: CHYRON (DSMITHHFX) 2 of 50
Ditch the existing conditions and use:
	RewriteCond %{REQUEST_URI} !-f

Which confirms the request is not for a file (you can do !-d to exclude directories). Much simpler than faffing with extensions.

The default for R is 302 already (so just [L,R] will do), but you possibly want 301 (permanent change) instead (although also best to wait until the rule works before doing that, to prevent browsers being annoying.)

If that still errors, see if you've got a log file giving any messages (might be mod_rewrite specific or in the Apache-wide error_log) - nothing is jumping out at me, but I am tired enough to potentially miss something obvious.

EDITED: 1 Sep 2015 21:20 by BOUGHTONP
From: CHYRON (DSMITHHFX) 1 Sep 2015 22:29
To: Peter (BOUGHTONP) 3 of 50
Thanks Peter. I'll give it a whirl tomorrow. If that works, I need to essay something fancier:

something.html to index.html#something (the old pages have been converted to includes, using original file names)
EDITED: 1 Sep 2015 22:30 by DSMITHHFX
From: CHYRON (DSMITHHFX) 2 Sep 2015 15:42
To: ALL4 of 50
OK I got it working using this:
 
Code: 
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !^/index.html$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
And I (then) got it appending the url as a hash (replacing last line above):
Code: 
RewriteRule ^(.+)\.html?$ /index.html#$1 [R,L,NE]
This is on a staging server root, not sure if it's going to work on shared hosting though.

For my next trick(s), I need to work out how to update the hash to reflect ensuing ajax content changes, and maybe the history. :-&
EDITED: 2 Sep 2015 15:43 by DSMITHHFX
From: Peter (BOUGHTONP) 2 Sep 2015 22:02
To: CHYRON (DSMITHHFX) 5 of 50
That first condition is redundant if index.html exists (the -f will get it), but if you want to do it as a safety/sanity check, I tend to do so as a distinct rule, like so:
RewriteRule ^index\.html                 -  [L]
RewriteRule ^(favicon\.ico|robots\.txt)$ -  [L]

Where the hyphen says "don't rewrite it".

The reason for having distinct rules being both readability and because despite being written first the rewrite conditions are checked after the first part of the RewriteRule is tested - so it feels better having distinct rules. (There'll be a (probably very minor) performance benefit too.)


I've not had problems with ErrorDocument - it is necessary to set it with cPanel, but all I do is this:

ErrorDocument 404 default
ErrorDocument 403 default
ErrorDocument 410 default
ErrorDocument 500 default

Don't remember if the order is relevant, but I have them after the RewriteEngine On line but before any rules are listed.


HTML5 History stuff is piss easy - just use this: https://github.com/browserstate/history.js/

There should be enough docs/examples/etc there to get it going, but I can probably answer questions if it misses anything.

From: Matt 3 Sep 2015 05:34
To: ALL6 of 50
People still use Apache? Oh.
From: ANT_THOMAS 3 Sep 2015 06:10
To: Matt 7 of 50
Meow (cat)
From: CHYRON (DSMITHHFX) 3 Sep 2015 09:38
To: Matt 8 of 50
Me to client: 'Why is your small, retail professional services web site that probably gets a half-dozen visits on a good day running on an apache server?'

Client: 'Huh?'
From: Matt 3 Sep 2015 12:04
To: CHYRON (DSMITHHFX) 9 of 50
You should have said, "I can make your web site go faster"
From: CHYRON (DSMITHHFX) 3 Sep 2015 12:11
To: Matt 10 of 50
 (fail)
EDITED: 3 Sep 2015 12:15 by DSMITHHFX
From: CHYRON (DSMITHHFX) 3 Sep 2015 12:21
To: Peter (BOUGHTONP) 11 of 50
I'm looking at the history.js, but it may be overkill and I'm reluctant to pile on another library. Anyhoo I may end up going down that road.

The tricky(er) part I've encountered is needing to do two seperate things: rewrite mydomain.com/ to mydomain.com/index.html (so ensuing ajax calls are bookmarkable), and mydomain.com/something.html --> mydomain.com/index.html#something

Simply chaining:
Code: 
RewriteRule ^(.+)\.html?$ /index.html#$1 [R,L,NE]
RewriteRule ^$ /index.html [R,L]

throws it into a loop.
-----

Edit: hmmm, nope. After fixing a misplaced [L] flag, the htaccess seems to be working fine*. The loop was being caused by a js $.get statement which fails spectacularly (and mysteriously) if an include can't be found, in this case due to a misconfigured path, by 'get-ting' the entire index page instead, even though I was using a jqXHR .fail statement that works fine in other .get instances in my script. I managed to work out a kludge:

Code: 
if ( !data.match(/^<DOCTYPE/) ) { [do the good stuffs] } else { FOAD }

*on my staging server...

EDITED: 3 Sep 2015 16:46 by DSMITHHFX
From: Peter (BOUGHTONP) 5 Sep 2015 14:49
To: CHYRON (DSMITHHFX) 12 of 50

The good thing about history.js is that it plugs in to several common libraries, but also has a native adapter.


Another workaround, if you're receiving a full page instead of a segment, is to pull out the html from the main content div, along the lines of:

if ( data.match(/^i) )
	data = $('div#content',data).html();

Not sure if it applies for your situation, but still a useful thing to keep in mind.

From: Peter (BOUGHTONP) 5 Sep 2015 15:01
To: Matt 13 of 50
(fail)

More people use Apache then every other web server combined, and it has over twice the usage of the second most common server.

IF nginx continues to gain use at its current rate, it'll be 2020 before it has equal share to Apache.

From: CHYRON (DSMITHHFX) 5 Sep 2015 15:35
To: Peter (BOUGHTONP) 14 of 50
I started out with a popstate listener which works fine except (I discovered) in IE11, so I switched it to hashchange, which seems to work equally well in all, relatively current browsers. So I guess I won't be needing history.js. Anyhoo, Tuesday I'll find out if my htaccess works on the client's server (it does have mod rewrite enabled).
From: Matt 6 Sep 2015 07:14
To: Peter (BOUGHTONP) 15 of 50
I bet more people use Apache because somebody or something installed it for them and they are still using it and they don't know any better. That doesn't make it the best web server (for their needs).

Apache was the definitely the best at one time, but that was when there was nothing else worthwhile installing.
From: ANT_THOMAS 6 Sep 2015 08:03
To: Matt 16 of 50
What makes nginx better apart from speed and resource handling?
From: Matt 6 Sep 2015 09:06
To: ANT_THOMAS 17 of 50
It's not just a webserver, its also a really clever proxy server. You can use it to proxy anything (not just http, but any kind of tcp), from a frontend to a backend service really easily.

More importantly, it is asynchronous / event driven using 1 thread per CPU (core) , rather than using multiple threads/processes to handle responding to individual clients like Apache does, so it scales a lot better as well as being quicker.

Its not difficult to learn either, despite the nay sayers. The configuration format is different, but easier to learn than Apache's.
From: ANT_THOMAS 6 Sep 2015 09:15
To: Matt 18 of 50
Good explanation. I currently use nginx on my RPis where required and Apache on my proper server(s). But they're not doing anything interesting, it was more a case of having used WAMP previously so I went with Apache when I moved my server to Ubuntu.

I only discovered how to use Proxies with Apache quite recently, really great idea in general. Passing specific subdomain requests to other servers seamlessly.
From: CHYRON (DSMITHHFX) 6 Sep 2015 14:02
To: Matt 19 of 50
Apache gets the job done, and it's pretty much on all our client's low-cost shared web hosts. I never recommend that clients change their hosting, unless they are having major issues or our proposed solution can't work on it, then it's usually just to switch from IIS to Linux +apache (because those are the choices).

Maybe in future I'll be in a position to provision a more performant solution, where that's a requirement, and I'll consider the alternatives more carefully. I did install lighttpd on a virtual server recently and it was easier to bring up, and (seemingly) speedier than apache. But it doesn't appear to be available on any shared providers, so...

Thing is, since apache really is so widely used then going 'off the reservation', so to speak, could create problems for anyone who eventually inherits the server admin. So there's that.

Other thing I'm pondering is where containerization is going to take this whole business. I took a spin at it a few months ago, and it appears to be more geared to large-scale hosting providers.
From: Matt 6 Sep 2015 14:19
To: CHYRON (DSMITHHFX) 20 of 50
Nginx has been available in Debian since 5.0 (I think) and Ubuntu since at least 12.04 and I'm sure the same is true of Redhat and other distros, so it's hardly going off reservation anymore. Installing and upgrading it is now no more difficult than installing Apache.

As long as you have free reign to install packages I would totally encourage you try it out and see what it can offer.