项目

常规

资料

操作

response.c 中的响应处理

-- 这也可能有助于理解配置的工作原理。

(我从代码中删除了 con-> 前缀以方便阅读;因此 mode 在源代码中是 con->mode)

条件检查会在特定点激活,正如你所见;因此,如果将模块包装在 $PHYSICAL["existing-path"] 条件中,那些在其 `uri_clean` 处理程序中执行操作的模块可能永远不会被触发。

在每次 handle(foo) 调用中,模块处理程序会按照模块加载的顺序被调用。但这并不意味着通过在一个模块之前插入另一个模块,就能使其总是在另一个模块之前处理请求,因为并非每个模块都实现了所有处理程序。

一个例子是 `mod_rewrite`/`mod_redirect`:`rewrite` 处理 `uri_raw`,`redirect` 处理 `uri_clean` —— 所以 `rewrite` 总是会在 `redirect` 之前执行(目前是这样 —— 我建议你先加载 `mod_rewrite`,再加载 `mod_redirect`,以防此行为发生变化)。

如果处理程序返回 HANDLER_COMEBACK(`mod_rewrite`、`mod_proxy_core`、`mod_magnet`),请求处理将重新开始。

待办:`config_cond_cache_reset(srv, con)` 应该在哪个点执行?

待办:`HANDLER_WAIT_FOR_FD` 呢?

如果请求处理程序未返回 HANDLER_GO_ON,请求处理将停止(剩余的模块处理程序不会被调用!),并且返回处理程序的返回值。

mode 指示哪个模块希望生成内容;mode == DIRECT 最终会由 `mod_staticfile` 处理(默认值);如果模块处理请求,则应将其设置为自己的 id:con->mode = p->id

如果 mode != DIRECT,你必须自己生成错误消息,因此如果你想让 lighty 发送错误(或触发错误处理程序),mode 必须是 DIRECT;只需将 http_status 设置为错误状态并返回 HANDLER_FINISHED

如果你想知道另一个模块是否已经处理了请求,可以这样做

if (con->mode != DIRECT || con->http_status != 0) return HANDLER_GO_ON;

那么,让我们开始吧(这基本上是 `response.c` 中的简化代码)

handle_request() {
  if (mode == DIRECT and (http_status != 0 or http_status != 200)) return HANDLER_FINISHED

  if (mode == DIRECT and empty(physical.path)) {
    // We need a physical path, i.e. a filename

    activate_conditionals($SERVER["socket"], $HTTP["scheme"], $HTTP["host"], $HTTP["remote-ip"],
        $HTTP["referer"], $HTTP["user-agent"], $HTTP["cookie"], $HTTP["request-method"])
    split(request.uri -> uri.path_raw '?' uri.query)

    handle(uri_raw)

    urldecode_and_simplify(uri.raw -> uri.path);  // "sanitising" 
    activate_conditionals($HTTP["url"], $HTTP["query-string"])

    handle(uri_clean)

    response to the query 'OPTIONS *'

    set default physical.doc_root (server.document-root from the last matching conditional)
    set default physical.rel_path = uri.path
    [lighty-1.5] filename_unix2local(physical.rel_path)

    handle(docroot)

    lowercase physical.rel_path on case insensitive platforms
    physical.path = physical.docroot + physical.rel_path

    [lighty-1.5] remove trailing DIR_SEPERATOR from physical.path

    handle(phyiscal)

    activate_conditionals($PHYSICAL["path"])
  }

  if (mode == DIRECT) {
    // Now we should have a physical.path

    if (exists(phyiscal.path)) {
      if (is_symlink(phyiscal.path) and not conf.follow_symlinks) return FORBIDDEN() // 403
      if (is_dir(phyiscal.path) and uri.path does not end with a '/') return redirect_to_dir(); // append '/'
    } else if (some physical.path component was not a directory) { // errno = ENOTDIR
      split phyiscal.path into (a existing filename) physical.path and request.path_info
    }

    [lighty-1.5] activate_conditionals($PHYSICAL["existing-path"])

    [lighty-1.4] handle(subrequest_start)
    [lighty-1.5] handle(start_backend)

    [lighty-1.4] if (mode == DIRECT and http_status == 0) {
      // no one wanted to send content
      if (request.http_method == 'OPTIONS') OK() // 200
      else FORBIDDEN() // 403;
    }
  }

  [lighty-1.4] handle(subrequest);

  [lighty-1.5] if (mode == DIRECT) {
    // no one wanted to send content
    FORBIDDEN() // 403
  }
}

kjikaqawej将近 13 年 前更新 · 8 个修订版本