Налагоджувати правила rewriterule, або трохи про інтимне життя mod_rewrite

У мене RewriteEngine завжди був досить стресовій темою. Тільки ось недавно я раптом виявив, що все якось вляглося і стало більш-менш зрозуміло. Оскільки я абсолютно звичайна людина, я впевнений, що ситуація помилки конфігурації веб-сервера «діставала» не одного лише мене, і я поспішаю поділитися своїм досвідом.

Вийшло щось середнє між керівництвом по використанню модуля mod_rewrite і своєрідним довідником по конфігурації веб-сервера за допомогою файлу .htaccess. Попутно хотілося б загострити увагу на особливо складних або неочевидних моментах.

Вихідні дані для дослідів



  • Всі досліди проводяться на локальному хості.
  • Встановлено сервер lampp
  • Версія Apache: 2.4.9 (збірка для Unix)
  • В папці / opt / lampp / htdocs / bbb / _engine лежить досвідчений сайт на домені engine.bbb.ru. Зазначена папка є кореневої (DocumentRoot).
  • У кореневій папці сайту лежить всього одна сторінка ind.php.
  • На сайті є одна папка / opt / lampp / htdocs / bbb / _engine / local.
  • У ній лежить один скриптова файл ind1.php

Налаштування віртуальних хостів


Для того, щоб було простіше працювати, налагоджувати і не псувати собі нерви там, де можна цього не робити, добре б налаштувати віртуальні хости з точки зору зручності. Розглянемо найпростіші налаштування, які дуже сильно полегшать нам життя.

налаштовуємо логи


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

Для балки помилок на нашому домені додаємо наступні два рядки.


Перша задає ім'я балки помилок для віртуального сервера і змушує починати новий лог кожні 86400 секунд. Rotatelogs є програмою, яка в загальному випадку входить в комплект веб-сервера Apache і я сподіваюся, що у вас вона теж встановлена.

Другий рядок задає формат кожного рядка балки помилок. Подробиці можна прочитати в документації до сервера Apache. Там все досить зрозуміло. В рамках цієї статті важливо просто мати на увазі, що формат налаштовується.

Для балки доступу я у себе включаю тільки одну сходинку. Формат рядка «за замовчуванням» мене зазвичай влаштовує.


В обох випадках зверніть увагу на шляху до програм веб-сервера і до логам. Ви повинні встановити у себе ті шляхи, які існують на вашому комп'ютері.

Найзагальніші відомості про те, як все працює


в файлі .htaccess. який буде керувати цією папкою. Крім цього ми маємо в своєму розпорядженні нижче цього рядка інші директиви і кілька правил для рерайтинга.

Припустимо, сервер отримує на вхід якийсь урл. RewriteEngine починає цей урл перевіряти, використовуючи правила. Робить він це зверху вниз по порядку. Якщо вхідний урл НЕ ВІДПОВІДАЄ жодному правилу, то він, як то кажуть «проходить». Так, наприклад, припустимо, що у нас є в кореневій папці файл index.php. Якщо вхідний урі "/index.php" не задовольняє жодному правилу, то ми побачимо в браузері результат роботи цього скрипта.

Якщо ми маємо наступне правило


то, очевидно, це правило для урі «index.php» спрацює. В цьому випадку урі буде переписаний на "" і новий урі "/" буде посланий на вхід сервера. І весь процес застосування правил піде заново. Тільки в тому випадку, якщо урі "/" не задовольнить жодному нашому правилом, ми побачимо те, що хочемо. А якщо задовольнить, то він буде знову переписаний і все повториться заново.

Як працює прапор [L]


Напевно, цей прапор вносить особливо багато непорозумінь. Наявність прапора запобігає перевірку вхідного урі на наступні за ним правила, якщо це правило спрацювало. Тільки і всього. Тобто, якщо наш урі «index.php» пройшов перевірку (правило для нього спрацювало), то через наявність прапора [L] ми перериваємо всі наступні перевірки, і веб сервер відразу виробляє рерайтинг «index.php» -> "" і отримує на вхід урі "/" ([INTERNAL REDIRECT]), і все повторюється з початку, з першого правила. А якщо цього прапора немає, то рерайтинг все одно відбувається і перевірка триває з наступного правила. Але урі буде вже змінений, а саме "/".

Розуміння цього процесу відразу запобігає багато циклічних редиректів.

Але дозвольте, чи не означає написане вище, що якщо не використовувати прапор [L], ми заощадимо час і сторінка відкриється швидше? Ми натикаємося на прапор [L] і повинні пройти заново за всіма правилами без винятку, а якщо не ставити прапор [L], то ми зробимо рерайтинг на спрацював правилі, пройдемо до кінця всіх правил і на цьому закінчимо?

