grails 3 interceptors

Having to wrap my head around grails 3 interceptors this week.

Grails 3 deprecated filters, and removed ‘beforeInterceptors’ from controllers, so now all that sort of work should be in general interceptors. An interceptor is essentially a controller with an ‘Interceptor’ trait, which adds 3 behaviours on (before, after and afterView).

Filters were handy for me to be able to change the ‘model’ information after it came from a controller action but before it was sent to the view layer. I’ve got some multitenant systems, and being able to set some view layer changes (different templates info, etc) based on tenant info was useful.

The problem I’ve run in to is that the interceptors have a precedence order – implicit or explicitly defined – but the behaviour is nested, not sequential. Take a look at the following

class GeneralInterceptor implements Interceptor {
  int order = HIGHEST_PRECEDENCE + 500
  def before() { true }
  def after() { true }
class DemoInterceptor implements Interceptor {
  int order = HIGHEST_PRECEDENCE + 1500
  def before() { true }
  def after() { true }

GeneralInterceptor.before() will be run first (HIGHEST_PRECEDENCE is the lowest integer possible, so, say, 0+500 vs 0+1500, lower wins), then DemoInterceptor.before() is run.

However, it looks like DemoInterceptor.after() is run, then GeneralInterceptor.after() is run – the reverse order of the before calls.

This has a bit of an implication for how you manage the model values – values I was setting in the “2nd” interceptor after call were being overridden by code in the first after call because I’d assumed they were sequential, not nested.

Possibly obvious to others, but it was news to me, so here you go :)

chunked file uploads with plupload

Holy tamole…

Have been wrestling with a client project using ‘plupload’ with a user base consistently uploading files from 150-500meg on a daily basis. They’d been uploading to youtube/vimeo mostly, because the experience with the older uploader (still plupload earlier version) was bad – slow, mostly, but some issues about determining whether items were uploaded/processed correctly (files sent to third party for processing).

Joined a project and the other dev had been working on a revamp, and had put some new things in place to help with logging/notifications/etc, but as we rolled it out to the main production site today, word had come back that “this is still really slow”.

I’ve only got 5mpbs up at the office, so it was hard for me to judge/test. Working with the PM, who had much faster upload, we tested a 344meg file. We got about 9:40 upload time. Ugh…

Spent a lot of time looking at lots of potential issues – any network throttling? Any firewall stuff? Error logs? Apache settings? Dug deeper and noticed that ‘chunk_size’ in plupload was set to 1m. Hrmm…. let’s change that to 5m.

Tested upload again, and got 5:12. Changed to 8m, got 4:40. Changed to 10m, got 4:39. Uploaded same file on and got 4:32, so we’re definitely in the ballpark on what the end users are accustomed to.

Whew… case solved…

defining functions inside a constructor

Recently came across some code on a project that looks like this (code changed – it wasn’t this simple!)

class foo {
 public function __construct() {
 function foobar() { echo 'abc'; }
$c = new foo();

It was a bit more convoluted than this originally, but that’s the gist of what’s going on. To ensure ‘foobar’ was defined as a function, the code would $f = new foo(); which would ensure the global ‘foobar’ function was defined.

Sort of blew my mind that someone would build a whole lot of code this way. It’s “wrong” on a lot of levels, but… still works. I was hoping it wouldn’t work in PHP7, and we could use that as an excuse to rewrite, but… it works in PHP7, at least this code does – haven’t tried the entire project in PHP7, and I’m sure something *will* break, but it may not be this pattern.

Have not seen much around the PHP blogs/forums about this pattern, so I thought I’d post it here.

Do you do this? If so, why? If not, why not? It’s certainly not demonstrated anywhere in PHP docs or any tutorials, so I’m wondering how this sort of code forms in someone’s thinking.

Avoid features vs abandoning them

I stumbled on an article from Matt Galligan about the initial versions of, a news aggregator app from a few years ago that recently closed up.

So the article talked about many of the design ideas they had, and the struggles they worked through before changing or abandoning some ideas.  This is an example

Screen Shot 2016-06-11 at 4.30.04 PM

I don’t think it’s just me, but certainly types of people *like* me, that would immediately look at that and say “it can’t realistically be done”.  There’s too many variations of image sizings/croppings/ratios that would prevent decent text overlays to make this anything near automatable.  Without automation, this means every item would need human input/work to get that visual aesthetic ‘just right’.

I’ve pointed this one out not in hindsight, but in ‘present sight’ in many projects – specifically, tying interfaces to designs that were only tested with 2 images and 3 lines of content, but that are intended to support unlimited amounts of images/content – all the use cases are unable to be defined in a single photoshop file.  As the person who has to actually make it all work, you have to be able to account for all input values – headlines won’t always be 24 characters.  How do you deal with a 70 char headline?  How do you deal with user-generated photos with non-standard aspect ratios?  These questions have to be addressed, and often the best solution is extreme limiting of the input variables if ‘design’ is the primary concern.

And yet, I’ve been on multiple projects where a design like this gets approved (often by many folks) before ever letting someone who will have to implement it be involved.  When the reality hits…. the pushback on the dev/engineer is often “just make it work”.  Or “quit being negative”, or what have you.  I can only imagine how much time/money was lost/wasted on this particular issue, but also how often this *exact* problem has been played out/repeated over hundreds or thousands of app startups over the last few years.  Each team beating their head against the wall to try to implement the ‘vision’ collectively wasted thousands of hours and dollars.

In many cases, it’s better (in terms of getting to market, hitting deadlines, reducing time/money waste, etc) to avoid working on features up front vs having to abandon them later.  Convincing others of this, especially after decisions have already been made, is often a difficult task.

While certainly was not glad to see close up, I was grateful to see Matt’s notes here.  I’m curious if anyone will actually pay heed to some of the lessons in this particular presentation and learn from them, saving themselves loads of time/money/headache.  My cynical nature expects not, because people always think their project/team/vision is more unique/special than it really is, and they’ll ‘get it right’ where others failed.

This all came about by perusing “/r/shutdown” subreddit earlier today.

Somewhat of an aside, but Matt worked with Joe Stump on SimpleGeo years back, and Joe is someone I knew from the early 2000s in Michigan before he moved on to greener pastures.  Matt also worked with Arsenio Santos at, and Arsenio was one of the better dev managers I’ve worked for over the years.  So while I’ve never met Matt directly, he’s a reminder to me a the increasingly small world we live in.





Visitors getting the wrong website content

I just recently had an exchange with a client that some of their web sites were ‘cross bleeding’ – a few visitors going to were getting  These are all hosted on the same server, stock Apache/PHP stuff, nothing special.  However, one of the domains was SSL, and had an entry for responding to port 443, which the others didn’t.  If anyone tried via https, they’d see siteb.  I went in and patched that up in the config and thought everything was good.

Week later… “this is still happening, and getting worse”.

Well… I started to dig in a bit more, and noticed that the control panel we’d installed had created the new siteb entry with IPv6 and IPv4, but the other sites, which got imported but not updated, were IPv4 only.  I updated all the vhost definitions to respond to IPv6 and IPv4, and… so far so good.  I’m pretty sure this was the issue.  It was only affecting a handful of people, and they were reporting in in a meeting (based on the context, I infer these were mobile users) and from what I gather, more mobile operators are pushing IPv6 out to end users.

If you’re getting the problem I was, check that you are dealing with both IPv6 and IPv4.

Getting console.log from phantomjs with selenese runner

Pretty much titled this what I was looking for this morning… :)


time java -jar bin/selenese-runner.jar -t 10000 --baseurl http://yourURL \
--phantomjs bin/phantomjs  \
--cli-args --webdriver-logfile=tests/browser.log \
--cli-args --webdriver-loglevel=debug \
--width 1280 --height 1024 \
--set-speed 130 --screenshot-dir public/tests/screenshots \
--screenshot-on-fail public/tests/screenshots \
--html-result public/tests \

Note the “–cli-args” flags.  Yes, you can have multiple, and yes… this is documented on the selenese runner page, but it wasn’t obvious to me, so I’m posting it here anyway.

letsencrypt live and functioning in virtualmin

I’ve been a virtualmin/webmin user for many years.  Last summer, I heard about “let’s encrypt“, a service to offer free short-term SSL certificates to everyone.  A colleague tested the service in December, and I started messing around with it based on his recommendation.  I found a few shell scripts that would help automate the setup for getting SSL certs for the domains I manage, and started testing those.  A bit cumbersome, but much easier than the traditional SSL cert dance from other vendors.  As a side note, I noticed that out of the box support was better for Ubuntu than CentOS.

Anyway, I’ve been searching around for ways to automate this within my virtualmin systems, and found a vague reference in someone’s post that webmin understood about let’s encrypt.  I loaded up my virtualmin, and found that… goodness me, in the virtualmin area for each domain’s “manage SSL certificates”, there was a “let’s encrypt” tab ready to go.  I needed to install the letsencrypt code, and I symlinked it to a ‘letsencrypt’ name on my path, and… virtualmin did the rest.  It was literally just pressing the “request a certificate” and waiting < 20 seconds.

Screen Shot 2016-01-31 at 12.32.53 PM

Another aside – you can fairly easily support multiple SSL certs on one shared IP address with any modern stack and browsers.  This has been a supported ‘thing’ since… 2007, IIRC.  However, it relies on newer networking stacks, and from what I understand, Windows XP will never support this new security handling.  So… if you need to support Windows XP browsers/clients, you may need to stick with the “one ip per SSL cert” approach.  For rather run-of-the-mill consumer-oriented sites, aimed at mostly users with modern stacks, there’s little reason to not be using at least letsencrypt as a free SSL to encrypt your traffic.

WordPress security woes and plan of attack

I’ve been involved in a few wordpress security snafus over the last 3-4 months – almost none of which were my doing directly, but I’ve still gotten involved anyway.  I’ve been disappointed, but not surprised, that even some commercial security and scanning services seem to miss rather obvious issues, and this sours me even more on the entire idea of using those commercial services in the first place.  A friend found the ‘social.png‘ issue on a server, and had scanned with maldet, clamav, bitdefender, and … I think.. service (not 100% sure on that one).  All of them failed to notice that a .png file had “eval(‘foo’)” PHP code in it.

To that end, I’m putting some restrictions/requirements on new wordpress projects that I get involved with:

