nginx map接受头到api奇怪行为的子目录

时间:2014-09-19 09:55:28

标签: php api http nginx hhvm

我已经花了很长时间来解决这个问题,而且我无法理解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的accept标头时,它会显示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 include。

设置

Debian 7, nginx的/ 1.2.1, hhvm 3.2.0

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

1 个答案:

答案 0 :(得分:2)

hhvm.conf的内容是什么?

我假设使用快速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提供静态文件等。但这对我有用 - 结合原始帖子中的map,当我curl -H 'Accept: application/vnd.com.example.api.v2+json' localhost时,我会从版本目录中的index.php文件中获得预期的响应。

我认为您需要做的是使用动态生成的root声明更新您的HHVM nginx配置,如上所述。如果您仍然获得404,请尝试以下操作:在/etc/init.d/hhvm中,找到ADDITIONAL_ARGS= var,将其设为ADDITIONAL_ARGS="-vServer.FixPathInfo=true"。我不确定它究竟是做什么的,但我之前遇到过这个问题,它修复了我过去遇到的一个奇怪的404问题(404来自HHVM,而不是Apache / nginx)