Testing HTTP redirects with Curl

We’ve got a really complex redirection setup for the current project at work, a mix of some general rules (http://blog.example.com/ to http://www.example.com/blog/), some oddball domain redirects (http://blog.example.jp/ to http://www.example.co.jp/blog/), and some more esoteric ones thrown in there for luck. I started off briefing my colleague with a description of what I needed, but this very quickly became too complex and I realised I really needed to give him a set of initial URLs and expected results. Why not express these rules in a quick test script? My colleague could run the script against the redirects as he wrote them, and see the successful ones and the failures, along with detail about why they failed.

The first version of the script output the HTTP Status Code and the resultant URL, using these wonderful instructions by Artem. After a discussion with my colleague, I realised it would be better if the script could be run and simply examine the resultant URL rather than the HTTP Status Code to indicate success. This way it’s easier to use a development server for testing, which may not have the right data and so may not return the right HTTP Status Code.

Here’s the script we ended up with, each redirect test is on it’s own line, with the test URL and expected result URL separated by a pipe character (“|”):

#!/bin/bash

(

	# The redirects: test URL and expected URL, separated by a 
	# pipe character
	REDIRECTS=(
		"http://blog.example.com/|http://www.example.com/blog/"
		"http://blog.example.co.uk/|http://www.example.co.uk/blog/"
		"http://blog.example.jp/|http://www.example.co.jp/blog/"
	)

	# Make string comparisons case insensitive, because Apache
	# can cast redirected URLs to lowercase
	shopt -s nocasematch

	# Test each, errrr, test
	for REDIRECT in ${REDIRECTS[@]}; do
		# Split the test on the pipe, and get the first portion 
		# as the test URL
		TEST_URL=`echo $REDIRECT |cut -d '|' -f1 `
		# Split the test on the pipe, and get the second portion
		# as the expected URL resulting from the redirects
		EXPECTED_URL=`echo $REDIRECT |cut -d '|' -f2 `
		# Check the URL using Curl, returning just the HTTP 
		# status code and the URL at the end of the redirections,
		# separated by a space
		RESULT=$(curl -L -s -w "%{http_code} %{url_effective}\\n" "$TEST_URL" -o /dev/null)
		# Split the Curl result by a space, and get the first 
		# portion as the HTTP Status code
		HTTP_CODE=`echo $RESULT |cut -d ' ' -f1 `
		# Split the Curl result by a space, and get the second
		# portion as the URL at the end of the redirections
		URL_EFFECTIVE=`echo $RESULT |cut -d ' ' -f2 `
		# Compare the end URL with the expected URL, output
		# the result as status code, smilie face and, if 
		# there's an error, an explanation
		if [[ "$URL_EFFECTIVE" == "$EXPECTED_URL" ]]; then
			echo "$HTTP_CODE :) $TEST_URL"
		else
			echo "$HTTP_CODE :( $TEST_URL: Expected $EXPECTED_URL, got $URL_EFFECTIVE"
		fi
	done
)

TDD!

UPDATE Thursday 20 March 2014: Commented the Shellscript better.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.