# Nginx frontend configuration for Feersum
# Usage: nginx -c /path/to/nginx-frontend.conf
#
# =============================================================================
# BACKEND OPTIONS
# =============================================================================
#
# 1. PSGI with Plack::Handler::Feersum (simple)
#    TCP:  plackup -s Feersum -p 5000 --keepalive app.psgi
#    Unix: plackup -s Feersum -l /tmp/feersum.sock --keepalive app.psgi
#
# 2. PSGI with Server::Starter + Plack::Handler::Feersum::SS (hot restart)
#    TCP:  start_server --port 5000 -- \
#            plackup -s Feersum::SS -E production \
#            --keepalive --header-timeout 30 app.psgi
#    Unix: start_server --path /tmp/feersum.sock -- \
#            plackup -s Feersum::SS -E production \
#            --keepalive --header-timeout 30 app.psgi
#
# 3. Native interface (maximum performance)
#    TCP:  perl -MFeersum -e '
#            my $f = Feersum->endjinn;
#            my $sock = IO::Socket::INET->new(
#                LocalAddr => "127.0.0.1:5000",
#                ReuseAddr => 1, Listen => 1024
#            ) or die $!;
#            $f->use_socket($sock);
#            $f->set_keepalive(1);
#            $f->header_timeout(30);
#            $f->request_handler(sub {
#                my $r = shift;
#                $r->send_response(200, ["Content-Type" => "text/plain"], "OK");
#            });
#            EV::run;'
#
#    Or use eg/native.pl:
#    perl eg/native.pl 5000
#
# 4. Native with Server::Starter (hot restart + native performance)
#    start_server --port 5000 --backlog 4096 -- \
#      perl -MFeersum -MServer::Starter=server_ports -e '
#        my ($port, $fd) = each %{server_ports()};
#        open(my $sock, "<&=", $fd) or die $!;
#        my $f = Feersum->endjinn;
#        $f->use_socket($sock);
#        $f->set_keepalive(1);
#        $f->header_timeout(30);
#        $f->request_handler(sub { shift->send_response(200, [], "OK") });
#        EV::run;'
#
# BACKLOG TUNING:
#   Feersum uses SOMAXCONN (typically 128) as listen backlog.
#   For high-traffic servers, increase at OS level:
#     Linux:   sysctl -w net.core.somaxconn=4096
#     FreeBSD: sysctl kern.ipc.somaxconn=4096
#   With Server::Starter, use --backlog option as shown above.
#
# =============================================================================

worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}

http {
    # Basic settings
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    # Logging
    access_log /var/log/nginx/access.log;

    # Gzip (optional)
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/javascript text/xml;

    #=========================================================================
    # Option 1: TCP backend
    #=========================================================================
    upstream feersum_tcp {
        server 127.0.0.1:5000;

        # Keepalive connections to backend (important for performance)
        keepalive 64;
        keepalive_requests 1000;
        keepalive_timeout 60s;
    }

    #=========================================================================
    # Option 2: Unix socket backend (faster, no TCP overhead)
    #=========================================================================
    upstream feersum_unix {
        server unix:/tmp/feersum.sock;

        # Keepalive connections to backend
        keepalive 64;
        keepalive_requests 1000;
        keepalive_timeout 60s;
    }

    server {
        listen 80;
        listen [::]:80;
        server_name localhost;

        # Client timeouts (Slowloris protection at nginx level)
        client_header_timeout 30s;
        client_body_timeout 30s;
        send_timeout 30s;

        # Request size limits
        client_max_body_size 100m;
        client_body_buffer_size 128k;

        # Proxy to Feersum (choose TCP or Unix)
        location / {
            # Use one of these:
            proxy_pass http://feersum_tcp;
            # proxy_pass http://feersum_unix;

            # HTTP/1.1 with keepalive to backend
            proxy_http_version 1.1;
            proxy_set_header Connection "";

            # Forward client info
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Port $server_port;

            # Timeouts
            proxy_connect_timeout 5s;
            proxy_send_timeout 60s;
            proxy_read_timeout 60s;

            # Buffering
            proxy_buffering on;
            proxy_buffer_size 4k;
            proxy_buffers 8 16k;
        }

        # WebSocket support (if using psgix.io)
        location /ws {
            proxy_pass http://feersum_tcp;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_read_timeout 3600s;
        }
    }

    # HTTPS server (recommended for production)
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name localhost;

        ssl_certificate /etc/ssl/certs/server.crt;
        ssl_certificate_key /etc/ssl/private/server.key;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
        ssl_prefer_server_ciphers off;

        location / {
            proxy_pass http://feersum_tcp;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
        }
    }
}
