Модуль 8

Location blocks та правила маршрутизації

Ось готовий урок, створений у стилі Девіда Малана (CS50) за твоїм майстер-промптом.


🎓 УРОК: Location Blocks та Магія Маршрутизації (Nginx)

Привіт, світе! Це CS50... тобто, це ваш урок з налаштування веб-серверів! 👋

Сьогодні ми зазирнемо під капот того, як інтернет "знає", куди вас відправити, коли ви вводите адресу в браузер. Ми поговоримо про Location blocks (блоки локацій) та правила маршрутизації в Nginx.


1. 🔥 Вступ: Куди я потрапив?

Уявіть, що ви заходите у величезний готель. Це наш сервер. Ви підходите до рецепції (це Nginx) і кажете: "Я хочу в басейн". Ресепшіоніст дивиться на мапу і каже: "Вам ліворуч, по коридору".

Але що, якщо ви скажете: "Я хочу в кімнату 101"? Вас направлять у ліфт. А якщо ви скажете: "Я хочу поговорити з директором"? Вас поведуть у пентхаус.

Проблема: Як ресепшіоніст (сервер) розуміє, куди саме вас направити, базуючись лише на парі слів, які ви сказали? Що буде, якщо ви скажете "Я хочу в кімнату 101", але в готелі є правило: "Всіх, хто запитує кімнати, спочатку перевіряти на наявність ключа"?

Без Location blocks ваш сервер — це просто ресепшіоніст, який усім відвідувачам, незалежно від прохання, видає одну й ту ж саму брошуру "Ласкаво просимо". Це нудно і, чесно кажучи, не працює для сучасних веб-додатків.

Нам потрібно навчити сервер розрізняти: * Користувач хоче завантажити картинку? 🖼️ * Користувач хоче отримати дані через API? 🤖 * Користувач просто зайшов на головну сторінку? 🏠

Якщо ви не зрозумієте цю тему, ваші сайти будуть видавати помилку 404 Not Found частіше, ніж працювати. Тож розберімося з цим!


2. 🧠 Теоретична база: Як думає сервер?

Коли Nginx отримує запит (наприклад, mysite.com/images/cat.jpg), він дивиться тільки на частину після домену: /images/cat.jpg. Це називається URI.

Його завдання — знайти у конфігурації блок location, який найкраще відповідає цьому URI.

Але тут є нюанс. Це не просто "хто перший, того й капці". Це змагання на точність.

🛠 Ключові гравці (Модифікатори):

  1. Точний збіг (=):
    • location = /login { ... }
    • Це снайпер. Працює тільки якщо адреса ідеально збігається. Найвищий пріоритет.
  2. Префіксний збіг (без знаків):
    • location /images/ { ... }
    • Це як вказівник на район. "Все, що починається з /images/, йде сюди".
  3. Регулярні вирази (~ або ~*):
    • location ~ \.php$ { ... }
    • Це патерни. "Якщо закінчується на .php...".
    • ~ — чутливий до регістру (A != a).
    • ~* — нечутливий до регістру (A == a).

⚙️ Що відбувається "під капотом"? (Логіка вибору)

Уявіть, що Nginx проводить кастинг для вашого запиту:

  1. Спочатку він шукає точні збіги (=). Знайшов? Стоп. Виконуємо.
  2. Якщо ні, він шукає звичайні префікси (найдовший збіг). Запам’ятовує найкращий варіант, але поки не виконує.
  3. Далі він перевіряє регулярні вирази (зверху вниз у файлі). Перший, що підійшов — перемагає і скасовує префікс.
  4. Якщо жоден регулярний вираз не підійшов — використовується той префікс, який ми запам'ятали на кроці 2.

Що треба запам’ятати залізно: Регулярні вирази (Regex) зазвичай мають вищий пріоритет за прості префікси, якщо тільки ви не використаєте спец-хак ^~ (але про це пізніше).


3. 🧪 Приклади: Від простого до реального

Приклад 1: "Двері для всіх"

location / {
    return 200 "Привіт! Це головний вхід.";
}
  • Запит: mysite.com/
  • Запит: mysite.com/anything
  • Результат: Всі потраплять сюди, якщо немає більш точного правила. Це ваш "catch-all" блок.

