mod_rewrite, проблемы с двойным переписыванием

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Привет всем.
у меня возникла проблема с mod_rewrite, за несколько часов не смог разобраться. Может, кто подскажет что-то.

Я пишу очень свою CMS-ку, куча сайтов хостятся на говнохостингах, т.е. решение должно быть под apache.

что мне надо:
админ CMS-ки задает нужные ему размеры картинки, картинки в оригинальном размере на сайте уже есть.
получается тег <img src="/img/500/12345/toyotacorolla.jpg">
toyotacorolla - отфонарное слово для SEO
12345.jpg - реальное имя файла и его id
500 - название размера

Для тех картинок, которые не существуют, мне надо, чтобы шло обращение к php-скрипту, который эту картинку сгенерит.

пишу правила:

RewriteRule ^img/(\w{1,20}/\d{1,10})/.*\.jpg$ assets/img/$1.jpg

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^assets/img/(\w{1,20})/(\d{1,10})\.jpg$ /controller/action/id/$2/preset/$1 [R,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
отресайзенные картинки показываются, все хорошо,

второе правило должно выдавать 302й редирект на скрипт, который сгенерит картинку.
редирект тут потому, что у меня одна точка входа, и скрипт должен получить нужный request_url.
но второе правило не срабатывает, а вместо него сразу срабатывает третье правило для yii, вызывается скрипт, и пишет "не могу найти контроллер" (естественно).

Если третье правило отключаю, то редирект срабатывает замечательно, но у меня yii и это 3е правило мне нужно.
Если выставляю 3е правило 2м и в 1м указываю флаг [ S ] - не помогает.

может, кто-то подскажет, где я неправ? или какой-то другой подход к решению
 

zerkms

TDD infected
Команда форума
Я не верю, что при наличии 3 правила "не срабатывает редирект". Может редирект срабатывает, но не срабатывает что-то ещё?

R,L - в случае матча сразу отправляет клиента в редирект, не применяя остальных правил

ps: а нафиг тебе редирект вообще? Почему не делать то же самое без редиректа, чтобы клиенты вообще не знали ничего о твоих скриптах
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
а, блин, вот так - вместо 2го правила срабатывает сразу 3е, а если его нет - то 2е.

без редиректа yii получит запрос с REQUEST_URI=assets/img/500/12345.jpg
да, можно и в роутере приложения правило для такого запроса написать
видимо, это будет самое простое решение
 

Absinthe

жожо
А если на шаредах отдавать картинку через PHP? Пусть оно трудится - "уплочено" же.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
не хочу, если картинка есть - пусть отдается из файла
 

fixxxer

К.О.
Партнер клуба
Я апача сто лет живого не видел, но я бы попробовал добавить что-то типа RewriteCond %{REQUEST_URI} ^assets/img (не уверен в написании) во 2-е
 

varan

Б̈́̈̽ͮͣ̈Л̩̲̮̻̤̹͓ДͦЖ̯̙̭̥̑͆А͇̠̱͓͇̾ͨД͙͈̰̳͈͛ͅ
L - не означает, что реврайт прекращен, это перекидывание в конец. После отрабатывания всех правил до конца, начинается реврайт по новой. До тех пор пока не перестанет изменяться.
 

Absinthe

жожо
не хочу, если картинка есть - пусть отдается из файла
Ну так если картинки нет - делаем и выводим в поток. Если есть - то readfile().
Неоптимально, но на шареде сгодится - заплачено же :D
 

zerkms

TDD infected
Команда форума
L - не означает, что реврайт прекращен, это перекидывание в конец. После отрабатывания всех правил до конца, начинается реврайт по новой. До тех пор пока не перестанет изменяться.
Там редирект же. R,L - не начинает нового цикла обработки
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Я апача сто лет живого не видел
я тоже. пришлось сесть за комп сотрудника, у которого апач стоит - лень же ставить его себе ради одного реврайта,
а на nginx такие правила пишутся минут за 15.

> я бы попробовал добавить что-то типа RewriteCond %{REQUEST_URI} ^assets/img (не уверен в написании) во 2-е
попробую завтра.

спасибо, почитаю
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
очень полезная статья!
а то я все удивлялся, что такое [INTERNAL REDIRECT] в rewrite.log
теперь я понял: 2е правило срабатывает при отсутствии 3го на 2м цикле работы
 

zerkms

TDD infected
Команда форума
очень полезная статья!
а то я все удивлялся, что такое [INTERNAL REDIRECT] в rewrite.log
теперь я понял: 2е правило срабатывает при отсутствии 3го на 2м цикле работы
А теперь нам расскажи, почему оно сразу на 302 редирект не уходило при наличии 3 правила, которое по факту никогда не должно было срабатывать, потому что у меня в данный момент есть несколько похожих и рабочих примеров, в которых редирект происходит без проверки остальных правил, как и ожидается.

Я правда редирекчу [R=301,L,QSA], но принципиальной разницы никакой
 

zerkms

TDD infected
Команда форума
Вот нарисовал пример даже

PHP:
RewriteEngine on

RewriteRule a http://ya.ru [R,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /index.php
PHP:
127.0.0.1 - - [08/Apr/2012:22:35:49 +1200] [127.0.0.1/sid#ad1520][rid#366e0f0/initial] (3) [perdir D:/server/www/] strip per-dir prefix: D:/server/www/aaaa -> aaaa
127.0.0.1 - - [08/Apr/2012:22:35:49 +1200] [127.0.0.1/sid#ad1520][rid#366e0f0/initial] (3) [perdir D:/server/www/] applying pattern 'a' to uri 'aaaa'
127.0.0.1 - - [08/Apr/2012:22:35:49 +1200] [127.0.0.1/sid#ad1520][rid#366e0f0/initial] (2) [perdir D:/server/www/] rewrite 'aaaa' -> 'http://ya.ru'
127.0.0.1 - - [08/Apr/2012:22:35:49 +1200] [127.0.0.1/sid#ad1520][rid#366e0f0/initial] (2) [perdir D:/server/www/] explicitly forcing redirect with http://ya.ru
127.0.0.1 - - [08/Apr/2012:22:35:49 +1200] [127.0.0.1/sid#ad1520][rid#366e0f0/initial] (1) [perdir D:/server/www/] escaping http://ya.ru for redirect
127.0.0.1 - - [08/Apr/2012:22:35:49 +1200] [127.0.0.1/sid#ad1520][rid#366e0f0/initial] (1) [perdir D:/server/www/] redirect to http://ya.ru [REDIRECT/302]
Хз откуда у вас там берётся обработка правил после редиректа
 

zerkms

TDD infected
Команда форума
PHP:
127.0.0.1 - - [09/Apr/2012:09:38:00 +1200] [localhost/sid#431520][rid#36760d0/initial] (3) [perdir D:/server/www/] strip per-dir prefix: D:/server/www/a -> a
127.0.0.1 - - [09/Apr/2012:09:38:00 +1200] [localhost/sid#431520][rid#36760d0/initial] (3) [perdir D:/server/www/] applying pattern 'a' to uri 'a'
127.0.0.1 - - [09/Apr/2012:09:38:00 +1200] [localhost/sid#431520][rid#36760d0/initial] (2) [perdir D:/server/www/] rewrite 'a' -> 'b'
127.0.0.1 - - [09/Apr/2012:09:38:00 +1200] [localhost/sid#431520][rid#36760d0/initial] (3) [perdir D:/server/www/] add per-dir prefix: b -> D:/server/www/b
127.0.0.1 - - [09/Apr/2012:09:38:00 +1200] [localhost/sid#431520][rid#36760d0/initial] (3) [perdir D:/server/www/] strip per-dir prefix: D:/server/www/b -> b
127.0.0.1 - - [09/Apr/2012:09:38:00 +1200] [localhost/sid#431520][rid#36760d0/initial] (3) [perdir D:/server/www/] applying pattern 'b' to uri 'b'
127.0.0.1 - - [09/Apr/2012:09:38:00 +1200] [localhost/sid#431520][rid#36760d0/initial] (4) [perdir D:/server/www/] RewriteCond: input='D:/server/www/b' pattern='!-f' => matched
127.0.0.1 - - [09/Apr/2012:09:38:00 +1200] [localhost/sid#431520][rid#36760d0/initial] (2) [perdir D:/server/www/] rewrite 'b' -> 'c'
127.0.0.1 - - [09/Apr/2012:09:38:00 +1200] [localhost/sid#431520][rid#36760d0/initial] (3) [perdir D:/server/www/] add per-dir prefix: c -> D:/server/www/c
127.0.0.1 - - [09/Apr/2012:09:38:00 +1200] [localhost/sid#431520][rid#36760d0/initial] (2) [perdir D:/server/www/] explicitly forcing redirect with http://localhost/D:/server/www/c
127.0.0.1 - - [09/Apr/2012:09:38:00 +1200] [localhost/sid#431520][rid#36760d0/initial] (1) [perdir D:/server/www/] escaping http://localhost/D:/server/www/c for redirect
127.0.0.1 - - [09/Apr/2012:09:38:00 +1200] [localhost/sid#431520][rid#36760d0/initial] (1) [perdir D:/server/www/] redirect to http://localhost/D:/server/www/c [REDIRECT/302]
Точно так же до последнего правила не доходим, и уходим сразу на редирект
 

varan

Б̈́̈̽ͮͣ̈Л̩̲̮̻̤̹͓ДͦЖ̯̙̭̥̑͆А͇̠̱͓͇̾ͨД͙͈̰̳͈͛ͅ
Домой приду вечером, тоже попробую.
А вообще, rewrite в apache - вообще ни разу не user-friendly. какой-то вынос мозга
 
Сверху