Skip to main content

Posts

Showing posts from 2016

Connecting to Elixir web channels from the Angular 2 quickstart application

I am busy learning Elixir , a language that adds syntactic sugar to the awesomely scalable and concurrent Erlang language.  The "go to" framework in Elixir is Phoenix  and I'm busy writing my "hello world" application which will serve up data across a web channel. I followed the Typescript version of the Quickstart guide for Angular 2 ( here ).  I really like what I've seen of Typescript so far.  Dependencies are easy to manage and the ability to define interfaces is a good sign of how well structured the language is.  I think Satya Nadella should be made an open source hero, if such an award exists. Anyway, what I wanted to do was get my Angular 2 application to be able to connect to the Elixir server channel and send a request to listen to a particular stream.  The idea is to use the Actor concurrency model (explained brilliantly in " The Little Elixir & OTP Book ") to start up a new process whenever a request for a stream arrives.  This

Laravel refusing to start up

I'm very much a fan of the clean implementation of Laravel but really dislike the fact that if there is something wrong with the .env file it refuses to give any meaningful information. Laravel uses the vlucas/phpdotenv package to manage its environment. It's pretty well known that if you have a space on either side the = sign in a key value pair then the .env file is invalid, but I had checked for this (and checked again). Laravel will try to use its standard logging methods before they have actually had a chance to be booted up with the result that you're left with a "reflection error" exception message on the CLI rather than the actual cause of the problem in the dotenv package. Debugging this is not trivial and I resorted to using strace to try and determine exactly what was going on.  Don't do this at home kids!  The easier solution is at the end of the article. I used the following command to generate a trace of the system calls being made by

Solving a Docker in VirtualBox DNS issue

I've recently been playing with Docker on Windows in conjunction with Linux on Windows .  I'm really amazed at how cool the stuff coming out of Microsoft is under Satya Nadella.   When I was using Docker Toolbox on Windows my Dockerfiles would build correctly but as soon as I tried to run them in a Virtualbox host they would fail with the error " Something wicked happened resolving 'archive.ubuntu.com:http' (-5 - No address associated with hostname) " Of course this error wasn't distribution specific and none of the distros I tried were working. The stack that I am using is Windows Home hosting Ubuntu on VirtualBox which is running Docker.  I'm using bash on Linux for Windows because it's easier to do stuff like ssh but it's not relevant to this setup. I tried setting the DNS in the Docker setup by using RUN steps to update /etc/resolv.  This felt a bit hacky and didn't work anyway. In the end the fix was to go to my Window

Limiting how often you run seeds and migrations in Laravel 5.2 testing

Image: Pixabay If integration tests take too long to run then we stop running them because they're just an annoyance.  This is obviously not ideal and so getting my tests to run quickly is important. I'm busy writing a test suite for Laravel and wanted more flexibility than the built-in options that Laravel offers for working with databases between tests. Using the DataMigrations trait meant that my seed data would be lost after every test.  Migrating and seeding my entire database for every test in my suite is very time consuming. Even when using an in-memory sqlite database doing a complete migration and seed was taking several seconds on my dev box. If I used the DataTransactions trait then my migrations and seeds would never run and so my tests would fail because the fixture data is missing. My solution was to use a static variable in the base TestCase class that Laravel supplies.  It has to be static so that it retains its values between tests by the way.  Th

Implementing a very simple "all of the above" checkbox

Image: Pixabay Implementing a checkbox that lets the user "select all of the above" is trivial with jQuery. The idea is that when the user selects the "all" checkbox then all of the other checkboxes are set to the same value. Similarly if they deselect any of the other options we need to turn off the "all" checkbox.

Why am I so late on the Bitcoin train?

Image: Pixabay I've been somewhat of a Bitcoin sceptic for quite some time.  When it first became a thing I was worried that governments would legislate it out of existence. It has had a pretty bad rap of being associated with the dark web and it is definitely the choice of currency for malware authors. In its normal usage Bitcoin is more transparent than cash.  If I give you a cash note there is no permanent record of the transaction and the tax man can't get a sniff into our business. Governments hate transactions they can't tax or police and so in the beginning there was a concern that Bitcoin would be outlawed. In contrast to cash, if I transfer you Bitcoin then there is a record of the transaction that anybody in the world can inspect.  It's possible to trace the coins in your Bitcoin wallet back through the various people who owned them.  Anybody in the world can watch the contents of your wallet and see where you spend your money. This is exactly th

Restarting BOINC automatically

Image: https://boinc.berkeley.edu, fair use BOINC is a program curated by the University of Berkeley that allows people around the world to contribute to science projects.   It works by using spare cycles from your computer to perform calculations that help do things like folding proteins to find candidates for cancer treatment, mapping the milky way galaxy, searching for pulsar stars, and improving our understanding of climate change and its effects. It runs as a background process and is easily configured to only run in certain conditions - like when you haven't used your computer for 10 minutes for example. It comes with a nifty GUI manager and for most people using it on their desktop this post is not going to be at all relevant.  This post deals with the case where a person is running it on a server without the GUI manager. Anyway, the easiest solution I found to restarting BOINC on a headless server was to use supervisord .  It's pretty much the "

Associating Vagrant 1.7.2 with an existing VM

My Vagrant 1.7.2 machine bugged out and when I tried to `vagrant up` it spawned a new box instead of bringing up my existing machine. Naturally this was a problem because I had made some manual changes to the config that I hadn't had a chance to persist to my puppet config files yet. To fix the problem I found used the command ` VBoxManage list vms ` in the directory where my Vagrantfile is.  This provided me a list of the machine images it could find. I then went and edited the file at .vagrant/machines/default/virtualbox/id and replaced the UUID that was in there with the one that the VBoxManage command had output. Now when I run 'vagrant up' it spins up the correct VM.  Happy days.

