【问题标题】:nginx map accept header to subdirectory for api strange behaviournginx 将标头接受到子目录的 api 奇怪行为
【发布时间】:2014-09-19 09:55:27
【问题描述】:

我已经在这个问题上摆弄了很长一段时间,但我无法真正掌握 nginx+hhvm 是如何映射我的请求的。

基本上,我在 api.example.com 上有一个 API,我想通过 Accept 调用它:application/vnd.com.example.api.v1+json 用于版本 1 和 application/vnd.com.example。 api.v2+json 用于版本 2。API 本身是一个 PHP 应用程序,我将使用全新安装的 HHVM 运行它。所有请求都将由 index.php 处理。

文件夹结构如下:

api.example.com/
  index.php (content: fail)
  v1/
    index.php (content: v1)
  v2/
    index.php (content: v2)

每当我使用我的 REST 客户端访问带有 v1 接受标头的 api.example.com/test 时,我都会返回 v1 响应。当我使用 v2 的接受标头时,它会显示 v2。所以一切都是正确的。如果我不提供任何接受标头,我将被重定向到 example.com

NGINX 配置如下所示

map $http_accept $api_version {
        default 0;
        "application/vnd.com.example.api.v1+json" 1;
        "application/vnd.com.example.api.v2+json" 2;
}

server {
        # listen to :80 is already implied.

        # root directory
        root /var/www/api.example.com/;
        index index.html;

        server_name api.example.com;
        include hhvm.conf;

        location / {
                if ($api_version = 0) {
                        # redirect to example.com if applicable
                        # Accept-header is missing
                        return 307 http://example.com;
                }

                try_files /v$api_version/$uri /v$api_version/$uri/ /v$api_version/index.php?$args;
        }

        # Prevent access to hidden files
        location ~ /\. {
                deny all;
        }
}

hhvm.conf 文件包含在下面。它是 hhvm 中包含的默认 hhvm.conf 的派生或稍微精确的功能。

location ~ \.(hh|php)$ {
    fastcgi_keep_conn on;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

这是我的问题

如果我尝试访问 api.example.com/index.php,我会收到“失败”响应,即使我期望 v1 接受标头为 v1,而 v2 接受标头为 v2。其他一切似乎都运行良好,甚至 index.html 也正确映射到它的子目录。

我尝试过的

我试过了

root /var/www/api.example.com/v$api_version/; 

在配置中,但这只会给我来自 NGINX 的 404 错误。我相信我正在寻找的实际上是改变根路径,但我还没有弄清楚如何让它工作。我还尝试在 nginx 配置和 hhvm.conf 中删除索引参数,但这似乎没有帮助。我还尝试了很多不同的配置,并且至少打开了 20-30 个 stackoverflow 选项卡来解决这个问题,但我显然在这里遗漏了一些东西(可能相当简单)。我还尝试将 hhvm 包含在 location 块中。

设置

Debian 7, nginx/1.2.1, hhvm 3.2.0

哦,这是我第一次在这里提出问题。 :) 希望我已正确格式化所有内容。

【问题讨论】:

  • +1 好问题。为什么所有新用户都不能像你一样?
  • @RaduMurzea 非常感谢你 :) 很高兴听到。很遗憾,我没有您的问题的答案,但我会确保进一步调查。

标签: php api http nginx hhvm


【解决方案1】:

hhvm.conf 的内容是什么?

我假设 Fast CGI 被用于代理对 HHVM 服务器的请求。所以你的 hhvm.conf 可能看起来像这样:

root /var/www/api.example.com;
index index.php;
fastcgi_pass   127.0.0.1:9000;
fastcgi_index  index.php;
fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
include        fastcgi_params;

应该由位置指令包装。

因此,根据您显示的配置,我认为您必须将 php 脚本与 HHVM 位置指令匹配,这很好,但这样做您的 try_files 设置,似乎负责执行 API版本到文件系统的映射,未被处理。

没有您的 hhvm.conf 很难说下一步该做什么,但我怀疑您需要关注包含 HHVM fastcgi 设置的 location 指令中的根值。

更新

所以我有一个 API 版本的概念,它从标头映射到在 nginx + HHVM 上为我工作的文件系统。这是我的 HHVM 的 nginx 配置:

location / {
    root /var/www/html/hh/v$api_version;
    index index.php;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

真的,/ 的位置并不比你的位置好 - 事实上,你的位置可能更好,因为你可能不希望 HHVM 提供静态文件等。但这对我有用 - 结合 @ 987654324@ 你在你原来的帖子里有,当我curl -H 'Accept: application/vnd.com.example.api.v2+json' localhost 时,我会从版本目录中的index.php 文件中得到预期的响应。

我认为您需要做的是使用动态生成的root 声明更新您的 HHVM nginx 配置,就像我上面的一样。如果你仍然得到 404,试试这个:在 /etc/init.d/hhvm 中,找到 ADDITIONAL_ARGS= 变量,将其设为 ADDITIONAL_ARGS="-vServer.FixPathInfo=true"。我不确定它到底是做什么的,但我之前遇到过它,它解决了我过去遇到的一个奇怪的 404 问题(404 来自 HHVM,而不是 Apache/nginx)。

【讨论】:

  • 我使用默认的 HHVM 配置以避免混淆(我让它做它的一部分,但我实际上不确定它是如何工作的)。我将使用 HHVM 配置文件更新问题。我一直在以与您相同的方式进行推理,但是根据我的问题,您会注意到在位置目录中使用 root /var/www/api.example.com/v$api_version/; 只会给我 404 错误。
  • 您的回答很有帮助。这是朝着正确方向迈出的一步。 hhvm.conf 实际上包含 .hh 和 .php 文件结尾的映射,这将使其优先于 try_files,不会太奇怪。但是,由于奇怪的 404 错误,我仍然无法将根目录更改为子目录。但也许我可以通过包含你的 hhvm.conf 来解决这个问题,它不包含 .hh 和 .php 的映射。
猜你喜欢
  • 1970-01-01
  • 2019-06-11
  • 1970-01-01
  • 2012-10-30
  • 1970-01-01
  • 1970-01-01
  • 2018-09-09
  • 2016-12-20
  • 1970-01-01
相关资源
最近更新 更多