Приклад 2: Спецвхід для адмінів (Точність)

Додамо ще один блок до попереднього:

location = /admin {
    return 200 "Тільки для обраних.";
}
  • Питання до вас: Що буде, якщо я зайду на mysite.com/admin?
  • Відповідь: Спрацює location = /admin.
  • Питання: А якщо я зайду на mysite.com/admin/settings?
  • Відповідь: Спрацює location / (перший приклад). Чому? Бо знак = вимагає ідеального збігу. /admin не дорівнює /admin/settings.

Приклад 3: Реальний конфлікт (Пастка для новачків) 🚨

Уважно подивіться на цей код:

# Блок А
location /images/ {
    return 200 "Я показую картинки з папки!";
}

# Блок Б
location ~ \.(jpg|png)$ {
    return 200 "Я обробляю картинку як Regex!";
}

Я роблю запит: mysite.com/images/logo.png.

  • Який блок спрацює? А чи Б?
  • Здається, що А, бо там написано /images/, правда?
  • Ні! Спрацює Блок Б.

Чому? Пам'ятаєте алгоритм? Nginx знайшов префікс /images/ (Блок А), запам'ятав його, але пішов перевіряти регулярні вирази. Блок Б підійшов (.png). Регулярка перебила префікс.


4. 🛠 Практична частина

Час забруднити руки кодом. Уявіть, що ви налаштовуєте сервер для стартапу.

Завдання 1: База Напишіть конфіг, де за адресою / віддається файл index.html, а за адресою /hello сервер відповідає текстом "Welcome to CS50!".

Завдання 2: Захист У вас є секретний файл config.json. Напишіть правило location, яке забороняє доступ до цього конкретного файлу (повертає помилку 403), навіть якщо він лежить у відкритій папці. Підказка: використовуйте точний збіг.

Завдання 3: API Всі запити, що починаються з /api/ (наприклад, /api/users, /api/posts), мають проксуватися на інший сервер http://localhost:3000. Напишіть цей блок.

Завдання 4: Пріоритети (Кейс) У вас є така конфігурація:

location /static/ { ... }
location ~* \.css$ { ... }

Користувач запитує /static/style.css. Який блок спрацює і чому? Як змусити працювати саме перший блок без видалення другого? (Підказка: модифікатор ^~).

Завдання 5: "А що, якщо..." Що станеться, якщо у вас є два однакових регулярних вирази в конфігу?

location ~ \.php$ { return 200 "First"; }
location ~ \.php$ { return 200 "Second"; }

Який з них виграє?


5. 💡 Мислення як у розробника

Як досвідчений інженер дивиться на Nginx-конфіг?

  1. "Keep it simple". Регулярні вирази (~) — це потужно, але повільно. Якщо ви можете обійтися простим префіксом (/images/) або точним збігом (= /favicon.ico) — робіть це. Це економить процесорний час.
  2. Порядок має значення (для Regex). На відміну від префіксів, де Nginx шукає "найдовший", регулярки перевіряються зверху вниз. Поставите загальну регулярку над специфічною — специфічна ніколи не спрацює.
  3. Тестування. Ніколи, чуєте, ніколи не перезавантажуйте "живий" сервер без команди nginx -t. Вона перевіряє синтаксис. Це як скомпілювати код перед запуском.

Типова помилка новачка: Думати, що location block — це папка на диску. Ні! Це просто правило маршрутизації. В блоці location /apples ви можете наказати серверу брати файли з папки oranges.


6. 🧩 Підсумок

Отже, що ми сьогодні зробили? Ми перетворилися з розгубленого швейцара на професійного диспетчера трафіку.

Тепер ви вмієте: * ✅ Створювати "входи" для різних частин вашого сайту. * ✅ Розуміти, хто переможе: префікс чи регулярка. * ✅ Захищати конкретні файли та налаштовувати API-шлюзи.

Ви більше не боїтеся магії маршрутизації. Ви нею керуєте.

Що далі? Тепер, коли ми вміємо ловити запити, наступного разу ми поговоримо про Rewrite rules. Це коли користувач просить "каву", а ви непомітно підміняєте замовлення на "чай", і він навіть не здогадується. Це магія підміни URL на льоту!

А поки що... це був CS50! 🏛️