Я перевірив. Це не спрацьовує. У разі відсутності прапорів [L], модуль, як і передбачається, замінює урі на спрацював правилі, йде по решті правилам до кінця, потім виробляє [INTERNAL REDIRECT] і все одно проходить з цим урі всіх правил ще раз. Тобто підтверджується те, про що ми писали вище. Це правило, схоже, не має винятків.

Висновок: завжди, коли спрацьовує правило RewriteRule, відбувається [INTERNAL REDIRECT] і повторне застосування всіх правил. Цей другий прохід починається або відразу після застосування правила з прапором [L], або після того, як закінчаться всі правила, якщо працюємо без прапорів [L]. Ситуація «проходу» урла, a вона називається «pass through» може відбутися тільки в тому випадку, якщо жодна правило не було застосовано. Прапор [L] дійсно може зменшити час обробки ури і його слід використовувати всюди, де можливо.

Що є RewriteBase?


Ця інструкція, на мій погляд, просто рекордсмен по незрозумілості! Я б дав їй за це приз! Зважаючи на це у мене є дві історії про цього звіра - коротка і довга. Коротка історія для тих, хто не хоче на цю інструкцію морочитися. Довга для цікавляться.

коротка історія


Якщо ви займаєтеся відносно простим урл-Рерайтінг за допомогою файлів .htaccess, то рекомендую завжди поступати таким чином.


  • Не застосовувати препарат описувану директиву взагалі.
  • У всіх правилах рерайтинга цільової урл завжди починати із слеша (вказівка ​​на те, що урі вказується щодо кореня сайту)
Довга історія


При рерайтинг відбуватимуться наступні процеси:

маємо:

  • Document Root: / opt / lampp / htdocs / bbb / _engine
  • Файл .htaccess лежить там же, в Document Root

Ми запитуємо урл engine.bbb.ru/ind.php

  • Сервіс рерайтинга призведе шлях запитуваної файлу до його шляху в файлової системі, а саме opt / lampp / htdocs / bbb / _engine / ind.php
  • Видалить з нього префікс opt / lampp / htdocs / bbb / _engine / (збігається з шляхом до папки, в якій лежить .htaccess)
  • Застосовуватиме правила рерайтинга, використовуючи рядок «ind.php»

Якщо в папці / opt / lampp / htdocs / bbb / _engine / local немає файлу .htaccess або є, але в ньому не включений RewriteEngine

  • Ми запитуємо урл engine.bbb.ru/local/ind1.php
  • Сервіс рерайтинга призведе шлях запитуваної файлу до його шляху в файлової системі, а саме opt / lampp / htdocs / bbb / _engine / local / ind1.php
  • Видалить з нього префікс opt / lampp / htdocs / bbb / _engine /
  • Застосовуватиме правила рерайтинга, використовуючи рядок «local / ind.php»
Якщо в папці / opt / lampp / htdocs / bbb / _engine / local є файл .htaccess і в ньому включений RewriteEngine

  • Ми запитуємо урл engine.bbb.ru/local/ind1.php
  • Сервіс рерайтинга призведе шлях запитуваної файлу до його шляху в файлової системі, а саме opt / lampp / htdocs / bbb / _engine / local / ind1.php
  • Видалить з нього префікс opt / lampp / htdocs / bbb / _engine / local / (це шлях до папки, де лежить файл .htaccess директорії / local)
  • Застосовуватиме правила рерайтинга, використовуючи рядок «ind1.php»

Увага! Такий алгоритм буде виконуватися завжди. Цей алгоритм висловлює специфіку терміна "per-dir", тобто "по-діректорной" підходу, закладеного в сервері Apache. Значення директиви RewriteBase ніяк на нього (на алгоритм) не впливає.
На що ж впливає директива RewriteBase?


Потрібно дуже добре пам'ятати, що в директиві RewriteBase вказується URL! Не можна вказати там "local /" Буде помилка! Можна тільки "/ local".

Нехай в нашому /opt/lampp/htdocs/bbb/_engine/local/.htaccess ми вказали


Ми запитуємо урл engine.bbb.ru/local/


Чи спрацює! І буде здійснено перехід на урі /local/ind1.php


теж спрацює, але перехід буде здійснено на урі /ind1.php. Файл не знайдено! Такого урі (щодо кореня сайту) у нас немає!

Висновок 1: URL, який ми вказуємо в RewriteBase додається в якості префікса до цільового урі в тому випадку, якщо він є відносним, тобто на початку немає слеша.

Висновок 2: Якщо ми ніколи не використовуємо відносні цільові урі в правилах, то і директива RewriteBase нам не потрібна!

Висновок 3: Якщо ми використовуємо «RewriteBase /», то при спрацьовуванні правила


Буде спроба перейти на урі /ind1.php. Ми просто використовуємо "/" в якості префікса.

Ми маємо такі правила RewriteEngine в кореневому .htaccess:

Якщо RewriteBase є урлом, то давайте встановимо


Ні. Не проходить. Помилка "RewriteBase: argument is not a valid URL". Дивно, правда? Але ми не здаємося! Міняємо RewriteBase!


