Как я могу получить информацию о пути URL верхнего уровня, используя Perl? - PullRequest
1 голос
/ 09 сентября 2011

Что я пытаюсь достичь

Учитывая URL верхнего уровня, такой как http://www.myapp.com/

Если кто-то просит:

http://www.myapp.com/questions/id/1

Я хочу получить часть "questions / id / 1" и передать ее соответствующему сценарию Perl для получения требуемого ресурса.

Что я достиг

В настоящее время я знаю, как это сделать, если в URL есть дополнительный уровень, например:

http://www.myapp.com/model/questions/id/1

Где «модель» - это просто типичный CGI-скрипт Perl, за исключением того, что он не имеет расширения «.pl», и обработчик perl Apache настроен для обработки этого, а часть «questions / id / 1» интерпретируется как путь информация (через CGI-> path_info ()) передается в "модель".

Я пришел к этой идее из статьи Эндрю Ханенкампа по теме на onlamp.com Разработка веб-сервисов RESTful на Perl

Что еще не так

Этот подход, однако, не работает для URL верхнего уровня, так как нет места для добавления "модель" или как там называется обработчик. Я попытался установить настройки документов по умолчанию в конфигурации, чтобы http://www.myapp.com/ по умолчанию http://www.myapp.com/modle.

Так что набор http://www.myapp.com/questions/id/1 обрабатывается как http://www.myapp.com/model/questions/id/1

Однако Apache считает, что это ошибка 404.

Как мне это сделать? Это даже работа для Perl или лучше выполняется на уровне конфигурации Apache или, может быть, используется какой-то API-интерфейс Apache, чтобы отлавливать ошибки 404 и извлекать часть "/ questions / id / 1" оттуда? Я не знаю. Может быть, кто-то здесь знает. ; -)

Примечание: Извините за длинный и окольный способ задать этот вопрос. Я не совсем уверен, какая терминология требуется, чтобы получить ответ по теме. Упоминание четырехбуквенного слова, начинающегося с R и заканчивающегося буквой T при задании этого вопроса ранее здесь и в других местах, привело к горячим дискуссиям о природе сказанного для буквенного слова, а также о значительных, но бесполезных предложениях использовать ту или иную структуру. Мне просто интересно узнать, как эти фреймворки реализуют эту функцию, и я хочу реализовать ее в Perl, чтобы узнать, как это сделать.

Обновление: Один из предложенных ответов побудил меня попробовать mod_rewrite. Работает. Тем не менее, довольно непрактично устанавливать Apache conf вручную для каждого отображения. Дальнейшие поиски позволили мне перейти к книге О'Рейли "Practical mod_perl". В нем Бекман и Шоле писали о программном доступе к mod_rewrite через пакет Apache CPAN для установки перезаписи. Приложение 10: "mod_rewrite in Perl" Написание кода для проверки идеи этой книги. А пока, если есть лучшие способы сделать это, пожалуйста, поделитесь.

Заключение

После создания прототипа двух сценариев маршрутизации / диспетчеризации Uri (или Whatchamacallit), один полагается на mod_rewrite, чтобы вызвать его, а другой на ErrorDocument; Я пришел к выводу, что mod_rewrite является правильным способом реализации этого.

Метод ErrorDocument является неправильным, поскольку он не сохраняет данные POST с перенаправленной страницы. Не нужно отправлять запрос POST на http://www.myapp.com/questions для создания нового ресурса, поскольку данные POST недоступны для пользовательского сценария обработчика ошибок, вызываемого ErrorDocument. Кроме того, поскольку каждый запрос по определению не будет обращаться к физическому файлу, таким образом, журнал ошибок Apache будет полон ошибок spurios 404 file not found. Это может быть огромной проблемой, если объем транзакций на сервере высок. Спасибо всем за то, что указали мне правильное направление. Теперь мое любопытство утолено.

Ответы [ 3 ]

1 голос
/ 09 сентября 2011

Я настоятельно советую использовать фреймворк для веб-разработки.Это потребует некоторого изучения, но к тому времени, как вы закончите, вы поймете, что ваш текущий подход далек от идеального.Существует множество простых фреймворков, которые позволят вам быстро приступить к работе.Я предлагаю использовать Dancer (www.perldancer.org).В Dancer настроить маршруты так же просто, как в примере ниже.

