项目

常规

个人资料

操作

从 Apache 迁移到 lighttpd

配置基础

Lighttpd 是替代现有 Apache 或 Apache2 系统的绝佳选择。

请从阅读 配置:文件语法 开始。配置语法最初的学习曲线最为陡峭,但一旦熟悉它,您将看到它的灵活性。Lighttpd 配置最强大的功能之一是其条件语句。Lighttpd 允许您根据客户端请求设置配置选项。条件语句可以嵌套,因此您可以创建一些非常复杂但有效的配置选项。条件语句是人们从 Apache/Apache2 迁移时遇到的许多问题的关键解决方案。

您应该熟悉正则表达式,才能真正体会 Lighttpd 条件语句的灵活性。您将在配置文件中使用条件语句来处理多种事务,例如身份验证、URL 重写、虚拟主机等等。所有可在条件语句中使用的变量都列在 配置:文件语法 中,并附有关于匹配运算符的进一步说明。

:如何在除 /download 目录之外的所有地方启用目录列表?

####### Enable dir listing for all directories
dir-listing.activate = "enable" 

####### If the URL is like ^/download/ then disable dir-listing
$HTTP["url"] =~ "^/download/" {
  dir-listing.activate = "disable" 
}

:如何限制状态页面仅在本地网络中可用?
$HTTP["remoteip"] == "10.0.0.0/8" {
  status.status-url = "/server-status" 
}

:如何仅在主机是 www2.example.org 且 URL 在 /download/ 下时启用目录列表?
条件可以嵌套
$HTTP["host"] == "www2.example.org" {
  server.document-root = "/var/www/servers/www2.example.org/pages/" 
  $HTTP["url"] =~ "^/download/" {
    dir-listing.activate = "enable" 
  }
}

有关更多条件示例,请阅读

基本选项

Options +FollowSymLinks 变为 server.follow-symlink = "enable"

访问日志

mod_accesslog accesslog.format = "..." 支持许多与 Apache 中相同的选项。
日志文件轮换也与 Apache 中的处理方式类似,例如
  • Debian 包中使用的 logrotate
    如果您不使用 Debian 包,请将 ./debian/lighttpd.logrotate 复制到 /etc/logrotate.d/
    当需要轮换日志时,logrotate 会向 lighttpd 发送 SIGHUP 信号,lighttpd 将相应地重新打开日志。
  • cronolog
    使用 cronolog,您可以将访问日志通过管道传输到一个外部程序,让该程序处理日志文件写入。
    accesslog.filename = "|/usr/sbin/cronolog /web/logs/%Y/%m/%d/access.log"

重写

mod_rewrite 可能更复杂。Lighttpd 中规则的编写方式与 Apache 大相径庭。Lighttpd 始终匹配用户提交的完整相对请求 URI(且未进行 URL 解码)。
  • 在 lighttpd 1.4.50 及更高版本中,${qsa} 可用于正则表达式替换中,以附加请求中的查询字符串,类似于 Apache 的 rewrite QSA 标志。
  • 在 lighttpd 1.4.50 之前的版本中,我们可以通过匹配查询字符串并将其添加回目标来模拟 Apache 的 QSA 标志(“query string append”;参见 Apache 中的 mod_rewrite)。url.rewrite = ( "^/something/(\d+)(?:\?(.*))?" => "/index.php?bla=$1&$2" ) 重要的是 (?:\?(.*))?,它匹配查询字符串并使用 $2(正则表达式的第二个捕获括号)插入到目标 URL 中。?: 使周围的括号不捕获。

以下示例基于 dbird@freenode 发送的来自 dir.onlinesearch.ws 的一个问题。

RewriteEngine On
RewriteBase /instadir/
RewriteCond %{REQUEST_FILENAME}  -d
# Fix trailing slash problem
RewriteRule ^(.+[^/])$           $1/  [R,L]
# Do not try to treat the following resources as parameters to index.php
RewriteRule ^index\.php.*$       - [L]
RewriteRule ^dmoz\.css$          - [L]
RewriteRule ^admin[/]?.*$        - [L]
RewriteRule ^img[/]?.*$          - [L]
RewriteRule ^[/]{0,}(.*)$ index.php?area=browse&cat=$1 [QSA,L] 

这些重写规则旨在将除 index.php、dmoz.css、admin-interface 或图像目录中的内容之外的所有内容重写为 index.php 页面的一个参数。此匹配的基本目录是 /instadir/。下面的第一个模式使用了名为 零宽度负向先行断言 的正则表达式语法,这是您的 正则表达式书籍 中高级章节的内容。
## for all URLs in /instadir/ that are not index.php, dmoz.css, admin or img, do ...
url.rewrite-once = ( "^/instadir/(?!index\.php|dmoz\.css|admin|img).*" => "$0", 
                     "^/instadir/([^?]*)(?:\?(.*))?" => "/instadir/index.php?area=browse&cat=$1&$2")

在 lighttpd 1.4.50 及更高版本中,上述内容可以简化为
## for all URLs in /instadir/ that are not index.php, dmoz.css, admin or img, do ...
url.rewrite-once = ( "^/instadir/(?!index\.php|dmoz\.css|admin|img)" => "",
                     "^/instadir/([^?]*)" => "/instadir/index.php?area=browse&cat=$1${qsa}")

