A blog of minor discoveries and useful tips from Kevin Locke.
A common tactic to increase performance and decrease bandwidth is to compress
HTTP responses. This is particularly useful for text content such as the CSS,
different methods for configuring compression in Apache, but most have subtle
(or not so subtle) issues. This post continues the series of
posts (after the earlier
posts) by outlining the problems encountered in popular compression
configurations and how to avoid them using
Web developers and admins looking to tighten the security of their websites
should consider defining a Content Security
Policy for their site. For sites hosted using
Apache, a simple way to achieve this is by
Content-Security-Policy header using
Unfortunately, making this simple solution robust is more difficult than it
first appears. This post describes a method for setting or modifying the
Content-Security-Policy header in a way that won’t clobber previous values
set by earlier configuration options or returned by an application server.
For those of you who are Serving XHTML with Apache
you may want to be careful about how
MultiViews interacts with
Configuring error documents with content negotiation can lead to compound
errors in the case that the client does not accept any of the types available
for the error document. This results in both unexpected behavior and a
suboptimal user experience. This post describes how to avoid such errors
while still negotiating the returned content type.
This blog has been dead for the last couple of years, without a single post since the beginning of April, 2013. In that time I’ve been preoccupied with other endeavors, primarily Quantpost, and haven’t had time to document any of my minor discoveries. Luckily for readers, this blog is only mostly-dead, not all-dead, and I am planning to bring it back to life.
I have recently moved to Seattle, WA to attend courses at the University of Washington and am planning to make time available for writing new content. I have a few drafts of new posts that have been waiting to be completed since 2013 which are still relevant and useful, as well as a and a long list of topics that deserve attention which has accumulated over the past 2 years. I make no guarantees about the frequency or volume of upcoming posts, but you can expect several new posts in the next few weeks and posts on a more regular basis after that. Perhaps even some style improvements to make the blog easier to read. So, without further ado, on to the new posts!
I recently configured an additional encrypted partition mounted at boot using cryptsetup with LUKS. Doing so increased my boot time by about 5 seconds. In tracking down this minor annoyance, I learned two things about cryptsetup which may be helpful to others in a similar situation:Read more...
Recent versions of Firefox crash on startup when
/proc is not mounted.
Although this is not a problem, per se, the fact that it crashes without
giving any indication of the reason can significantly complicate testing
alpha/beta/nightly releases. This post simply lists the errors that I have
seen in hopes that it will save others some debugging time.
I just finished tracking down a rather esoteric bug in a Scala application that I am writing. Understanding this bug requires some understanding of how Scala is translated to Java and how Java handles static initialization, neither of which will be explained (much) in this post. So, if you are interested in how default parameters on a constructor can cause circular static initialization resulting in a NullPointerError, read on.Read more...
If a delete trigger is fired on a table due to an
ON DELETE CASCADE action,
will the trigger see the rows in the parent table which triggered the cascade?
Will a trigger on the originating table see rows in the child tables? Does it
matter if the trigger is a “before” or an “after” trigger? The answer to these
questions was not immediately obvious to me, and my half-minute of searching
didn’t find a clear answer, so I have written this post to remind myself and
others what happens in PostgreSQL 9.1.
This post is just a quick warning that Flyway (before commit 55985b, which includes version 2.0.3, the current version) disables auto-commit on its JDBC Connection. Also, BoneCP (before commit 99d50d, resulting from bug 790585, which includes version 0.7.1.RELEASE, the current version) did not apply the default auto-commit or read-only setting to recycled connections. When these behaviors are combined, connections will be returned from the connection pool which have differing auto-commit. Plan accordingly.
Another quick note, version 0.8.0-rc1 has auto-commit set to
default, which differs from the JDBC behavior. I consider this a
The Lift web framework integrates the SLF4J logging framework through a set of interfaces for performing logging and a configuration mechanism. The configuration mechanism attempts to configure the logging in a manner similar to the configuration for other parts of Lift. Unfortunately, this mechanism performs differently (or not at all) when running tests than it does when running normally. This post is a quick explanation of the configuration mechanism and how to configure logging during tests.Read more...
Just a quick reminder to always flush your buffers (when appropriate) and that
the behavior of the JDK default
com.sun.xml.internal.stream.writers.XMLStreamWriterImpl) differs between
UTF-8 output, which is unbuffered, and non-UTF-8 output, which is buffered
com.sun.xml.internal.stream.writers.XMLWriter. I just spent way too
much time figuring this out (particularly because finding the actual location
of the source file is non-trivial - Hint: It’s not in the OpenJDK source
tree). Hopefully this post will save others that time/effort.
Ruby software is commonly distributed as “gems”, packages containing Ruby
applications and/or libraries, which can be installed using the
RubyGems package manager, typically run as a command
gem. On Debian systems, some gems are also available as Debian
packages through the Debian package repositories. For Ruby developers on
Debian, it is almost inevitable that some gems will be installed through
RubyGems and some will be installed through the Debian package managers (and
possibly some installed through both). This post discusses some tips for
minimizing the pain of this situation.
Just a quick note: I wanted to work with fonts from Google Web Fonts offline. Unfortunately, the source code only contains TTF files and I was unable to find either a trusted converter utility for all formats or a way to download non-TTF formats. So, I wrote a simple utility to download the fonts. Perhaps you will find it useful.
Updated December 13, 2012 at 00:19 AM MST
Recent versions of Lift (2.2-M1 and later) provide a concise way of expressing XML transformations using a CSS-like syntax called CSS Selector Transforms. The pleasant conciseness comes with a number of unexpected/undocumented behaviors and corner-cases. One which recently caught me by surprise is the handling of attributes on XML elements. This post is a brief discussion of the behavior and how to work around it to remove attributes from elements.Read more...
I’ve recently started using the Dispatch library for HTTP/HTTPS, which is quite a nice library, as long as you don’t need documentation. Dispatch uses the Ning/Sonatype AsyncHttpClient library, which is also quite nice, and although AsyncHttpClient is a library which I could recommend, it does have an insecure-by-default implementation of SSL. This post is a quick discussion of the AsyncHttpClient defaults and how to implement certificate verification to increase the security provided by SSL.Read more...
Updated November 16, 2012 at 08:38 AM MST
I recently started using SLICK (formerly ScalaQuery) for database access in a Scala project. In the process of wrapping my head around how SLICK, I’m documenting some “recipes” for common queries. Unfortunately, this post got published before the recipes were ready. (Oops!) But, not to worry, I’ll post them here (or a link from here) once they are ready.
Updated November 16, 2012 at 11:41 AM MST
I recently had to make the difficult choice to replace Squeryl with SLICK (formerly ScalaQuery) much later in the development cycle than I would have liked. Although I do like some of the design and features of Squeryl, it has some very significant limitations that anyone considering using it should be aware of up-front. Also, in an effort to avoid excessive bias, I’ll include a few of the limitations of SLICK that I have encountered for comparison.Read more...
Although it does not appear to be officially documented, it is possible to subscribe to a Google Group without a Google Account. There are several ways to subscribe but, as I recently found out, Google Groups tries really hard to use a GMail account, if you have one. This post explains how to subscribe to a Google Group via email and how to avoid one pitfall that may result in messages being sent to your GMail address rather than the address with which you subscribed.Read more...
Updated September 07, 2012 at 20:45 PM MDT
The latest issue that I’ve encountered while working with Squeryl in a Lift-based web application, is that not all transactions are being committed to the database. This post is a quick discussion of the symptoms that I was seeing and a note on how to avoid the issue.Read more...
In tracking down some persistent errors relating to using Squeryl with Lift, I’ve found that the latest version of BoneCP does not appear to be safe for use in this scenario. This article is a quick discussion of the symptoms that I am seeing and how to avoid them.Read more...
Although the ffmpeg (and avconv) program has a relatively intuitive command-line interface, given the diversity and complexity of the functionality that it exposes, there are still many operations which can be difficult to express. I found letterboxing (and pillarboxing) to be one of those operations, so in order to save others the trouble of working out the details, this post will develop a command for doing boxing with ffmpeg/avconv.Read more...
I recently spent way too much time tracking down the source of an error in the Squeryl integration to the Record persistence layer in Lift. In the hopes that it may be useful to others encountering the same error, here are the details:Read more...
If you are reading this article on the web using a modern web browser, you should be seeing an XHTML version of this page served as application/xhtml+xml. The merits of the XHTML media type, and XHTML in general, have been widely debated and I will not discus them here. Instead, here is a brief discussion of how this server is configured to serve HTML and XHTML content.Read more...
Updated September 01, 2012 at 23:07 PM MDT
Recently Thunderbird started opening http URLs in the wrong browser. Although you may think that the solution would be a simple configuration change, as I did at the time, it turns out that the process which Thunderbird uses to determine which browser to use is complex, poorly documented, and has changed several times between Thunderbird versions. This post outlines my understanding of the process and, most importantly, how to change the default browser in current versions of Thunderbird.Read more...
Redmine is a web-based project management system, often called a forge, built using the Ruby on Rails framework. It provides bug/issue tracking, time tracking, wiki pages, gantt charting and calendar, multiple project support, and role-based access control for users to name a few. This article will cover the process of installing Redmine on Debian Squeeze using MySQL for data storage, Thin for serving Ruby, and nginx as the outward-facing server.
Updated July 21, 2012 at 11:37 AM MDT
This post was converted from a page I put together several years ago. It is presented here for posterity and in the hopes that it may still be useful in some way.
The Simple Directmedia Layer (SDL) library provides several methods of displaying images, many of which may be used interchangeably. In order to help developers choose which method to use in a given set of situations, this post presents performance numbers for a variety of these display methods.Read more...