我已经花了很长时间来解决这个问题,而且我无法理解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
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
哦,这是我第一次在这里问一个问题。 :)希望我已正确格式化所有内容。
答案 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)