У цьому випадку помилки немає! Що ж у нас відбувається з шляхами? Дуже багато цікавого!
Сервер чесно отримує шлях / opt / lampp / htdocs / bbb / _engine /. видаляє з нього префікс / opt / lampp / htdocs / bbb / _engine / і працює з нового рядка ( '').
Натикаємося на правило і міняємо порожній рядок на 'ind.php'
Чесно додаємо префікс "//bbb.ru" і вирушаємо на наступний прохід. Цей другий прохід відповідає виклику engine.bbb.ru//bbb.ru/ind.php. що, за великим рахунком є ​​зовсім не тим, що ми хотіли (було початкове бажання стрибнути на інший сайт). Коротше, ідея себе не виправдала. В результаті у нас виникає помилка 404, що логічно. До речі, "//" були в процесі рерайтинга замінені сервером на "/". Трасування цього прикладу дана значно нижче.

Як я отримав всі ці захоплюючі дух відомості про інтимне життя сервера Apache? Або нарешті про налагодження


Дійсно! Як я побачив помилки, який видає сервіс перейменування урлов? Адже саме це і є налагодження! Є дуже корисна директива, яку я вставив в віртуальні хости для домену engine.bbb.ru. А саме

А що таке "warn"? Буквально наша запис LogLevel означає, що для всіх модулів рівень помилок warn і тільки для модуля rewrite - trace4

Що ми отримуємо в результаті включення налагодження?

Уявляю трасування рерайтинга з наступними умовами:

Налагодження діє саме для того віртуального хоста, для якого вказана


Якщо домен engine.bbb.ru використовує зовнішні стилі css, які беруться з домену bbb.ru. і проблема саме в цьому, то не треба включати налагодження в межах віртуального сервера engine.bbb.ru, а треба включати в віртуальному сервері bbb.ru. Тоді всі виклики до домену bbb.ru треба дивитися в логах помилок (не доступний!) Домену bbb.ru. При цьому викликів до трассируемого об'єктів не буде в логах доступу взагалі!

А можна не користуватися настільки стресовим RewriteEngine взагалі?


Можна перейти на використання всього одного скрипта на весь сайт і робити весь рерайтинг в ньому. На PHP це зробити легше, та й налагоджувати куди простіше. Крім явних переваг у питаннях безпеки сайту, ми отримуємо зручність рерайтинга без нервування. Для того, щоб перейти на таку схему роботи, наш .htaccess повинен бути приблизно такий:

І в скрипті dispatch.php дуже раджу не забути заборонити прямий виклик самого dispatch.php.

Якщо вам цей підхід раптом захочеться перейняти, то рекомендую скрипт dispatch.php назвати як-небудь інакше. Я використовував цю назву тільки в цілях наочності.

До слова, цей підхід впроваджується досить активно. Цьому ми повинні бути вдячні впровадження ЧПУ (урлов, зрозумілих для людини, хоча особисто для мене вони дуже незрозумілі). Практично у всіх сучасних двигунах він вже діє.

Зламуємо D-Link DIR-890L
Останні 6 місяців я був страшенно зайнятий і не стежив за новими хрін від D-Link. Щоб трохи розважитися, я зайшов на їх сайт, і мене привітав цей кошмар: Найбожевільніший роутер D-Link DIR-890L за $ 300 Мабуть, самим «божевільним» в роутері є те, що він працює під управлінням все тієї ж забагованной прошивки, яку D-Link ставить в

Налагоджувати правила rewriterule, або трохи про інтимне життя mod_rewrite

Автоматична збірка пакетів для CMS Joomla!
До того, як я почав працювати над поточним проектом, я не думав, що мені коли-небудь доведеться використовувати інструменти для автоматичного складання проектів. Адже працюю я виключно з інтерпретуються мовами, яким не потрібна компіляція. Однак, як виявилося, вони можуть бути корисними і при розробці на PHP, і особливо при роботі з Joomla!

Налагоджувати правила rewriterule, або трохи про інтимне життя mod_rewrite

Мій варіант .htaccess
В одному з попередніх тематичних постів про .htaccess для нубов я хотів запропонувати свій варіант з різними обробками і заборонами, ну і певною логікою структурування, але так як карма була в мінусі, то викладаю зараз. Вашій увазі мій дивіться на правила обробки URL з поясненнями і коментарями «чому так?».

DDOS-бот на PHP гуляє по серверам
Сьогодні, близько другої години ночі, коли я хотів відійти до сну, до мене в скайп написав один зі знайомих. У минулому році я допомагав йому адмініструвати кілька його серверів. В такий пізній час він писав про те, що мережевий інтерфейс одного з його серверів повністю забитий, судячи з графіку mrtg. Я подивився, дійсно, я навіть не зміг достукатися

Налагоджувати правила rewriterule, або трохи про інтимне життя mod_rewrite