WordPress Rewrites without .htaccess

It’s been known for many years that apache’s AllowOverride .htaccess files incur a performance hit, as every node on the path from the location hit to the document root need to be checked for .htaccess files and parsed. I’ve mostly avoided the whole issue by hosting on nginx instead, but I recently needed to host WP on Apache again and ran into this issue. Many places offer a snippet like this for rewrites from a .htaccess file:

RewriteEngine On
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [NC,L]

This says:

  • If the request is for index.php, serve it as is.
  • If the request is for a file or folder that does not exist, serve index.php instead.
  • Implicitly, if the request is for a file or directory that does exist, serve that.

The problem is that while this will work in a .htaccess file, it won’t work in main apache config because REQUEST_FILENAME will just be a filename, not a whole path, so it’s unlikely to match. The solution to this is to prepend the document root:

RewriteEngine On
RewriteRule ^index.php$ - [L]
RewriteRule ^.*$ /index.php [NC,L]

This took me a silly amount of time to solve. I found the critical info in this post, but I thought I’d clarify it here. HTH!

Wifi disappointment: Ubiquiti’s AC-Lite access point

My broadband provider’s (free.fr) built-in wifi is pretty dismal – despite having a reasonably solid 26Mbit VDSL connection, my iPhone will often time out even when in the same room, and streaming video from another computer through 1 plasterboard wall often glitches, while an Ethernet connection works fine. Free’s admin software has a neat little channel scanner, and I can see that my network is the only one using these channels, so it’s not an interference problem, and my phone has no speed problems on other wifi networks I use. So I decided to spring for a new access point that would support 5GHz bands, to see if that would work better, and chose the AC-Lite model from the highly recommended Ubiquiti Networks.

I wasn’t sure if my router supported PoE, so I plugged in the AC-lite to see if would show any signs of life, but no lights came on – but none did. So I plugged in the PoE injector and plugged it in again – but still no signs of life! I replugged the PoE injector and checked the docs to ensure I had the ports connected the right way round, but still nothing. Leaving it plugged in, I started searching Ubiquiti’s support docs, but after a few minutes noticed that the lights had come on on the access point. A further test reveals that it takes quite a long time for anything to show up – it’s just slow.

While doing that, I needed to sign up for Ubiquiti’s support site at help.ubnt.com, so I did the whole email sign-up dance. I also gathered form the “Quick Start” guide that I needed to install a local copy of their management application, UniFi. So I grabbed the latest macOS version (5.6.22, at the time) and installed that. On running it, it complained it couldn’t run because “Port 8080 is used by other programs”. That is true – I run nginx on port 8080 with a port mapping from port 80 so I can run it unprivileged. After some rummaging through the help site, it tells me I need to edit the “system.properties” file and change the default port. I then need to find the system properties file. Eventually I find a reference that says it’s inside the UniFi app bundle, in UniFi.app/Contents/Resources/data, however, it’s not there. Later on I find a comment on someone else’s identical question revealing that this file is only created after you’ve run it successfully for the first time – so we have a stupid chicken & egg situation – you can only avoid a port clash by not having a port clash. So I stop nginx, relaunch UniFi, and sure enough, the system.properties file appears, so I can then quit, edit the settings and relaunch. This can’t be that unusual (given the numerous support questions asking it), and being able to set ports from the launcher would seem a basic thing to allow.

Now it lets me click the “Launch a browser to manage the network” button, which takes me to a browser page filled with warnings about invalid security settings – browsers are now much pickier about such things – and after clicking through all the warnings, it ultimately requires me to provide an admin override to allow the use of a self-signed certificate. Not pretty. It then tells me Safari isn’t supported. Sigh. So I switch to Chrome, and go through the whole set of security warnings again. None of this is mentioned in the quick start guide. I know what all this means – but I suspect many would not.

“At last”, I think, “I can get on with configuring this thing”. Fat chance. It takes me through a config wizard. As part of this it asks me to enter my login details for the Ubiquiti support site for its “cloud integration”. However, the login that I created earlier doesn’t work – after much retrying and checking, it turns out that I have to create a new account, because, obviously, help.ubnt.com and account.ubnt.com are completely different and unrelated sites ?. I noticed that the site supports 2FA, so I enabled that, though I also noticed that it does not provide any backup keys, so if you lose your authenticator (e.g. in the way that google authenticator does occasionally), you’re screwed.

Finally I get to log in, where I’m greeted with lots of greyed out areas and warnings saying “UniFi Security Gateway Required”, and “DPI data is missing”. Just what I wanted to see on my first login to this shiny new product. Requiring some other device is fine, but it doesn’t need to be so prominent that it looks like there’s something wrong.

