Jamie Balfour

Welcome to my personal website.

Find out more about me, my personal projects, reviews, courses and much more here.

Jamie Balfour'sPersonal blog

CloudFlare is a content delivery network (CDN) that makes delivery of your website much faster and much more secure. It's great and it definetly took a lot of the demand away from my shared server. On top of that, it meant that when the server my website is hosted on went down it was there to step in a display static content from the cached version of my website that it had.

I've enjoyed CloudFlare for the last two or three years and found it to be the most valuable tool used with my website. But now I've been contemplating it's use. For four or five months I've been trying to get SSL (TLS nowadays) to work on my website and to display that HTTPS padlock on the client's browser when they visit my website. I bought a certificate for £13 in February but due to unforeseen circumstances I did not manage to get round to installing it until about April or May. When it was installed it did not work so I went straight to my web host's customer service team to get them to investigate. After four or five times getting in touch and being told it was installed several times, I though that there must be something wrong with this. At first I assumed the dedicated IP was the problem. Then realised something else.

A little explanation of how CloudFlare works

Overview of CloudFlare

How CloudFlare works

CloudFlare acts like the man in the middle, protecting your website and sending information to the people who are expecting it. It's a great idea and it works well. But one of the key concepts of SSL is this:

You are connecting to the website that holds the certificate and that you are not connecting to some other website instead.

In other words when you initiate a connection to jamiebalfour.scot, you are expecting jamiebalfour.scot. Not jamiebalfour.cloudflare.com or something. The man in the middle could be perceived by the browser as being a man in the middle attack but really it is just CloudFlare's CDN trying to send the data. So what happens next? The browser in turn says the SSL certificate is invalid or the website that is trying to be reached is not the one that is coming in to the browser (in this case it will be CloudFlare's website that is coming in). This in turn means that the browser dismisses the website claiming it to be fraudulent. 

The result

You simply cannot have a HTTPS website and CloudFlare unless you pay for a custom certificate from them. This causes problems with my website which is now using HTTPS. I have decided to leave out CloudFlare, at least for the next few months and I will be trying to rectify this problem from time to time in the hope that I can fix it so from time to time you may get SSL errors. I will say that my website performs reasonably well under general use without CloudFlare's assistance, but it does add a lot of security improvements as well as taking a considerable chunk of the stress from my origin server, but for the next few months my website will continue without it.

Posted in Web Development
ssl
tls
update
cloudflare
problems
content
delivery
network
cdn

I spend a lot more of my time developing the front end than the back end of my website since the back end is pretty damn flawless as it is. I say this because I was originally more of a back end web developer - and I probably say this to many peoples' suprise but it's actually true that I still am. I prefer working on the front end sure, but the back end is really where I am more talented.

Effectively combining the front and back end is about ensuring that the back end stuff works with the front end stuff, but your front end needs may be quite high. For instance, iterating 1000 records on your local database is not going to be too demanding, but getting them from an external website and then generating the HTML for these then adds quite a bit more work. What if you are collecting the latest from your Twitter account (like I do) and placing it on the website and applying regexps all over the content? This is quite demanding. So I spent a lot of time reviewing literature on this exact problem and it seems it actually is a problem, albeit easy to fix.

Our PHP function may return us a HTML result when we get our Tweets back from Twitter's API, and we know that the Twitter feed is only going to update when we update it, so why don't we just throw the HTML result into a text or HTML file? This solution then means that we have to manually update (delete the file) the website when we update Twitter. Not ideal.

The solution, check the modification date of our cached file. If it is more than 24 hours old, delete it. The PHP function will no longer see the file and instead of getting a cached version it will refresh it with a new request to Twitter. Still not perfect though since we've got to delete the file.

The final solution, the PHP file checks if the file exists, if it does checks the modification date and if it's over 24 hours old it gets the latest data from Twitter and updates the file with that data and returns it.

There you have the description of a very simple PHP caching system. 

Posted in Web Development
cache
php
script
js
website

I would go as far as to say that over the few months I have learned so much and am aiming to become an Apache master soon! 

In the last year or two, I have also been using regular expressions (regexps) to do everything and I think it's fair to say I am a master of them. I find them to be the most useful thing you can know for using your computer on a day to day basis. I now use them to search my computer or a text editor, I have made my own programming language which uses them for matching in the compiler, and very recently to match things on my website. I recently mastered htaccess files on Apache and nginx servers. As part of this I have made my site much more SEO friendly and developed BalfBlog considerably. I have been using regexps for about five or six years, but I was not exactly using them often enough and skillfully enough. Back in my C# programming days (I haven't worked on my C# projects since 2013, but I am talking about when it was my main language in about 2008 - 2010) I used regexps in Wonderword for the search and replace features, in BlackRabbit Script it was pretty much the basis of the language and in other programs I used it for text replacement tools (also included in Wonderword, but also found in my BBCL library).

Recently I brought both of these masteries together and have done so much with my website to make it better. I improved my hotlink protection due to these regexps and, to be honest, I think I did a great job since I cut ninety lines down to three with some simple regexps. 

So today I'm going to share this with you.

cPanel, by default, allows you to add URLs that will not be affected by hotlink protection. As such you enter them in (or if you add a new subdomain it adds them automatically). Except as great as this is, my URLs looked like this:

HTAccess
RewriteCond %{HTTP_REFERER} !^http://2010.archive.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://2010.archive.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://2012.archive.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://2012.archive.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://airdisplays.sites.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://airdisplays.sites.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://alpha.archive.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://alpha.archive.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://archive.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://archive.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://ashes-scattered.sites.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://ashes-scattered.sites.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://be.sites.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://be.sites.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://castleinn.sites.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://castleinn.sites.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://clickit.education/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://clickit.education$      [NC]
RewriteCond %{HTTP_REFERER} !^http://developer.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://developer.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://doodle.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://doodle.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://doodle.projects.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://doodle.projects.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://edustream.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://edustream.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://flitter.projects.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://flitter.projects.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://firestarter.projects.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://firestarter.projects.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://jamiebalfour.co.uk/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://jamiebalfour.co.uk$      [NC]
RewriteCond %{HTTP_REFERER} !^http://jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://jbtest.projects.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://jbtest.projects.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://projects.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://projects.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://sites.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://sites.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://wonderword.sites.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://wonderword.sites.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.2010.archive.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.2010.archive.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.2012.archive.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.2012.archive.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.airdisplays.sites.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.airdisplays.sites.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.alpha.archive.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.alpha.archive.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.archive.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.archive.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.ashes-scattered.sites.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.ashes-scattered.sites.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.be.sites.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.be.sites.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.castleinn.sites.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.castleinn.sites.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.clickit.education/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.clickit.education$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.developer.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.developer.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.doodle.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.doodle.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.doodle.projects.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.doodle.projects.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.edustream.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.edustream.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.flitter.projects.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.flitter.projects.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.firestarter.projects.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.firestarter.projects.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.jamiebalfour.co.uk/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.jamiebalfour.co.uk$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.jbtest.projects.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.jbtest.projects.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.projects.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.projects.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.sites.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.sites.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.wonderword.sites.jamiebalfour.scot/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.wonderword.sites.jamiebalfour.scot$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.zenlang.net/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://www.zenlang.net$      [NC]
RewriteCond %{HTTP_REFERER} !^http://zenlang.net/.*$      [NC]
RewriteCond %{HTTP_REFERER} !^http://zenlang.net$      [NC]

I was looking at what it generated tonight since I've been fixing a lot of htaccess directive files across my site and subdomains and my other domains. I realised that I can put these down to just three lines of code and make it easier for me to maintain in the future. So this is what I've got:

HTAccess
RewriteCond %{HTTP_REFERER} !^https?://(www.)?(.*.)?(.*.)?jamiebalfour.co(m|.uk)(.*)      [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www.)?clickit.education(.*)      [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www.)?zenlang.net$      [NC]

 So there you have a simple solution to a big problem. Learning regexps is like learning to use a calculator, it just saves so much time!

Posted in Web Development
apache
web
server
nginx
regex
regular
expression
matching

In the old days, before CSS, background colours were set using the bgcolor attribute as below:

HTML
<html bgcolor="rgb(255, 0, 0)">
</html>

But since this is quite an old way of doing things and not used often nowadays, you'll probably find it has a lack of support in some newer browsers like Google's Chrome. I came across this issue when I was trying to make the background red by using rgba(255, 0, 0) which would normally produce red and does in other browsers, but in Google's Chrome browser it produces a totally different colour. I believe this is because Google did not spend much time working on support for this older attribute that should be banished from HTML5 altogether. Below is a sample that may or may not do anything at all:

Hello world

Have you experienced this issue where the colour value represents different colours on different browsers? If so let me know by commenting below.

Posted in Web Development
css
web
development
design
chrome
back
ground
bgcolor

I have been working quite a lot recently on my latest project, ClickIt. ClickIt is a web development tool using the new HTML5 drag and drop standards. It has been working fine with all browsers until very recently I discovered it had an issue with both Mozilla Firefox and Microsoft Edge. I have in the past stated my dislike for Firefox after it made my life much harder in one of my courseworks last semester and now my anger continues.

Chrome, Safari and Opera cover a reasonably large base of users but for full compatibability, I'm going out of my way to try and fix an issue which I don't even know what it is. The original problem occured when I used the W3 standard for drag and drop and did this:

JavaScript
function DragBlock(ev, mode) {
	setData(ev, "mode", mode);
	setData(ev, "text", ev.target.innerText);
	setData(ev, "style", ev.target.getAttribute("class"));
}
function setData(ev, x, v){
	ev.originalEvent.dataTransfer.setData(x, v);
}

The problem however is that when I then try to retrieve this information, none of it exists. It does in Chrome and Safari, but not in Firefox or Edge. If I find a solution I will post it here.

My good friend Merlin managed to discover the problem with my implementation, and it's hardly obvious nor expected! The problem actually occurs with the ev.target.innerText function. This function is not supported in Edge or Firefox, but is in Chrome and Safari. So there you have it. My problem is fixed.
Another update on the situation: I fixed the issue altogether after I learned that the first parameter to the setData function is actually not the name of the value but the type. For some reason, Chrome and Safari accept this as the name anyway and transform this to a map from the name to the value (or in this case x -> v). Instead of messing about with this, my solution, which is somewhat crude, is to use a global variable which in turn is a map from x -> v. Since I put these in functions, my functions were simply changed to modify this global variable upon request and retrieve information back from it. This solution is as I say crude since it relies on the fact there is only one object being transferred. I am most puzzled by the fact that the issue is totally different with Safari and Chrome and that they work this as if it were a map.
Posted in Web Development
drag
drop
firefox
microsoft
mozilla
edge
issue
problem
datatransfer
Powered by DASH 2.0