get '/' => sub {'Hello world!'}

Кроме того, очень маловероятно, что вы захотите использовать CGI.CGI обычно имеет очень низкую производительность и в основном не функционирует.Я предлагаю вам взглянуть на FastCGI и PSGI, которые доступны в Apache.

1 голос
/ 09 сентября 2011

Вы можете отловить ошибку 404 и обработать ее с помощью скрипта cgi. В вашем файле верхнего уровня .htaccess (docroot / .htaccess):

ErrorDocument 404 /cgi/my-script.sh

Тогда в вашем скрипте-обработчике (my-script.sh) исходный путь будет передан как переменная enviromnent REDIRECT_URL. Но убедитесь, что ваш скрипт обработчика правильно устанавливает статус HTTP, добавив заголовок Status: 200 OK. Вот пример сценария cgi (/cgi/my-script.sh):

#!/bin/sh

echo Status: 200 OK
echo Content-type: text/plain
echo
echo Your url was $REDIRECT_URL

(я не рекомендую использовать оболочку bourne для написания сценариев cgi, но это иллюстрирует метод).

Вы также можете поместить параметр ErrorDocument в файл httpd.conf, но любое изменение требует перезагрузки сервера; размещение его в .htaccess значительно упрощает настройку во время выполнения.

Справочник Apache по пользовательской обработке ошибок: http://httpd.apache.org/docs/2.1/custom-error.html

Если вы используете mod_perl, проще и чище (не говоря уже о лучшей производительности) настроить его как обработчик perl; снова в файле .htaccess верхнего уровня (или httpd.conf):

SetHandler perl-script
PerlHandler MyThing::HandlerPackage

, где MyThing::HandlerPackage - это модуль perl, который определяет соответствующий handler sub.

1 голос
/ 09 сентября 2011

Вы можете определить правила перезаписи в файле .htaccess или в файле конфигурации Apache. Подробнее см. mod_rewrite .

В вашем случае .htaccess файл может выглядеть так:

AddHandler cgi-script .cgi
Options +ExecCGI

RewriteEngine on

RewriteRule ^(questions/id/.*)$ model.cgi/$1 [L]

Это должно работать, если вам нужно обрабатывать только /question/id/ запросов. Но вы можете обрабатывать все запросы через приложение Perl. Так что на самом деле передавать все запросы в ваше приложение может быть хорошей идеей. Что-то вроде:

RewriteRule ^(.*)$ app.cgi/$1 [L]

И пусть ваш запрос на отправку заявки, чем. Кроме ... всегда есть какое-то исключение. Вы должны позволить Apache обслуживать статические файлы для вас. И вам нужно, чтобы Apache не обслуживал файлы приложений (исполняемые файлы и конфиги) как статические файлы. Таким образом, большинство современных платформ Perl хранит статические данные в отдельном каталоге, например, public. Таким образом, вы помещаете все ваши изображения, css, js и т. Д. В / public и настраиваете Apache следующим образом:

 RewriteCond %{DOCUMENT_ROOT}/public/%{REQUEST_URI} -f
 RewriteRule ^(.*) public/$1 [L]

 RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI} !-f
 RewriteRule ^(.*) myapp.cgi [L] 

Этот пример взят из Уважительной документации .

Теперь Apache отправляет статические файлы пользователю, если пользователь запросил что-то, что существует в 'public', и перенаправляет все другие запросы в ваше приложение.

В вашем приложении вам нужно отправить несколько запросов на некоторые действия. На самом деле, вам нужен модуль, который сделает эту работу за вас. Маршруты :: Tiny (также доступны на CPAN ), написанные Вячеславом Тихановским, - хороший выбор.

В конце концов, если вы хотите знать, как работают фреймворки, почему бы вам не погрузиться в одну из них? Mojolicious и Dancer слишком велики, но вы можете взглянуть на что-то меньшее, например Lamework , работающее по протоколу PSGI, ставшее сегодня стандартным.

...