在单一Pyramid实例上使用多个域和子域
我想在一个Pyramid实例上使用多个域名和子域名。但是,我找不到相关的文档。之前有一个问题提到过一个词汇表,但里面的信息很少,也没有例子。你们有没有什么例子或者能推荐更好的文档给我?
2 个回答
0
如果你能控制你的服务器环境,我强烈建议把域名的相关设置放在外面,使用像Apache的代理服务器来处理,这样可以把请求路由到Pyramid的子域名上。这样一来,你就可以轻松地切换任何域名来查看路由,而不需要在Pyramid的代码中处理那些脆弱的东西(比如域名)。这样你的应用代码会更干净,也更容易在以后进行修改。
下面是一个Apache的例子,展示了两个域名如何指向一个Pyramid应用,假设我们在5001端口上运行这个Pyramid应用(可以是gunicorn或者你想用的其他方式)。
<VirtualHost *:80>
ServerName domain_2.com
ProxyPreserveHost On
# send all request to our app at /app1/*
ProxyPass / http://127.0.0.1:5001/app_1/
ProxyPassReverse / http://127.0.0.1:5001/app_1/
</VirtualHost>
<VirtualHost *:80>
ServerName domain_2.com
ProxyPreserveHost On
# send all request to our app at /app2/*
ProxyPass / http://127.0.0.1:5001/app_2/
ProxyPassReverse / http://127.0.0.1:5001/app_2/
</VirtualHost>
还有一个例子是一个域名指向多个Pyramid实例:
<VirtualHost *:80>
ServerName mydomain.com
ProxyPreserveHost On
# admin go to manager app on 5001
ProxyPass /media/manager/ http://127.0.0.1:5001/ retry=5
ProxyPassReverse /media/manager/ http://127.0.0.1:5001/
# downloads from server app on 5002
ProxyPass /media/server/ http://127.0.0.1:5002/ retry=5
ProxyPassReverse /media/server/ http://127.0.0.1:5002/
</VirtualHost>
24
Pyramid其实就是一个WSGI应用。这意味着它依赖于HTTP_HOST这个环境变量(由Host头设置)来确定应用的主机。简单来说,就是一切都是相对的。重点是,Pyramid对它能接受的内容没有限制,所以你可以随意设置,让它只接受特定域名的内容。当然,这一切都得从你的网络服务器是如何配置来给应用提供服务说起。
假设你在使用URL调度,你可能想设计一些自定义的路由条件,来检查request.host
的值,看看是否符合你的要求。如果这个条件返回False
,那么这个路由就永远不会匹配到那个主机的请求。
这个话题比较大,所以如果你能提供更多具体信息会更有帮助。例如,由于Pyramid是相对的,任何你想从'example.com'生成的URL,去重定向到'sub.example.com',都需要通过一个预生成器来完成。
def pregen(request, elements, kw):
kw['_app_url'] = 'http://sub.example.com'
return elements, kw
def req_sub(info, request):
return request.host.startswith('sub')
config.add_route('sub_only', '/',
custom_predicates=(req_sub,),
pregenerator=pregen)
config.add_route('foo', '/foo')
config.add_view(view, route_name-'foo')
def view(request):
# redirect the user to "http://sub.example.com", regardless of whether
# request.host is "example.com" or "sub.example.com"
return HTTPFound(request.route_url('sub_only'))