Variabel Bawaan

Variabel Bawaan #

Nginx menyediakan banyak variabel yang tersedia di seluruh konfigurasi — dari dalam log_format, proxy_set_header, return, sampai kondisi if. Variabel ini terisi secara otomatis dari data request, koneksi, atau konfigurasi server. Memahami variabel yang paling umum digunakan akan membuat konfigurasi kamu jauh lebih dinamis.

Variabel Request #

Variabel-variabel ini berisi informasi tentang HTTP request yang masuk:

# URL dan path
$uri              # Path URL setelah normalisasi (tanpa query string)
                  # /about → /about, /About/../about → /about
$request_uri      # Path URL asli termasuk query string, tidak dinormalisasi
                  # /search?q=nginx&page=1 → /search?q=nginx&page=1
$args             # Query string tanpa tanda tanya
                  # ?q=nginx&page=1 → q=nginx&page=1
$arg_NAME         # Nilai query parameter tertentu
                  # $arg_q → "nginx", $arg_page → "1"
$is_args          # "?" jika ada query string, string kosong jika tidak

# Method dan versi
$request_method   # GET, POST, PUT, DELETE, dll.
$server_protocol  # HTTP/1.0, HTTP/1.1, HTTP/2.0
$request          # Baris pertama request: "GET /path HTTP/1.1"

# Body request
$content_length   # Nilai header Content-Length
$content_type     # Nilai header Content-Type

# Header request (akses header apapun dengan $http_NAMA)
$http_host        # Nilai header Host
$http_user_agent  # Nilai header User-Agent
$http_referer     # Nilai header Referer
$http_cookie      # Semua cookie dalam satu string
$http_x_forwarded_for  # Header X-Forwarded-For (IP asli dari proxy/load balancer)

Variabel Koneksi dan Server #

# Informasi koneksi klien
$remote_addr      # IP address klien
$remote_port      # Port klien
$binary_remote_addr  # IP klien dalam format binary (berguna untuk limit_req_zone)

# Informasi server
$server_addr      # IP address server yang menerima koneksi
$server_port      # Port server yang menerima koneksi
$server_name      # Nama server yang cocok (dari server_name directive)

# SSL/TLS (hanya tersedia jika koneksi menggunakan HTTPS)
$scheme           # "http" atau "https"
$https            # "on" jika HTTPS, string kosong jika HTTP
$ssl_protocol     # Versi TLS: TLSv1.2, TLSv1.3
$ssl_cipher       # Cipher yang digunakan

Variabel Response dan Upstream #

# Response
$status           # HTTP status code yang dikirim ke klien
$body_bytes_sent  # Jumlah bytes body response yang dikirim
$bytes_sent       # Total bytes yang dikirim (termasuk header)

# Upstream (tersedia saat menggunakan proxy_pass)
$upstream_addr           # IP:port backend yang menangani request
$upstream_status         # HTTP status code dari backend
$upstream_response_time  # Waktu respons backend dalam detik
$upstream_cache_status   # HIT, MISS, BYPASS, EXPIRED, dll.

$upstream_cache_status sangat berguna untuk debugging cache:

location / {
    proxy_pass http://backend;
    proxy_cache my_cache;

    # Tambahkan header ini untuk debug — hapus di production!
    add_header X-Cache-Status $upstream_cache_status;
}

Variabel Waktu #

$time_local       # Waktu lokal saat request: "15/Jan/2024:10:30:45 +0700"
$time_iso8601     # Format ISO 8601: "2024-01-15T10:30:45+07:00"
$msec             # Unix timestamp dalam milidetik: "1705287045.123"
$request_time     # Total waktu pemrosesan request dalam detik (float)
                  # Diukur dari saat byte pertama diterima hingga byte terakhir dikirim

Variabel yang Sering Digunakan Bersama #

Dalam log_format #

