I am currently refactoring some mailings in an application and as you probably know, debugging mails is a PITA. Luckily I stumbled across Mailcatcher, which runs a simple mail server and can catch mails you send to it and display them in a web gui.

Since it runs on localhost, it’s a bit tricky to set it up in a Vagrant box, where your box probably has it’s own hostname (e.g. myapp.dev). This blog post is written for Ubuntu 14.04 with PHP and apache.

Here’s how to set up Mailcatcher in your Vagrant box.

Provisioning

First you need to provision your Vagrant box to install Mailcatcher. If you don’t already have a provisioning script, you can add one to your Vagrantfile like this:

Note that I replace the default sendmail path in the php.ini* for apache with Mailcatcher’s own catchmail, which causes all mails to be sent there. If you also send mails from the command line (e.g. cronjobs), you’ll also need to replace sendmail in /etc/php5/cli/php.ini.

If you’re sending your mails with SMTP, you have to configure smtp_port instead.

This script is only run automatically when your box is first setup. You can run it manually by calling:

vagrant provision

*you could also just configure this in your apache config like:

php_admin_value sendmail_path "/usr/local/bin/catchmail"

But I feel more comfortable knowing that it’s in my php.ini and won’t suddenly start sending mails if I change around my apache config and suddenly that rule is in the wrong Directory or something.

Starting Mailcatcher on ‘vagrant up’

Just add this to your Vagrantfile to start Mailcatcher when you run vagrant up:

config.vm.provision:shell,inline: "mailcatcher",run: "always"

Accessing Mailcatcher web gui

Since the Mailcatcher web gui, where you can view all captured mails, runs on localhost, it’s not accessible via your app or website frontend by default. This is how I configured my Apache virtualhost conf to enable this (only relevant parts):

How to parse multipart data manually in PHP when working with HTTP PUT requests.

Luckily, PHP offers some great tools for working with data that we usually take for granted. When posting multipart form-data to a PHP script, the POST values will automatically become available as an array of values in the $_POST superglobal, the files will automatically be processed and be made available in the $_FILES superglobal. Unfortunately, this doesn’t work for PUT requests. This is probably by design, as with a PUT request you are actually sending a specific file to a specific location on a server. This is supported, as is sending an url-encoded querystring as the payload. What doesn’t work out of the box though is sending multipart data in a PUT request.

If you get rid of the CURLOPT_CUSTOMREQUEST bit, this will be sent as a POST, and the data will be available in the $_POST and $_FILES arrays respectively. With PUT, the data will not be parsed by PHP at all. So I wrote a method to do it manually. Unparsed multipart data looks something like this: