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}")