http {
    log_format main '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

    # Format yang lebih informatif untuk debugging proxy
    log_format proxy '$remote_addr - [$time_local] '
                     '"$request" $status '
                     'upstream: $upstream_addr '
                     'resp_time: $upstream_response_time '
                     'cache: $upstream_cache_status';

    access_log /var/log/nginx/access.log main;
}

Dalam proxy_set_header #

location / {
    proxy_pass http://backend;

    # Beritahu backend IP asli klien
    proxy_set_header X-Real-IP $remote_addr;

    # Kumpulkan chain IP jika melewati beberapa proxy
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # Beritahu backend apakah koneksi asal HTTP atau HTTPS
    proxy_set_header X-Forwarded-Proto $scheme;

    # Pertahankan header Host asli
    proxy_set_header Host $host;
}

Dalam return dan rewrite #

# Redirect dengan mempertahankan path dan query string
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

# Redirect non-www ke www
server {
    listen 80;
    server_name example.com;
    return 301 $scheme://www.example.com$request_uri;
}

Menggunakan if dengan Variabel #

Nginx mendukung blok if, tapi penggunaannya sangat dibatasi dan sering menjadi sumber bug. Ada alasan komunitas Nginx menyebutnya “if is evil” — ia tidak berperilaku seperti if di bahasa pemrograman biasa.

# Penggunaan if yang aman — hanya untuk redirect/return
server {
    if ($scheme = http) {
        return 301 https://$host$request_uri;
    }
}

# Cek nilai header tertentu
location / {
    if ($http_user_agent ~* "bot|crawler|spider") {
        return 403;
    }
    proxy_pass http://backend;
}
# ANTI-PATTERN: if di dalam location dengan proxy_pass
location / {
    if ($request_method = POST) {
        proxy_pass http://write_backend;  # ← Ini bisa berperilaku tidak terduga
    }
    proxy_pass http://read_backend;
}

# BENAR: Gunakan location terpisah
location / {
    proxy_pass http://read_backend;
}
location / {
    limit_except GET HEAD {
        proxy_pass http://write_backend;
    }
}
Hindari menggunakan if dalam location block jika bisa diselesaikan dengan cara lain (location terpisah, map, atau geo). Satu-satunya penggunaan if yang benar-benar aman adalah di level server context untuk redirect/return.

Variabel Kustom dengan map #

Untuk logika yang lebih kompleks, Nginx menyediakan directive map yang jauh lebih aman dari if:

http {
    # Buat variabel $is_mobile berdasarkan User-Agent
    map $http_user_agent $is_mobile {
        default         0;
        ~*mobile        1;
        ~*android       1;
        ~*iphone        1;
    }

    # Buat variabel $cache_bypass berdasarkan kondisi
    map $request_method $cache_bypass {
        default  0;
        POST     1;
        PUT      1;
        DELETE   1;
    }

    server {
        location / {
            proxy_pass http://backend;
            proxy_cache_bypass $cache_bypass;   # Bypass cache untuk non-GET
        }

        # Redirect ke versi mobile jika $is_mobile = 1
        location / {
            if ($is_mobile) {
                return 302 https://m.example.com$request_uri;
            }
        }
    }
}

map dievaluasi secara lazy — hanya saat variabel yang dihasilkannya digunakan, dan hanya sekali per request. Ini jauh lebih efisien dan mudah diprediksi dibanding if yang bercabang.


Ringkasan #

  • Variabel request ($uri, $args, $request_method, $http_*) berisi informasi tentang request yang masuk.
  • $remote_addr adalah IP klien langsung; gunakan $http_x_forwarded_for jika server berada di balik load balancer.
  • $scheme (“http”/“https”) dan $host sering digunakan bersama untuk redirect yang benar.
  • $upstream_response_time dan $upstream_cache_status sangat berguna untuk log debugging proxy.
  • Hindari if di dalam location block — gunakan map atau geo untuk logika kondisional yang lebih aman dan lebih efisien.

← Sebelumnya: Location Block   Berikutnya: Serving Static Files →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact