Basically a place that Chris can post solutions to problems so he can easily find them later

Authorize.Net, DPM, relay response and TLS 1.0

leave a comment

I think I lost almost 8 hours to this. We have an app that integrates with Authorize.Net via DPM and no matter what I did I couldn’t get the relay response to work. The app was working fine last year, the only change (I thought) was that this year I pointed it at their new Akamai endpoint. I also couldn’t get into my sandbox account so I had to create a new one but I couldn’t think of anything in the new one that would have caused the dreaded error message below:

An error occurred while trying to report this transaction to the merchant…

I thoroughly read through the go-to community post on the subject and it said that ultimately the problem is the Authorize.Net can’t reach my server. So I checked my DNS entries, all public and valid. And then I checked them from multiple networks around the globe and, once again, all valid. I checked my cert, totally fine and not a self-cert. Then I did tail -f on every log file that I could find, access, error, nginx, php-fpm, auth (why not?) and watched and never saw Authorize.Net reaching my server. This usually makes me feel good because I can say something like “it’s you, not me” but not in this case.

Finally, I started to write an email to Authorize.Net explaining the situation, what I tried, what I debugged and as I was explaining my local setup it finally dawned on my that the one weird thing about my dev site compared to live is that the dev site is configured with Mozilla’s modern profile which means TLS1.0 is not enabled. Sure enough, the moment I enabled TLS 1.0 in my Nginx config my relay responses started going through again.

Written by Chris Haas

September 22nd, 2015 at 1:25 pm

Posted in Authorize.Net,nginx

SimpleSAMLphp + Nginx


Ugh, this was weeks in the making. I want to use SimpleSAMLphp but I prefer Nginx over Apache. As of right now I can’t find any official documentation for installing on Nginx but they say it should work and shouldn’t be too hard. There’s a couple of threads out there but they were all old configs (two plus years) and none of them worked for me. Finally, after many hours (including giving up for a couple of weeks and just firing up a dedicated Apache server before coming back) I finally found one that works for me.

First, don’t clone from git but download the most recent version as a zipped resources. This is important because the paths in git (I think) aren’t all setup completely and are expected to be resolved via some dependency resolver.

Second, extract the zip file somewhere, in my case /var/www/simplesamlphp.

