# limit rss requests to 1 r/m
limit_req_zone $binary_remote_addr zone=rsslimit:8m rate=1r/m;

# limit general requests to 20 r/s to block DoS attempts.
limit_req_zone $binary_remote_addr zone=archweblimit:10m rate=20r/s;

limit_req_status 429;

uwsgi_cache_path /var/lib/nginx/cache levels=1:2 keys_zone=archwebcache:10m inactive=60m;
uwsgi_cache_key "$scheme$host$request_uri";

map $uri $cache_key {
    default            $scheme$host$request_uri;
    /devel/mirrorauth/ $scheme$host$request_uri$http_authorization;
}

upstream archweb {
    server unix:///run/uwsgi/archweb.sock;
}

{% if archweb_domains_templates -%}
{% for domain in archweb_domains_templates | dict2items(key_name='domain_name', value_name='template_name') %}
{% include domain['template_name'] %}
{% endfor %}
{%- endif %}

{% if archweb_domains_redirects %}
{% for domain in archweb_domains_redirects | dict2items(key_name='domain', value_name='redirect') %}

server {
    listen       80;
    listen       [::]:80;
    server_name  {{ domain['domain'] }};

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

    include snippets/letsencrypt.conf;

    location /.well-known {
        add_header Access-Control-Allow-Origin *;
        return 301 https://$server_name$request_uri;
    }

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

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

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

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

    location /.well-known {
        add_header Access-Control-Allow-Origin *;
        return 301 https://{{ archweb_domain }}{{ domain['redirect']|default('$request_uri') }};
    }

    location / {
        access_log off;
        return 301 https://{{ archweb_domain }}{{ domain['redirect']|default('$request_uri') }};
    }
}
{% endfor %}

server {
{% else %}

server {
{% endif %}
    listen       80;
    listen       [::]:80;
    server_name  {{ archweb_domain }};

    access_log   /var/log/nginx/{{ archweb_domain }}/access.log reduced;
    access_log   /var/log/nginx/{{ archweb_domain }}/access.log.json json_reduced;
    error_log    /var/log/nginx/{{ archweb_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  {{ archweb_domain }};

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

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

    location /.well-known/matrix/server {
        default_type application/json;
        return 200 '{"m.server": "{{ matrix_domain }}:443"}';
    }

    location /.well-known/matrix/client {
        default_type application/json;
        add_header Access-Control-Allow-Origin *;
        return 200 '{"m.homeserver": {"base_url": "https://{{ matrix_domain }}"}, "m.identity_server": {"base_url": "https://matrix.org"} }';
    }

    location = /robots.txt {
        alias {{ archweb_dir }}/archlinux.org/robots.txt;
    }

    location = /humans.txt {
        alias {{ archweb_dir }}/archlinux.org/humans.txt;
    }

    location = /google7827eadf026b4a87.html {
        alias {{ archweb_dir }}/archlinux.org/google7827eadf026b4a87.html;
    }

    location = /BingSiteAuth.xml {
        alias {{ archweb_dir }}/archlinux.org/BingSiteAuth.xml;
    }

    location = /favicon.ico {
        alias {{ archweb_dir }}/collected_static/favicon.ico;
    }

    location /pacman/ {
        alias {{ archweb_dir }}/archlinux.org/pacman/;
    }

    location /netcfg/ {
        alias {{ archweb_dir }}/archlinux.org/netcfg/;
    }

    location /logos/ {
        alias {{ archweb_dir }}/archlinux.org/logos/;
    }

    location ~ ^/iso/(.*\.(iso|img|tar\.gz|sfs)$) {
        deny all;
    }

    location /iso/ {
        alias {{ archweb_rsync_iso_dir }};
    }

    # Cache django's css, js and png files.
    location /static/ {
        expires 30d;
        add_header Pragma public;
        add_header Cache-Control "public";
        alias {{ archweb_dir }}/collected_static/;
    }

    location /img/ {
        alias {{ archweb_dir }}/media/img/;
    }

    location /retro/ {
        alias {{ archweb_retro_dir }};
    }

    # Rate limit all RSS feeds
    location ~ (^/feeds/|\.xml$) {
        include uwsgi_params;
        uwsgi_pass archweb;

        uwsgi_cache archwebcache;
        uwsgi_cache_revalidate on;
        add_header X-Cache-Status $upstream_cache_status;

        limit_req zone=rsslimit burst=10 nodelay;
    }

    location / {
        access_log   /var/log/nginx/{{ archweb_domain }}/access.log main;
        access_log   /var/log/nginx/{{ archweb_domain }}/access.log.json json_main;
        include uwsgi_params;
        uwsgi_pass archweb;

        uwsgi_cache archwebcache;
        uwsgi_cache_revalidate on;
        uwsgi_cache_key $cache_key;
        add_header X-Cache-Status $upstream_cache_status;

        limit_req zone=archweblimit burst=10 nodelay;
    }
}
