Portrait Michael Malura

How I Do Redirects with Nginx and Test Them with Python

I needed a way to easily and quickly define lots of redirects for my blog. In this post I want to present my solution.

First a .map file has to be created. Each line represents one redirect and should have the following format FROM TO;. It's important to end each line with a ;.

/posts /blog;
/en/blog /blog;
/en/todo.html /blog/todo;

The nginx server configuration should look like this.

map_hash_bucket_size 256;

map $uri $redirected_url {
  default "none";
  include /etc/nginx/redirects.map;
}

server {
  # ...
  if ($redirected_url != "none") {
    return 301 $redirected_url;
  }
  # ...
}

This Python script can be used to test the redirects. It loads each line of the redirects.map, makes a request to it and checks whether it redirected correctly.

import requests
from urllib.parse import urljoin

class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

base = 'https://malura.de'

redirect_count = 0
redirect_success_count = 0

with open('redirects.map') as fp:
    for cnt, line in enumerate(fp):
        redirect_count += 1
        [url, redirect] = [urljoin(base, chunk.strip().replace(';', '')) for chunk in line.split(' ')]
        r = requests.get(url, allow_redirects=False)

        redirected_location = r.headers['Location']
        if redirected_location != redirect:
            print("{} -> {} = {}".format(url, redirect, redirected_location))
        else:
            redirect_success_count += 1

if redirect_success_count != redirect_count:
    print(f"{bcolors.FAIL}{redirect_count - redirect_success_count} redirects didnt work{bcolors.ENDC}")
11.02.2020 updated 27.06.2026
Share X Reddit Hacker News LinkedIn E-Mail