# This nginx configuration defines two servers, one on port 80 and one on port
# 443. All traffix on port 80 is redirect to port 443 on SSL.
#
# Nginx proxies all requests on port 443 to upstream the application server
# which is expected to be running on port 5000/5001.

upstream ui_server {
  server web-ui:5000 fail_timeout=0;
}
upstream api_server {
  server web-api:5000 fail_timeout=0;
}

# HTTP server
server {
  # Redirects all requests to https. - this is in addition to HAProxy which
  # already redirects http to https. This redirect is needed in case you access
  # the server directly (e.g. useful for debugging).
  listen 80 default_server; # IPv4
  listen [::]:80 default_server; # IPv6
  server_name _;
  return 301 https://$host$request_uri;
}

# HTTPS server
server {
  listen 443 default_server ssl http2; # IPv4
  listen [::]:443 default_server ssl http2; # IPv6
  server_name _;
  charset utf-8;
  keepalive_timeout 5;

  # SSL configuration according to best practices from
  # https://mozilla.github.io/server-side-tls/ssl-config-generator/
  # The provided certificate (test.crt) and private key (test.key) is only for
  # testing and must never be used in production environment.
  ssl_certificate /etc/ssl/certs/test.crt;
  ssl_certificate_key /etc/ssl/private/test.key;
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:50m;
  ssl_session_tickets off;

  # Accepted protocols and ciphers
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
  ssl_prefer_server_ciphers on;

  add_header Strict-Transport-Security "max-age=15768000"; # 6 months

  # Request ID tracing (allows end-to-end tracking of requests for better
  # troubleshooting)
  add_header X-Request-ID $request_id;

  # The request body is sent to the proxied server immediately as it is
  # received
  proxy_request_buffering off;
  # Sets the HTTP protocol v1.1 for proxying in order to not use the buffer
  # in case of chunked transfer encoding
  proxy_http_version 1.1;

  # Proxying to the application server
  ## UI server
  location / {
    uwsgi_pass ui_server;
    include uwsgi_params;
    uwsgi_buffering off;
    uwsgi_request_buffering off;
    chunked_transfer_encoding off;
    uwsgi_param Host $host;
    uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
    uwsgi_param X-Forwarded-Proto $scheme;
    # Pass request id to the ui server
    uwsgi_param X-Request-ID $request_id;
    # X-Session-ID / X-User-ID is read by nginx and included in the logs,
    # however we don't want to expose them to clients so we are hiding them.
    uwsgi_hide_header X-Session-ID;
    uwsgi_hide_header X-User-ID;
    # Max upload size (except for files) is set to 100mb as default.
    client_max_body_size 100m;
  }
  ## Most API
  location /api {
    uwsgi_pass api_server;
    include uwsgi_params;
    uwsgi_buffering off;
    uwsgi_request_buffering off;
    chunked_transfer_encoding off;
    uwsgi_param Host $host;
    uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
    uwsgi_param X-Forwarded-Proto $scheme;
    # Pass request id to the api server
    uwsgi_param X-Request-ID $request_id;
    # X-Session-ID / X-User-ID is read by nginx and included in the logs,
    # however we don't want to expose them to clients so we are hiding them.
    uwsgi_hide_header X-Session-ID;
    uwsgi_hide_header X-User-ID;
    # Max upload size (except for files) is set to 100mb as default.
    client_max_body_size 100m;
  }
  ## API files
  # Another location is defined in order to allow large file uploads in the files
  # API without exposing the other parts of the application to receive huge
  # request bodies.
  location ~ /api/records/.+/draft/files/.+/content {
    gzip off;
    uwsgi_pass api_server;
    include uwsgi_params;
    uwsgi_buffering off;
    uwsgi_request_buffering off;
    chunked_transfer_encoding off;
    uwsgi_param Host $host;
    uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
    uwsgi_param X-Forwarded-Proto $scheme;
    # Pass request id to api server
    uwsgi_param X-Request-ID $request_id;
    # X-Session-ID / X-User-ID is read by nginx and included in the logs,
    # however we don't want to expose them to clients so we are hiding them.
    uwsgi_hide_header X-Session-ID;
    uwsgi_hide_header X-User-ID;
    # Max upload size for files is set to 50GB (configure as needed).
    client_max_body_size 50G;
  }
  # Static content is served directly by nginx and not the application server.
  location /static {
    alias /opt/invenio/var/instance/static;
    autoindex off;
  }
  # Robots.txt file is served by nginx.
  location /robots.txt {
    alias /opt/invenio/var/instance/static/robots.txt;
    autoindex off;
  }
}
