【问题标题】:redirect http to https in twisted以扭曲的方式将 http 重定向到 https
【发布时间】:2011-07-15 17:41:16
【问题描述】:

我正在使用twisted 运行一个django 应用程序。我现在从 http 移动到 https。如何在twisted中添加从http到https的重定向?

【问题讨论】:

  • 请详细说明您是如何使用 Twisted 运行您的 Django 应用程序的。

标签: ssl https twisted


【解决方案1】:

从 HTTP 上的任何给定路径重定向到 HTTPS 上的相同路径 (基于 Jean-Paul 针对我的评论提出的建议):

from twisted.python import urlpath
from twisted.web import resource, util

class RedirectToScheme(resource.Resource):
    """
    I redirect to the same path at a given URL scheme
    @param newScheme: scheme to redirect to (e.g. https)
    """

    isLeaf = 0

    def __init__(self, newScheme):
        resource.Resource.__init__(self)
        self.newScheme = newScheme

    def render(self, request):
        newURLPath = request.URLPath()
        # TODO Double check that == gives the correct behaviour here
        if newURLPath.scheme == self.newScheme:  
            raise ValueError("Redirect loop: we're trying to redirect to the same URL scheme in the request")
        newURLPath.scheme = self.newScheme
        return util.redirectTo(newURLPath, request)

    def getChild(self, name, request):
        return self

然后,您可以使用RedirectToScheme("https") 代替您的Site(),作为您要从中重定向的HTTP 站点。

注意:如果您要从中重定向的 HTTP 位于非标准端口上,您可能在 URLRequest 中有一个:<port> 部分,您还需要重写它。

【讨论】:

  • 这曾经可以工作,因为 redirectTo 曾经采用它的第一个参数(此处为newURLPath)并将其插入到带有%s 的字符串中。然而,最新版本的 Twisted 已经改变为做其他事情。现在将URLPath 传递给redirectTo 是一个错误。这有点像 Twisted 中的回归——但 redirectTo 之前被记录为采用 str(现在是 bytes)。所以......人们也可以说这是对 API 的误用。无论如何,要完成这项工作,您应该将 newURLPath 粉碎成一个字节字符串,然后再将其传递给 redirectTo - bytes(newURLPath)
  • 感谢有用的文章。我改变的一件事是对我有用的if newURLPath.scheme == self.newScheme。你能解释一下为什么它们不相等意味着重定向循环吗?
  • @AmaJayJB 是的,这似乎是一个错误。我已经做出了改变。不幸的是,我不再有权访问我最初为其编写此项目的项目,因此我无法查看它的历史。
  • 绝对没问题。以为我错过了什么(感谢您的回复!)
【解决方案2】:

在 Twisted Web 中生成重定向的一种简单方法是使用 Redirect 资源。使用 URL 实例化它并将其放入您的资源层次结构中。如果它被渲染,它将向该 URL 返回一个重定向响应:

from twisted.web.util import Redirect
from twisted.web.resource import Resource
from twisted.web.server import Site
from twisted.internet import reactor

root = Resource()
root.putChild("foo", Redirect("https://stackoverflow.com/"))

reactor.listenTCP(8080, Site(root))
reactor.run()

这将运行一个服务器来响应http://localhost:8080/ 的请求,并重定向到https://stackoverflow.com/

如果您在托管在 HTTPS 服务器上的 WSGI 容器中运行 Django,那么您的代码可能如下所示:

from twisted.internet import reactor
from twisted.web.wsgi import WSGIResource
from twisted.web.server import Site
from django import some_wsgi_application_object # Not exactly

root = WSGIResource(reactor, reactor.getThreadPool(), some_wsgi_application_object)
reactor.listenSSL(8443, Site(root), contextFactory)

reactor.run()

您可以运行额外的 HTTP 服务器,只需将第一个示例中的一些代码添加到第二个示例中,即可生成所需的重定向:

from twisted.internet import reactor
from twisted.web.wsgi import WSGIResource
from twisted.web.util import Redirect
from twisted.web.server import Site
from django import some_wsgi_application_object # Not exactly

root = WSGIResource(reactor, reactor.getThreadPool(), some_wsgi_application_object)
reactor.listenSSL(8443, Site(root), contextFactory)

old = Redirect("https://localhost:8443/")
reactor.listenTCP(8080, Site(old))

reactor.run()

【讨论】:

  • 对,但是对于 HTTPS 重定向,您希望重定向到的不是固定 URL,而是重定向到一个 URL a) 使用用户输入的任何主机名或地址 b) 到服务器上的相同路径用户输入的。 (例如,我会在 apache mod_rewrite 中使用 RewriteRule ^var/www-redirect/(.*)$ https://%{SERVER_NAME}/$1 [R,L] 执行此操作)。这可以通过重定向资源或其他扭曲方式实现吗?
  • 呃,我的 mod_rewrite 示例是针对文档根 /var/www-redirect 的重定向站点。 =)
  • 当然。 Redirect 实际上是一个非常简单的类,twistedmatrix.com/trac/browser/tags/releases/twisted-11.0.0/…>。它可以扩展为从请求中获取主机名并在重定向中使用它。您也可以查看ChildRedirector 以了解如何保留请求路径。
猜你喜欢
  • 2018-05-03
  • 2019-02-23
  • 2012-08-22
  • 2017-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多