Third, use this for your location block:

    location ^~ /simplesaml {
        alias /var/www/simplesamlphp/www;
        location ~ ^(?/simplesaml)(?.+?\.php)(?/.*)?$ {
          include fastcgi_params;
          fastcgi_pass unix:/var/run/php5-fpm.sock;
          fastcgi_param SCRIPT_FILENAME $document_root$phpfile;
          fastcgi_param PATH_INFO       $pathinfo if_not_empty;

If you want to use a different URL endpoint you can change simplesaml above in the location lines to match your value in config/config.php for the baseurlpath value.

Written by Chris Haas

December 1st, 2014 at 9:58 pm

Posted in nginx,simplesamlphp

curl with base64 encoded data

leave a comment

I just spent the last hour trying to figure out how to send base64 encoded data that lives in a file using curl. Everyone says to just use --data-binary but that assumes you know what the binary format should actually be! Every combination I tried of --data-ascii and --crlf kept failing with server-side errors.

The trick for me was making sure that the file itself was manually URL encoded. So all newlines were replaced with %0a and all plus signs were replaced with %2b. Then just put everything on one line. So my file (which was a SAML payload for testing) looked like:

                                                                 +                     \n

This can just be sent using the normal --data parameter as a file:

curl -XPOST --data @saml.txt http://www.example.net/

Written by Chris Haas

November 26th, 2014 at 2:17 pm

Posted in Uncategorized

Using web page test with a custom IP address

leave a comment

I recently had a need to speed test a site that was almost launched. Since the site required an SSL cert we’d been doing our final tests with local host files. However, we wanted to get an external network’s view of our site and for that we always use the wonderful http://www.webpagetest.org/. The obvious problem that we ran into was that they wouldn’t have access to our local copies of DNS.

Luckily the answer was simple, they have a great scripting interface along with very comprehensive documentation.

All we had to do was enter this into the Script tab:

setDns www.example.com 456.456.456.456
navigate https://www.example.com

Written by Chris Haas

November 20th, 2014 at 3:52 pm

Posted in Uncategorized

WP 4.1 – Something to watch

leave a comment

First, a very old bug/feature:

Currently, if you have WP Category for fruits called “Apple” and a WP Tag for pies called “Apple” and a custom taxonomy such as “Computer Manufacturers” with an item called “Apple”, that “Apple” term is shared between everything. This isn’t much of a problem until you decide to rename the computer manufacturer to “Apple Computers”, at which point you’ve also renamed the fruit and pie. For the past seven years the only solution to this has been to create a new term instead and manually re-tag everything.

Last year one of the core developers, Andrew Nacin, outlined a roadmap for fixing this, with the expected final change to land in 4.x somewhere in 2015

One part of this roadmap that was to land in 4.1 was when a shared term was detected by the system during an edit, the system would automatically break the share and create unique unrelated terms. So if you edit the Apple computer term in any way (or just hit save on it), WP would detect that it is used in multiple contexts and break that computer one away into a dedicated context of its own.

Sounds like a good plan except it turns out a lot of people having been storing/caching the underlying ID of the shared term instead of the term itself. So developers have been storing “term 48” instead of just “apple” since developers like numbers.

This is a pretty big potentially breaking change but was luckily rolled backed a couple of days ago:

This was re-introduced and in theory fixed four days ago however I can still think of many edge cases that can break:

Written by Chris Haas

November 18th, 2014 at 1:33 pm

Posted in WordPress

Fun links of the day

leave a comment

Written by Chris Haas

November 17th, 2014 at 10:19 am

Fun links of the day

leave a comment

I love the Hot Network Questions on the StackExchange network. Here’s some from this morning.

Written by Chris Haas

November 13th, 2014 at 9:11 am

Finding abandoned/no longer maintained plugins

leave a comment

After Matt’s State of the Word 2014 presentation I was talking to my host (QTH) about how Matt would like to encourage/pressure hosts into upgrading their PHP installs. My host told me that he’s tried this but it often results in broken sites because users don’t have their plugins updated in the first place and many are using plugins that are no longer maintained by anyone.

WordPress does a pretty good job of alerting you that a plugin is no longer maintained if you actually visit the WordPress plugin website but once you’re in the backend you (shudder) have to actually read! And worse, once you have a plugin installed you have no idea when it was last updated by the plugin author unless you (double shudder) click and then read on each individual plugin. Who has the time?

Seriously, I actually do click and read, but most people don’t.

This lead me to build a quick plugin to query the WordPress API servers for each plugin and ask them when each plugin was last updated. You can download the Vendi Abandoned Plugin Check here. Version 1 will query the servers daily and update your plugin listing screen with the number of days since the last SVN check-in.

Unfortunately it needs WordPress 3.4 or greater because of improvements made to the built-in HTTP request methods. I spent a while trying to get it working in 3.3 but eventually had to give up.

If I get a chance, version 2 will add support for alerting on the plugin install screen itself for abandoned plugins. Version 3 will add a management screen where you can actually configure a couple of settings like “how old is abandoned (currently 365 days, half of WordPress’s 2 year)” and possibly excluding plugins from the check.

Written by Chris Haas

October 30th, 2014 at 12:08 pm

Posted in Plugins,WordPress

WordPress VIP Scanner – Undefined index: slug

leave a comment

We just started playing with WordPress’s VIP scanning plugin but ran into an issue when trying to scan with the WordPress coding standards.

PHP Notice:  Undefined index: slug in /var/www/wp-content/plugins/vip-scanner-master/vip-scanner/checks/WordPressCodingStandardsCheck.php on line 173

After a little bit of digging we found that there’s a problem with the way that the scanning tool parses the results of PHP_CodeSniffer (or there’s a problem with how PHP_CodeSniffer writes results or there’s a problem with WordPress’s implementation of PHP_CodeSniffer rulesets, I guess this is a matter of perspective). Since no one is mentioning this I’m guessing that the problem might be related to my install but I decided to document it here just in case.

Anyway, results are supposed to look like:

Line is indented with space not tab (WordPress.WhiteSpace.PhpIndent.Incorrect)
No space after opening parenthesis of function definition prohibited (WordPress.Functions.FunctionCallSignature)
No space before closing parenthesis of function definition prohibited (WordPress.Functions.FunctionCallSignature)

Or more generically:


The regex that handles this in on line 41 of /vip-scanner/checks/WordPressCodingStandardsCheck.php:

private $sniffer_slug_regex = '/\((?P<slug>(\w+\.)+\w+)\)/';

For whatever reason, some rules are coming through ending in a period (or missing the last word, perspective again) and looking like this:

Detected access of super global var $_POST, probably need manual inspection. (WordPress.VIP.SuperGlobalInputUsage.)

Note the period inside of the parentheses.

In the regex above, the (\w+\.)+ means “find one or more words that each end in a period“. This is then followed up by \w+ which means “plus one more word”. Combined this means “find a bunch of words separated by periods but doesn’t end in a period” which is what is breaking the rule above.

The solution is to just switch to a simpler capture that uses a character class of [\w\.]+ which means “find a bunch of things that are words or periods”. Technically this matches A..B and .A.B as well as our desired A.B. but at least it doesn’t break anymore.

So the final solution is to change line 41 to:

private $sniffer_slug_regex = '/\((?P[\w\.]+)\)/';

Written by Chris Haas

October 3rd, 2014 at 2:17 pm

Posted in VIP,WordPress

Varnish as a frontend for a remote WordPress install – Part 2

leave a comment

Part of this setup Nginx, MySql, PHP and WordPress. This part is for configuring Varnish 4.0 on Ubuntu 14.04

On varnish.chris.example.com

Install Varnish 4.0

  1. Add Varnish’s GPG key
    curl https://repo.varnish-cache.org/ubuntu/GPG-key.txt | sudo apt-key add -
  2. Add the source location
    echo "deb https://repo.varnish-cache.org/ubuntu/ trusty varnish-4.0" | sudo tee /etc/apt/sources.list.d/varnish-cache.list
  3. Update local cache
    sudo apt-get update
  4. Perform a version check to make sure that Varnish 4.0 is listed:
    sudo apt-get install -s varnish
  5. Install
    sudo apt-get install varnish

Configure Varnish

  1. Edit the main config file for Varnish
    sudo vi /etc/default/varnish
  2. Change the 6081 to 80 in this block.

    DAEMON_OPTS="-a :6081 \
                 -T localhost:6082 \
                 -f /etc/varnish/default.vcl \
                 -S /etc/varnish/secret \
                 -s malloc,256m"


    DAEMON_OPTS="-a :80 \
                 -T localhost:6082 \
                 -f /etc/varnish/default.vcl \
                 -S /etc/varnish/secret \
                 -s malloc,256m"
  3. Restart Varnish
    sudo service varnish restart

Written by Chris Haas

September 27th, 2014 at 12:25 pm