0

我正在尝试使用 Python 的 Twisted 框架编写一个 Web 应用程序。如果作为独立服务器(ala twistd)运行,或者如果 Apache 反向代理它,我希望应用程序能够工作。例如

阿帕奇https://example.com/twisted/ --> https://internal.example.com/

在做了一些研究之后,似乎我需要使用 vhost.VHostMonsterResource 来完成这项工作。因此,我使用以下指令设置了 apache:

ProxyPass /twisted https://localhost:8090/twisted/https/127.0.0.1:443

这是我的基本 SSL 服务器:

from twisted.web import server, resource, static
from twisted.internet import reactor
from twisted.application import service, internet
from twisted.internet.ssl import SSL
from twisted.web import vhost

import sys
import os.path
from textwrap import dedent

PORT = 8090
KEY_PATH = "/home/waldbiec/projects/python/twisted"
PATH = "/home/waldbiec/projects/python/twisted/static_files"

class Index(resource.Resource):
    def render_GET(self, request):
        html = dedent("""\
            <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
            <html>
            <head>
                <title>Index</title>
            </head>
            <body>
                <h1>Index</h1>
                <ul>
                    <li><a href="/files/">Files</a></li>
                </ul>
            </body>
            </html>
            """)
        return html

class ServerContextFactory:
    def getContext(self):
        """
        Create an SSL context.

        Similar to twisted's echoserv_ssl example, except the private key
        and certificate are in separate files.
        """
        ctx = SSL.Context(SSL.SSLv23_METHOD)
        ctx.use_privatekey_file(os.path.join(KEY_PATH, 'serverkey.pem'))
        ctx.use_certificate_file(os.path.join(KEY_PATH, 'servercert.pem'))
        return ctx

class SSLService(internet.SSLServer):
    def __init__(self):
        root = resource.Resource()
        root.putChild("", Index())
        root.putChild("twisted", vhost.VHostMonsterResource())
        root.putChild("files", static.File(PATH))

        site = server.Site(root)
        internet.SSLServer.__init__(self, PORT, site, ServerContextFactory())

application = service.Application("SSLServer")
ssl_service = SSLService()
ssl_service.setServiceParent(application)

它几乎可以工作——但是当使用 apache 作为反向代理时,索引页面上的“文件”链接的行为并不像我想要的那样,因为它是一个绝对链接。

我的主要问题是,除了使用相对链接之外,是否有某种方法可以计算链接的完整 URL 路径应该是什么,以使链接仍然可以在独立服务器模式下工作?第二个问题是,我是否正确使用了 VHostMonsterResource?我没有找到太多文档,我从网上找到的示例中拼凑了我的代码。

4

3 回答 3

1

This seems like too much work. Why use VHostMonsterResource at all? You may have very specific reasons for wanting some of this but....Most times:

  • Have apache handle the ssl. apache then passes off to your twisted app serving non SSL goodies back to apache. Documentation all over the net on the apache config stuff.

  • you can sill add another server on an ssl port if you really want to

Haven't tested but structure more like:

root = resource.Resource()
root.putChild("", Index())
root.putChild("files", static.File(PATH))

http = internet.TCPServer(8090, server.Site(root))
# change this port # to 443 if no apache
https= internet.SSLServer(8443, server.Site(root), ServerContextFactory())

application = service.Application("http_https_Server")
http.setServiceParent(application)
https.setServiceParent(application)

Dev tip: During development, for the cost of a couple of extra lines you can add an ssl server so that you can ssh into the running web_server and inspect variables and other state. Way cool.

ssl = internet.TCPServer(8022, getManholeFactory(globals(), waldbiec ='some non-system waldbiec passwork')) 
ssl.setServiceParent(application)
于 2012-07-14T00:02:49.610 回答
0

因此,在深入研究 vhost.VHostMonsterResource 源之后,我确定我可以创建另一个资源,该资源可以让反向代理 URL 前缀由 Apache ProxyPass URL 中的附加标记指定。

首先,我终于发现 vhost.VHostMonsterResource 应该是后端网站中的一个特殊 URL,它从 URL 路径中编码的数据中找出反向代理主机和端口。URL 路径(无方案和网络位置)如下所示:

/$PATH_TO_VHMONST_RES/$REV_PROXY_SCHEME/$REV_PROXY_NETLOC/real/url/components/

$PATH_TO_VHMONST : Path in the (internal) twisted site that corresponds to the VHostMonsterResource resource.
$REV_PROXY_SCHEME : http or https that is being used by the reverse proxy (Apache).
$REV_PROXY_NETLOC : The net location (host and port) or the reverse proxy (Apache).

因此,您可以通过在 URL 中编码此信息来控制反向代理的配置。结果是扭曲的站点将理解 HTTP 请求来自反向代理。

但是,如果您按照我的原始示例代理外部站点的子树,则此信息将丢失。所以我的解决方案是创建一个额外的资源来解码额外的路径信息。新的代理 URL 路径变为:

/$PATH_TO_MANGLE_RES/$REV_PROXY_PATH_PREFIX/$VHOSTMONST_MARKER/$REV_PROXY_SCHEME/$REV_PROXY_NETLOC/real/url/components/

$PATH_TO_MANGLE_RES : The path to the resource that decodes the reverse proxy path info.
$REV_PROXY_PATH_PREFIX : The subtree prefix of the reverse proxy.
$VHOSTMONST_MARKER : A path component (e.g. "vhost") that signals a VHostMonster Resource should be used to further decode the path.
于 2012-07-22T19:54:47.073 回答
0

配置 Twisted 应用程序,使其知道自己的根位置。它可以使用该信息正确生成 URL。

于 2012-07-13T17:31:27.807 回答