After all that, I got everything connected. My iPhone connects over 5G, and so far it seems to be free of the network issues that led me in this direction to start with, so it worked out in the end – but it could so easily have been so much better.

Getting the modulus of an SSL public key

Getting a hash of the modulus of SSL keys and certificates is a nice simple way of making sure they match.
I’ve found lots of docs that tell you how to get the modulus of a private key, CSR or certificate, but I had trouble finding how to do the same for a public key, where the PEM-encoded file begins -----BEGIN PUBLIC KEY-----. The public key is x509, but this openssl command produces an error because it’s expecting a certificate rather than a public key:

openssl x509 -noout -modulus -in mykey.public | openssl md5
unable to load certificate
140735178354768:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:701:Expecting: TRUSTED CERTIFICATE
(stdin)= d41d4e9400998ecf8cd98f00b208427e

The solution is simply to tell it that it’s a public key with the -pubin switch:

openssl rsa -noout -modulus -pubin -in mykey.public | openssl md5
(stdin)= 6ab17b2db672280921e1c5fed6908187

(Hashes altered to protect the innocent!)

Review of “Getting Started with PhantomJS”

Review of Packt Publishing’s “Getting Started with Phantom JS” by Aries Beltran

[iframe src=”http://rcm-na.amazon-adsystem.com/e/cm?t=marcboin-20&o=1&p=8&l=as1&asins=1782164227&ref=tf_til&fc1=000000&IS2=1&lt1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr” style=”width:120px;height:240px;” scrolling=”no” marginwidth=”0″ marginheight=”0″ frameborder=”0″]

I was asked by Packt to review several books, but I chose “Getting Started with PhantomJS” because I was actually interested in it! I’ve used various faceless web browsers before, in particular webkit in GTK applications like wkhtmltopdf or with python or PHP bindings. wkhtmltopdf (and the related wkhtmltoimage) in particular has been suffering from neglect – it has lots of depedencies and it’s difficult and unreliable to build and use (something I’ve written about before). I’ve most often used server-side browsers for tasks like generating page preview images, and seeing that phantomjs will do that, I’ve long thought I’d like to know more about it so that I could get away from custom-building complicated webkit stacks.

As far as I’m concerned, the two key things that phantomjs brings are a straightforward build process (a simple ‘brew install phantomjs’ for me) and a simple way of scripting the virtual browser, with the ability to inject scripts into the page, without having to resort to peculiar tricks, messing with virtual frame buffers or installing odd browser plugins.

I hadn’t realised phantomjs’s own scripting environment was quite so complete, supporting commonJS module integration. The separation between browser and page contexts (using `evaluate`) is clean and easy to get to grips with, and the book presents this well.

The book mentions several extensions to phantomjs that I had not encountered and look useful (particularly casper).

I hadn’t spent much time reading phantomjs’s own docs, but when I looked at them I found that they are very limited. Even though it’s not long, the book goes deeper into examples and explanations than the docs, so there is genuine value in having the book.

All of the example code I tried worked without a hitch. Packt’s web site sets a wrong MIME type on zip downloads, resulting in a page full of rubbish, but it unzips ok when saved manually. There are more example files than are mentioned in the book, which is a welcome bonus.

One small error I spotted suggested using single quotes around JSON values – that’s not valid JSON, though it is valid Javascript. It also mischaracterises JSON slightly – object syntax is part of the Javascript language, so it’s not a separate thing when you’re already in a Javascript context.

One formatting issue costs a little typing – while all the code samples are provided as text and in files, all the displayed command lines (for example when a long URL is passed as a param) are in images, so you can’t copy and paste commands as text. Call me lazy!

The English is generally good, concise and to the point. This is not a long book, but it doesn’t need to be as a “getting started” guide on something that is a pretty confined subject. The editing had a few holes – several typos had sneaked through, things that would have been caught by any spell checker. The code samples had been updated recently, but there were no errata. Oddly, getting to errata is annoying on Packt’s site – when you’re looking at a book’s page there is no link for it. You have to go to the “code and errata page” and select the book from the pop-up menu. This menu is sorted by the exact book title (and contains ALL their book titles!), so I had to look under ‘getting…’ rather than ‘phantomjs’. This could be made much easier.

There are several other books and resources for learning and using phantomjs, and they may be sufficient for some users as it is a fairly small subject to cover. Overall I was impressed with the book. It does exactly what the title says, provides useful links for further reading, and provides effective, useful scripts that cover much of what many will want phantomjs to do in sufficient detail to make it easy to derive your own. Well done Aries!