  • fail2ban has to be installed and running
  • maldet/clamav (they have found some issues in the past)
  • all files and directories are not writeable – small shell script will make them writeable on demand for a few minutes, then revert all files/directories back to unwriteable shortly thereafter
  • blocking all outbound port 80 and 443 traffic via iptables, with a specific whitelist of exceptions.  I can’t think of but a handful of reasons why PHP code needs to initiate unrestricted outbound traffic (maybe I’m wrong?)


I’m picking on wordpress mostly because it’s the cleanup I’ve had to wrestle with the last few months, but there’s little reason that these don’t really apply to any web projects, really.  The one that came up this week is on a managed server (“you can’t have root because you might do something to compromise security… but go ahead and install wordpress and do whatever you want”), and they called out and said “hey, you’re infected”.  but… as a managed service that I don’t even have shell access to, doesn’t the managed server company bear some responsibility for preventing these sorts of situations in the first place?  At >$500/month, I expected better service (wasn’t my client, wasn’t my hosting company choice, I’m just now being looped in because of the exploits).

There’s 2 main issues at play:

1.  bad code allows PHP code to be written in to world-accessible URLs to be executed

2.  the executed code can then talk to other servers on the internet, typically over ports 80 or 443

Stopping public folders from being writeable and stopping unrestricted outbound traffic both seem to go a long way to preventing these two issues.

Am I missing something?  Don’t say “go get wordfence” or something similar.  Well, you can say it, but… that is really only addressing a subset of potential issues.  I wouldn’t say no to something like wordfence on top of these other steps, but .. that doesn’t address a joomla project, or drupal projects, or whatever.

quick web idea generator

Running low on ideas? At our local wordpress helpdesk meeting this morning, someone mentioned his business venture, and it turned out he didn’t have the domain yet (but had already incorporated it in to his web copy, strangely). Fortunately, it was still available, and has since been secured, but it was quite a simple name (started with the word ‘triangle’, as that’s our regional nickname).

I did a quick search at for ‘triangle’, then filtered to only domains starting with ‘triangle’, and was surprised at how many names were available. Of course, a domain name does not a business make, but you may get some neat ideas just by playing around.

Some links to regionality-based domain names that might spark some ideas in you :)

I’m sure you can likely think of regional nicknames for your neck of the woods as needed!

Grails ckeditor full settings

Took me a while to find this, and I’m posting here primarily for my own memory, but hopefully this useful to some of you as well.