如果某些 Apache 重写规则的组合无法用 Lighttpd mod_rewrite 规则编写,那么另一个选项是 Lighttpd mod_magnet,它使用 Lua(一种真正的编程语言)。可以使用 Lighttpd mod_magnet 代替 mod_rewrite 编写任意复杂的逻辑

FastCGI

如果您在 Apache 中为 FastCGI 处理程序分配了两个扩展名,例如
AddType fastcgi-php .php .phtml
那么您需要告诉 lighttpd mod_fastcgi 将这些扩展名视为相同。

fastcgi.map-extensions = ( ".phtml" => ".php" )
fastcgi.server = ( ".php" => (( "bin-path" => "/my/fastcgi-php", 
                                "socket" => "/path/to/php.socket" )),
                 )

如果您需要在同一设置中使用 PHP 和 Python,只需添加两个扩展名。
fastcgi.server = ( ".php" => (( "bin-path" => "/my/fastcgi-php", 
                                "socket" => "/path/to/php.socket" )),
                   ".py" => (( "host" => "127.0.0.1", "port" => 3200 ))
                 )

对于上面的示例,Python 是在外部生成的,正在等待来自 localhost 端口 3200 的请求。

!MultiViews

如何设置类似于 Apache 的 MultiViews 选项 的机制?

幸运的是,Christian Hoffman 编写了一个 Lua 脚本 来实现此功能。以下是使用方法:

server.modules = ( "mod_magnet", )
server.document-root = "/var/www" 
magnet.attract-physical-path-to = ( server.document-root + "/multiviews.lua" )

另一个选项是 content-negotiation.lua

目录 !ForceType 迁移

有几个 PHP 包和教程使用 Apache 的 ForceType 指令而不是 mod_rewrite。它们将其用作一种对搜索引擎友好的方式,将参数作为伪目录传递。

假设您有以下设置:
  • 您的脚本名为 news(注意没有 php 扩展名)
  • 您的 URL 看起来像 /news/100/(/news/_新闻的 ID_)
  • 您的脚本通过 $_GET!['PHP_SELF'] 获取新闻 ID

并且 Apache 配置了 Location 或 LocationMatch 条目,如下所示:

<Location /news>
   ForceType application/x-httpd-php
</Location>
最简单的迁移方式是:
  • 首先使用 lighttpd 设置 PHP 并确保 .php 扩展名工作正常
  • 将文件名 news 重命名为 news.php
  • 使用 lighttpd 重写规则替换 Forcetype 条目

在 lighttpd 配置文件中:

url.rewrite-once = ("^/news/.*" => "/news.php")

如果您的脚本仍然无法工作,请尝试替换
$_GET!["PHP_SELF"] 为 $_GET!["REQUEST_URI"]。您通常可以在脚本顶部找到它。
PHP 在 FastCGI 中运行时无法正确注册 PHP_SELF。

美观的 URL(或“.php”脚本自动检测)

在迁移后,我遇到了一个问题,即复制我旧的 Apache1.x + PHP 设置时,原来 '''http://server.com/script/blah''' 可以顺利运行 ''script.php_ with arguments _/blah''。这对于轻松创建美观的 URL 非常有用。

我找不到一种简单的解决方案来复制这种行为,或者在这里的文档中也没有找到任何条目,所以我决定分享我的发现。本质上,有两种半通用方法可以复制这种行为,这样您就不必重新编码/重命名实际脚本。

如果您乐于重命名,您或许可以使用 lighttpd 的 forcetype 支持来使事情正常工作。

mod_rewrite 解决方案

这是我选择的方法,因为它更快,而且看起来更简洁。基本上我添加了:

include "mod_rewrite.conf" 

... 然后创建该文件,内容为...

url.rewrite-repeat = ( "/script/(.*)" => "/script.php/$1" )

我想您也可以通过命名每个脚本来以半通用的方式实现这一点。

url.rewrite-repeat = ( "/(script|script2|script3)/(.*)" => "/$1.php/$2" )

404 处理程序解决方案

这可能速度会慢一点点,但如果您的 URL 重写中考虑了更复杂的(即:不纯粹的正则表达式)因素,这可能是一个更好的主意。您也可以使用 PHP preg_match() 复制上面的正则表达式。只需添加:

server.error-handler-404 = "/404.php" 

... 然后在该文件中编写您的处理程序。

!ScriptAlias

$HTTP["host"] == "example.com" {
            alias.url  = ( "/bin/" => "/path/to/my/bin/" )
            $HTTP["url"] =~ "^/bin" {
                    cgi.assign = ( ".pl" => "/usr/bin/perl" )
            }
}

另一种解决方案是使用 mod_alias,配合

cgi.assign = ( ".py" => "/usr/bin/python" )
alias.url = (
    "/chrome" => var.basedir + "/foo.org/chrome",
    "" => var.basedir + "/foo.org/dispatch.py" 
)

缺少结尾的 '/' 将作为通配符。

在此脚本内部,获取环境变量 'REQUEST_URI' 以找出“美观的”结尾字符串。

在 Python 中,这将是:os.environ['REQUEST_URI'](省略导入),在 PHP 中:$_SERVER['REQUEST_URI']。

.htaccess 类似功能

.htaccess 类似功能
Apache .htaccess 替代方案

任意复杂的逻辑

如果 lighttpd 模块不原生支持特定的逻辑集,则还有另一个选项:lighttpd mod_magnet
任意复杂的逻辑可以写入 Lua 脚本并通过 mod_magnet 运行。

gstrauss近 3 年前更新 · 51 次修订