This page looks best with JavaScript enabled

Nginx Rewrite URL

 ·  β˜• 4 min read

    NGINX rewrite and return rules are used to change the URL requested.

    The are many reasons to change totally or in part the URL requested, common examples are
    keeping url clean removing the extension (blogs), redirect content from a domain to another.

    The are two main directives to do such job: return and rewrite.
    Both the directives perform the same function, but the rewrite directive can do parsing of the url and thus is more flexible and customizable than the return directive.

    Rewrite Module Documentation

    we will be using the same piece of configuration chaging only code in the commented part.

    server {
        listen 80;
        server_name example.com;
        root /var/www/default/;
        error_log /var/log/nginx/example_error.log error;
        access_log /var/log/nginx/example_access.log combined;
    
        #--- BEGIN DIRECTIVES ---#
    
        #--- END DIRECTIVES ---#
    
        error_page 404 /404.html;
    }
    
    

    Return

    Syntax: return code [text];
            return code URL;
            return URL;
    Default: β€”
    Context: server, location, if
    

    Return stops processing and returns the specified code to a client, so no further operations will be perfomerd by the server. Notice the the context can be either server or location.

    There area 3 possibile ways to use the return keyword:

    • return a status code an a message test (es. 404 NOT FOUND)
    • return a status code and a URL to be redirected to (301 http://newsite.dev)
    • return a URL to be redirected to

    Return Redirect

    $sheme is the protolo (http|https) while $request_uri is the resource requested on the server

    return 301 $scheme://www.newsite.com$request_uri;
    

    This will redirect for example from http://example.com/admin.html to http://www.newsite.com/admin.html sending the status code 301 (Moved Permanently), obiviously you can redirect only the $requested_uri to a fixed one.

    Sending a permanent redirect code 301 makes the browser forget the original address entirely and prevents it from attempting to access that address anymore.

    It is possible to specify a redirect URL for different codes such as 301, 302, 303, 307 or a response body text for codes such as 1xx, 2xx, 4xx, 5xx.

    List of Http codes

    Other examples:

    return 401 "Access denied";
    
    return 404 "Try Later, I'm not here";
    
    return 403 "Service unavailable"
    

    Dropping Requests for unwanted extensions

    if URL location contains one of the listed extensions Nginx returns tha status code 410 (Gone) that indicates that the resource is permantently unavailable.

    location ~ .(aspx|asp|jsp|cgi)$ {
        return 410 "no no no";
    }
    

    Rewrite

    Syntax: rewrite regex replacement [flag];
    Default: β€”
    Context: server, location, if
    

    The rewrite directive is a little more complex.
    The syntax is:

    rewrite regex replacement [flag];
    

    where regex is a regualar expression matched againt the requested URI, the replacement part indicates what to change in the requested URI, and the flag is use to perform more processings in the rewrite or stops. In fact if a new rewritten url mathches another rewrite directive you can choose to proced with the rewrite of the URI or not using the flag.

    Flag can be

    last
    stops processing the current set of ngx_http_rewrite_module directives and starts a search for a new location matching the changed URI;
    break
    stops processing the current set of ngx_http_rewrite_module directives as with the break directive;
    redirect
    returns a temporary redirect with the 302 code; used if a replacement string does not start with β€œhttp://”, β€œhttps://”, or β€œ$scheme”;
    permanent
    returns a permanent redirect with the 301 code.

    A rewrite directive will only return an HTTP 301 or 302 status code, if you need to return a differente status code an explicit return directive must be inserted after the rewrite directive.

    Get File

    Suppose to have media files organized in subfolders such as /media/mp3 or /media/pdf. We can access simply rewriting the url and indicating the name og the file in this way

    http://exameple/mp3/zappa or http://exameple/pdf/catalog but in reality the files will be found in /media/mp3/zappa.mp3 or /media/pdf/catalog.pdf

    rewrite ^/(.*)/(.*)$ /media/$1/$2.$1 last;
    

    The first (.*) is matched with mp3 and the second with zappa and would be assigned to $1 and $2 variables and used in replacement url.

    Clean URLs

    Remove the .html extensions from the url making the URL more readable.

    rewrite ^(/.*)\.html(\?.*)?$ $1$2 redirect;
    rewrite ^/(.*)/$ /$1 redirect;
    
    location / {
        try_files $uri/index.html $uri.html $uri/ $uri =404;
    }
    

    The try_files directive indicates to the server to check for the existence of index.html file inside $uri directory , then for a $uri.html file, then directory $uri/ and finally for a file named $uri.

    If nothing is found, Nginx returns a status 404.

    try_files manual page

    Rewrite dynamic URLs

    Suppose to have a url like this http://example.com/profile.html?userid=32 and we want to rewrite to something more readable, somthing like http://example.com/profile/32.

    rewrite ^/profile/(.*)$ /profile.html?userid=$1 last;
    

    Redirect HTTP to HTTPS

    return 301 https://$host$request_uri;
    

    Add WWW to domain

    if ( $host !~ ^www\. ) {
        return 301 $scheme://www.$host$request_uri;
    }