 <ckeditor:config var="toolbar_Custom">
{ name: 'document',
items : [ 'Source','-','BulletedList', 'Link', 'Image', 'Font', 'FontStyle'] },
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ], items: [ 'Source', '-', 'Preview', '-', 'Templates' ] },
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ], items: [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ] },
{ name: 'links', items: [ 'Link', 'Unlink', 'Anchor' ] },
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker' ], items: [ 'Find', 'Replace', '-', 'SelectAll', '-', 'Scayt' ] },
{ name: 'forms', items: [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton' ] },
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ], items: [ 'Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat' ] },
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ], items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'Justify
{ name: 'insert', items: [ 'Image', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak', 'Iframe' ] },
{ name: 'styles', items: [ 'Styles', 'Format', 'Font', 'FontSize' ] },
{ name: 'colors', items: [ 'TextColor', 'BGColor' ] },
{ name: 'tools', items: [ 'Maximize', 'ShowBlocks' ] },
{ name: 'others', items: [ '-' ] },
{ name: 'about', items: [ 'About' ] }

You can then reference the custom toolbar as such

<ckeditor:editor name="body" toolbar="Custom">${content?.body}</ckeditor:editor>

Comment out any sections in the toolbar config tags which you don’t want to show up in the CKEditor. This is current as of version 4.4.1 (I think). If/when CKEditor adds more functionality or renames things, this might get out of sync, but it works as of today.