Redirecting non-www urls to www and http to https in Nginx web server

Image: Pixabay Although I'm currently playing with Elixir and its HTTP servers like Cowboy at the moment Nginx is still my go-to server for production PHP. If you haven't already swapped your web-server from Apache then you really should consider installing Nginx on a test server and running some stress tests on it.  I wrote about stress testing in my book on scaling PHP . Redirecting non-www traffic to www in nginx is best accomplished by using the "return" verb.  You could use a rewrite but the Nginx manual suggests that a return is better in the section on " Taxing Rewrites ". Server blocks are cheap in Nginx and I find it's simplest to have two redirects for the person who arrives on the non-secure non-canonical form of my link.  I wouldn't expect many people to reach this link because obviously every link that I create will be properly formatted so being redirected twice will only affect a small minority of people. Anyway, here's

Logging as a debugging tool

Image: https://www.pexels.com Logging is such an important part of my approach to debugging that I sometimes struggle to understand how programmers avoid including logging in their applications. Having sufficiently detailed logs enables me to avoid having to make assumptions about variable values and program logic flow. For example, when a customer wants to know why their credit card was charged twice I want to be able to answer with certainty that we processed the transaction only once and be able to produce the data that I sent to the payment provider. I have three very simple rules for logging that I follow whenever I'm feeling like being nice to future me.  If I hate future me and want him to spend more time answering queries than is needed then I forget these rules: The first command in any function I write is a debug statement confirming entry into the function Any time that the script terminates with an error then the error condition is logged, along with the e

Are tokens enough to prevent CSRF?

Image: Pixabay CSRF attacks exploit the trust that a website has in a client like a web browser.  These attacks rely on the website trusting that a request from a client is actually the intention of the person using that client. An attacker will try to trick the web browser into issuing a request to the server.  The server will assume that the request is valid because it trusts the client. At its most simple a CSRF attack could involve making a malicious form on a webpage that causes the client to send a POST request to a url. As an example, imagine that a user called Alice is logged into Facebook in one tab and is browsing the internet on another tab.  A filthy pirate Bob creates a malicious form in a webpage that submits a POST request to Facebook that sends a person to a link of Rick Astley dancing.  Alice arrives on the page we made and Javascript submits the form to Facebook.  Facebook trusts Alice's web browser and there is a valid session for her so it processes th

Exploring Russian Doll Caching

This technique was developed in the Ruby community and is a great way to approach caching partial views. In Ruby rendering views is more expensive than PHP, but this technique is worth understanding as it could be applied to data models and not just views. In the Ruby world Russian Doll caching is synonymous with key-based expiration caching.  I think it's useful to rather view the approach as being the blend of two ideas.  That's why I introduce key-based expiration separately. Personally I think Russian Dolls are a bit of a counter-intuitive analogy.  Real life Russian Dolls each contain one additional doll, but the power of this technique rests on the fact that "dolls" can contain many other "dolls".  I find the easiest way to think about it is to say that if a child node is invalidated then its siblings and their children are not affected.  When the parent is regenerated those sibling nodes do not need to be rendered again. Cache Invalidation

Working with classic ASP years after it died

I searched for "dead clown" but all the pictures were too disturbing.  I suppose that's kind of like the experience of trying to get classic ASP up and running with todays libraries I'm having to work on a legacy site that runs on classic ASP.  The real challenge is trying to get the old code to run on my Ubuntu virtual machine. There is a lot of old advice on the web and most of it was based on much older software versions, but I persevered and have finally managed to get classic ASP running on Apache 2.4 in Ubuntu. The process will allow you to have a shot at getting your code running, but my best advice is to use a small Windows VM.  There's no guarantee that your code will actually compile and run using this solution, and the effort required is hardly worthwhile. The Apache module you're looking for is Apache::ASP.  You will need to build it manually and be prepared to copy pieces of it to your perl include directories.  You will also need to m

Laravel - Using route parameters in middleware

I'm busy writing an application which is heavily dependent on personalized URLs.  Each visitor to the site will have a PURL which I need to communicate to the frontend so that my analytics tags can be associated with the user. Before I go any further I should note that I'm using  Piwik  as my analytics package, and it respects "Do Not Track" requests.  We're not using this to track people, but we are tying it to our clients existing database of their user interests. I want the process of identifying the user to be as magical as possible so that my controllers can stay nice and skinny.  Nobody likes a fat controller right? I decided to use middleware to trap all my web requests to assign a "responder" to the request.  Then I'll use a view composer to make sure that all of the output views have this information readily available. The only snag in this plan was that the Laravel documentation was a little sketchy on how to get the value of the

Using OpenSSH to setup an SFTP server on Ubuntu 14.04

I'm busy migrating an existing server to the cloud and need to replicate the SFTP setup.  They're using a password to authenticate a user and then uploading data files for a web service to consume. YMMV - My use case is pretty specific to this legacy application so you'll need to give consideration to the directories you use. It took a surprising amount of reading to find a consistent set of instructions so I thought I should document the setup from start to finish. Firstly, I set up the group and user that I will be needing: groupadd sftponly useradd -G sftponly username passwd username Then I made a backup copy of and then edited /etc/ssh/sshd_config Right at the end of the file add the following: Match group sftponly ChrootDirectory /usr/share/nginx/html/website_directory/chroot X11Forwarding no AllowTcpForwarding no ForceCommand internal-sftp -d /uploads For some reason if this block appears before the UsePAM s