fastcgi_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=wiki:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

# rate limit API endpoint
limit_req_zone $binary_remote_addr zone=api_zone:10m rate=5r/s;

# limit general requests to 10 r/s to block DoS attempts with a burst of 10.
limit_req_zone $binary_remote_addr zone=archwikilimit:10m rate=10r/s;

limit_req_status 429;

upstream archwiki {
    server unix://{{ archwiki_socket }};
}

server {
    listen       80;
    listen       [::]:80;
    server_name  {{ archwiki_domain }};

    access_log   /var/log/nginx/{{ archwiki_domain }}/access.log reduced;
    access_log   /var/log/nginx/{{ archwiki_domain }}/access.log.json json_reduced;
    error_log    /var/log/nginx/{{ archwiki_domain }}/error.log;

    include snippets/letsencrypt.conf;

    location / {
        access_log off;
        return 301 https://$server_name$request_uri;
    }
}

server {
    listen       443 ssl http2;
    listen       [::]:443 ssl http2;
    server_name  {{ archwiki_domain }};

    access_log   /var/log/nginx/{{ archwiki_domain }}/access.log reduced;
    access_log   /var/log/nginx/{{ archwiki_domain }}/access.log.json json_reduced;
    error_log    /var/log/nginx/{{ archwiki_domain }}/error.log;

    ssl_certificate      /etc/letsencrypt/live/{{ archwiki_domain }}/fullchain.pem;
    ssl_certificate_key  /etc/letsencrypt/live/{{ archwiki_domain }}/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/{{ archwiki_domain }}/chain.pem;

    root {{ archwiki_dir }}/public;
    index index.php;

    # Block search bot that apparently never heared the term rate limiting
    if ($http_user_agent ~ "Bytespider$" ) {
        return 403;
    }

    location = /robots.txt {
        alias {{ archwiki_dir }}/robots.txt;
    }

    location ^~ /. {
        log_not_found off;
        deny all;
    }

    # Redirect old URLs to the new short-url (/title/<page>)
    location ~ ^/index.php/(.*)$ {
        return 301 /title/$1$is_args$args;
    }

    # Handling for the article path (pretty URLs)
    location ^~ /title/ {
        rewrite ^ /index.php;
    }

    # Handling for MediaWiki REST API, see https://www.mediawiki.org/wiki/API:REST_API
    location ^~ /rest.php/ {
        rewrite ^ /rest.php;
    }

    # special case for '/load.php' type URLs to cache css/js in nginx to relieve php-fpm
    location = /load.php {
        access_log   /var/log/nginx/{{ archwiki_domain }}/access.log main;
        access_log   /var/log/nginx/{{ archwiki_domain }}/access.log.json json_main;
        fastcgi_pass   archwiki;
        fastcgi_index  index.php;
        include        fastcgi.conf;

        fastcgi_cache wiki;
        fastcgi_cache_valid 200 10m;

        add_header X-Cache $upstream_cache_status;
    }

    # mediawiki API endpoint
    location ~ ^/api\.php {
        limit_req zone=api_zone burst=10 delay=5;
        try_files $uri =404;
        access_log   /var/log/nginx/{{ archwiki_domain }}/access.log main;
        access_log   /var/log/nginx/{{ archwiki_domain }}/access.log.json json_main;
        fastcgi_pass   archwiki;
        fastcgi_index  index.php;
        include        fastcgi.conf;
    }

    # normal PHP FastCGI handler
    location ~ ^/[^/]+\.php$ {
        try_files $uri =404;
        access_log   /var/log/nginx/{{ archwiki_domain }}/access.log main;
        access_log   /var/log/nginx/{{ archwiki_domain }}/access.log.json json_main;
        fastcgi_pass   archwiki;
        fastcgi_index  index.php;
        include        fastcgi.conf;

        limit_req zone=archwikilimit burst=10 nodelay;
    }

    # whitelist known OK directories
    location ~ ^/(?:skins|resources|images|extensions/ArchLinux/modules|extensions/WikiEditor/modules/images/toolbar|extensions/CodeMirror/resources/mode/mediawiki/img)/ {
        expires 30d;
        add_header Pragma public;
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
    }

    # block all other directories
    location ~ ^/[^/]+/ {
        log_not_found off;
        deny all;
    }
}
