Reverse-proxying web applications with Apache 2.4+

Note: Making a reverse proxy with nginx is much more straightforward.


A reverse proxy is a "man in the middle" server that tunnels requests to another server. You can use for things like:

  • Expose a local service that you cannot directly reach over the internet
  • "Change" the domain or path of a web application by rewriting them on the fly
  • Instantly change servers that respond to a name or ...

Gatekeeping: Guide for gatekeeper

Note: This process is tailored to our specific needs and tools at makandra. While it will certainly not apply to all (especially larger teams), we think it is a helpful starting point.


In order to reduce the number of rejects we get from clients, we want to review all code written before it goes to the staging server.

If you're responsible for gatekeeping in a projects, this is what to do:

First, read the [Gatekeeping for developers](https://makandracards.com/makandra/6579-gatekeeping-guide-for-develope...

Manually trigger a delegated DOM event

When you register a delegated event using on (or the deprecated delegate / live), it is somewhat hard to manually trigger these events manually, e.g. for testing.

After trying jQuery's trigger to no avail, I had success by using native Javascript methods to create and dispatch an event. For instance, to trigger a mousedown event:

element = $('...').get(0);
event = new MouseEvent('mousedown', { view: window, cancelable: true, bubbles: true }...

Show details of TLS/SSL connections of remote hosts

sslscan is a nice tool to show details about TLS/SSL connections:

~> sslscan some-host-at.makandra.de

Testing SSL server some-host-at.makandra.de on port 443

  Supported Server Cipher(s):
    Failed    SSLv3  256 bits  ECDHE-RSA-AES256-GCM-SHA384
    Failed    SSLv3  256 bits  ECDHE-ECDSA-AES256-GCM-SHA384
    Failed    SSLv3  256 bits  ECDHE-RSA-AES256-SHA384
    Failed    SSLv3  256 bits  ECDHE-ECDSA-AES256-SHA384
    Rejected  SSLv3  256 bits  ECDHE-RSA-AES256-SHA
...

  Prefered Server Cipher(s):
    TLSv1  128 bits  ECDHE-RSA-A...

Cucumber step to pick a datetime in Rails' horrible datetime_select

Please don't use the horrible datetime_select helper. It has a terrible UI. Always prefer to use a visual time picker like Rome instead.

In case everything has failed and you do need a Cucumber step to pick a datetime datetime_select, here it is:

When(/^I select the time (\d+)\-(\d+)\-(\d+) (\d+):(\d+) from "(.*?)"$/) do |year, month, day, hour, minute, label_text|
  label = page.find('label', text: label_text)
  id = label[...

has_defaults 0.4.2 lets you use dagger lambdas

Starting with has_defaults 0.4.2, default values that are lambdas are no longer called with the current object as argument, but instance_exec'd instead.

This means you can now use dagger lambdas like this:

has_defaults :full_name => -> { "#{first_name} #{last_name}" }

You can also use lambda and proc as long as you don't take parameters:

has_defaults :full_name => lambda { "#{first_name} #{last_name}" }
has_defaults :full_name => proc { "#{first_name} #{last_name}" }

You can no longer write this:

has...

Savon testing: How to expect any message

When using Savon to connect a SOAP API, you may want to use Savon::SpecHelper to mock requests in your tests as described in their documentation.

When sending a message body, the savon mock object requires a message to be set, like this:

savon.expects(:action_name).with(message: { user_id: 123 }).returns('<some xml>')

If you want to stub only the returned XML and do not care about request arguments, you can not omit with as Savon's helper will complain:

savo...

Detect recently added vdisks in a VMware ESXi linux guest

After adding a vdisk to an ESXi linux guest you will assert that you can't find a new device in the running VM. You have to force a SCSI rescan.

  1. find your host bus number with: grep mtpspi /sys/class/scsi_host/host?/proc_name
  2. output should look like this: /sys/class/scsi_host/host2/proc_name:mptspi where the bold part is what you're searching for
  3. force an SCSI rescan with echo "- - -" > /sys/class/scsi_host/<host>/scan and insert the host found in point two for <host>
  4. cat /proc/scsi/scsi should now show the new ad...

Why you see a GET "/__identify__" request in Capybara tests

You might wonder about this request in your test.log:

Started GET "/__identify__" for 127.0.0.1 at 2015-04-29 18:00:02 +0100

This is what happens: For drivers like Selenium, Capybara will boot up a Thin or Webrick server in a separate thread. It then makes a GET request to /__identify__ to see if the server is ready to accept requests.

Since you don't have a route that responds to /__identify, Capybara will wrap your Rails app in...

Make timestamp of dmesg in Ubuntu human readable

dmesg shows the kernel ring buffer containing low-level system messages.
Per default, dmesg shows a timestamp:

12:59:26 fnordomator ~ > dmesg | tail
[101925.211846] usb 2-1.1: USB disconnect, device number 16
[110486.855788] usb 2-1.1: new high-speed USB device number 17 using ehci_hcd

If you're a human, use dmesg -T to print the timestamp human readable:

12:59:31 fnordomator ~ > dmesg -T | tail
[Di Apr 21 12:43:16 2015] usb 2-1.1: USB disconnect, device number 16
[Di Apr 21 15:05:57 2015] usb 2-1.1: new hig...

Unfreeze a frozen ActiveRecord

You can freeze any Ruby object to prevent further modification.

If you freeze an ActiveRecord and try to set an attribute you will an error like this:

can't modify frozen hash

This is because ActiveRecord delegates #freeze to its attributes hash.

You can unfreeze most Ruby objects by creating a shallow copy of the frozen object by calling #dup on it:

user = User.find(3)
user.freeze
unfrozen_user = user.dup

Notes for Rails 2 users
-----------------...

Make "rake notes" learn about Haml, Sass, CoffeeScript, and other file types

Rails comes with a Rake task notes that shows code comments that start with "TODO", "FIXME", or "OPTIMIZE".

While it's generally not good practice to leave them in your code (your work is not done until it's done), in larger projects you will occasionally have to use them as other parts of the application that you depend upon are not yet available.
To keep track of them, run rake notes. Its output looks something like this:

$ rake notes
app/controllers/fron...