Apache mod_perl处理程序/调度程序将控制权返回给Apache

Apache mod_perl处理程序/调度程序将控制权返回给Apache,apache,apache2,mod-perl,Apache,Apache2,Mod Perl,是否可能有一个apache mod_perl处理程序,它接收所有传入的请求,并根据一组规则决定该请求是否是它想要执行的,如果不是,则将控制权返回给apache,apache将正常地处理该请求 用例: 使用 用于服务index.html的DirectoryIndex (或类似)和的默认处理程序 perl脚本等,正在获得 更新url方案 (django/catalyst-ish)。调度员 将有一组URL映射到 基于调度的控制器 在传入的url上 然而,棘手的部分是 此调度器位于同一个目录中 名称空间

是否可能有一个apache mod_perl处理程序,它接收所有传入的请求,并根据一组规则决定该请求是否是它想要执行的,如果不是,则将控制权返回给apache,apache将正常地处理该请求

用例:

使用 用于服务index.html的DirectoryIndex (或类似)和的默认处理程序 perl脚本等,正在获得 更新url方案 (django/catalyst-ish)。调度员 将有一组URL映射到 基于调度的控制器 在传入的url上

然而,棘手的部分是 此调度器位于同一个目录中 名称空间与旧名称空间位于同一vhost上 地点。我们的想法是重写 站点一块一块地更新,作为“全部更新” 迁移不会给测试带来任何机会 新系统的现场性能, 这也不可能,因为纯粹的 网站的大小

许多问题之一是,dispatcher现在按预期接收所有URL,但DirectoryIndex和静态内容(主要由不同的主机提供,但不是所有内容)没有得到正确的服务。对于不匹配的URL,dispatcher返回一个Apache::Const::Decended,但Apache不会像通常那样继续为请求提供服务,而是提供默认的错误页面。Apache似乎没有尝试查找/index.html等

如何解决这个问题?您需要使用内部重定向吗?是否更改调度程序中的处理程序堆栈?使用一些聪明的指令?所有这些?根本不可能


欢迎所有建议

使用mod_rewrite配置可能会成功,该配置仅在文件系统中不存在请求的文件时才将URL重写到调度程序。这样,您的新应用程序就可以作为旧应用程序的覆盖,并且可以通过在部署新部件的过程中删除应用程序的旧部件,在后续步骤中进行替换

这可以通过RewriteCond和RewriteRule的组合来实现。您的新应用程序需要位于一个私有的“名称空间”(位置),而不是在旧应用程序中使用

我不是mod_perl专家,但使用eg mod_php,它可以像这样工作:

RewriteEngine on

# do not rewrite requests into the new application(s) / namespaces
RewriteRule ^new_app/ - [L]

# do not rewrite requests to existing file system objects
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l

# do the actual rewrite here
RewriteRule ^(.*)$ new_app/dispatcher.php/$1

使用mod_rewrite配置可能会成功,该配置仅在文件系统中不存在请求的文件时将URL重写到调度程序。这样,您的新应用程序就可以作为旧应用程序的覆盖,并且可以通过在部署新部件的过程中删除应用程序的旧部件,在后续步骤中进行替换

这可以通过RewriteCond和RewriteRule的组合来实现。您的新应用程序需要位于一个私有的“名称空间”(位置),而不是在旧应用程序中使用

我不是mod_perl专家,但使用eg mod_php,它可以像这样工作:

RewriteEngine on

# do not rewrite requests into the new application(s) / namespaces
RewriteRule ^new_app/ - [L]

# do not rewrite requests to existing file system objects
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l

# do the actual rewrite here
RewriteRule ^(.*)$ new_app/dispatcher.php/$1

我之前也做过类似的事情,所以我可能有点含糊不清:

  • 我认为您需要在堆栈中使用标准文件处理程序(我相信这是使用set handler指令完成的)以及perl处理程序
  • 您可能需要使用或类似的方法来连接到filename/url映射阶段,并确保下一个内联处理程序将从文件系统中提取正确的文件

不久前,我也做过类似的事情,所以我可能有点含糊不清:

  • 我认为您需要在堆栈中使用标准文件处理程序(我相信这是使用set handler指令完成的)以及perl处理程序
  • 您可能需要使用或类似的方法来连接到filename/url映射阶段,并确保下一个内联处理程序将从文件系统中提取正确的文件

我一直在考虑您建议的解决方案,但我不知道如何通过重写来解决。我首先考虑让dispatcher处理“所有”请求,但我想它处理所有“丢失”请求更明智,也就是说,所有DirectoryIndex或显式文件/mime类型处理程序都找不到的请求。这意味着Apache必须调用dispatcher作为最后手段,此时它通常会给出404。然后,如果调度器拒绝,则给出404。我添加了一个建议的重写配置示例。我一直在考虑您建议的解决方案,但我不知道如何通过重写来解决它。我首先考虑让dispatcher处理“所有”请求,但我想它处理所有“丢失”请求更明智,也就是说,所有DirectoryIndex或显式文件/mime类型处理程序都找不到的请求。这意味着Apache必须调用dispatcher作为最后手段,此时它通常会给出404。然后,即使调度器拒绝,也会给出一个404。我添加了一个建议的重写配置示例,为感兴趣的人提供了一个快速更新。我添加了一个PerltTransHandler来指向MyClass::handler,在其中我根据$r->uri()检查所有URL。如果存在匹配项,则执行:$r->handler('perl-script')$r->set_处理程序(PerlResponseHandler=>sub{$self->dispatch();});返回值取决于所需的行为。如果没有匹配项,请返回Apache2::Const::Decedden。对于感兴趣的人,请快速更新此内容。我添加了一个PerltTransHandler来指向MyClass::handler,在其中我根据$r->uri()检查所有URL。如果存在匹配项,则执行:$r->handler('perl-script')$r->set_处理程序(PerlResponseHandler=>sub{$self->dispatch();});返回值取决于所需的行为。如果没有匹配项,只需返回Apache2::Const::谢绝。