扭曲的HTTPS客户端 [英] Twisted HTTPS Client

查看:87
本文介绍了扭曲的HTTPS客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前在使用扭曲的python库访问通过https托管的内容时遇到一些麻烦.我是这个库的新手,并假设我缺少一些导致问题的概念,但可能并非基于示例.

I am currently having some trouble accessing content hosted via https using the twisted python library. I am new to this library, and am assuming there is some concept I am missing that's causing the issue, but perhaps not based upon the example.

这里是指向我收集示例的页面的链接: https://twistedmatrix.com/documents/current/web/howto/client. html

Here is a link to the page in which I gathered the example: https://twistedmatrix.com/documents/current/web/howto/client.html

在标题下基于SSL的HTTP

from twisted.python.log import err
from twisted.web.client import Agent
from twisted.internet import reactor
from twisted.internet.ssl import optionsForClientTLS

def display(response):
    print("Received response")
    print(response)

def main():
    contextFactory = optionsForClientTLS(u"https://example.com/")
    agent = Agent(reactor, contextFactory)
    d = agent.request("GET", "https://example.com/")
    d.addCallbacks(display, err)
    d.addCallback(lambda ignored: reactor.stop())
    reactor.run()

if __name__ == "__main__":
    main()

运行此代码时,它直接失败.我收到一个看起来像这样的错误:

When running this code, it straight up fails. I get an error that looks like this:

Traceback (most recent call last):
  File "https.py", line 19, in <module>
    main()
  File "https.py", line 11, in main
    contextFactory = optionsForClientTLS(u"https://example.com/")
  File "/home/amaricich/.local/lib/python2.7/site-packages/twisted/internet/_sslverify.py", line 1336, in optionsForClientTLS
    return ClientTLSOptions(hostname, certificateOptions.getContext())
  File "/home/amaricich/.local/lib/python2.7/site-packages/twisted/internet/_sslverify.py", line 1198, in __init__
    self._hostnameBytes = _idnaBytes(hostname)
  File "/home/amaricich/.local/lib/python2.7/site-packages/twisted/internet/_sslverify.py", line 86, in _idnaBytes
    return idna.encode(text)
  File "/usr/local/lib/python2.7/dist-packages/idna/core.py", line 355, in encode
    result.append(alabel(label))
  File "/usr/local/lib/python2.7/dist-packages/idna/core.py", line 276, in alabel
    check_label(label)
  File "/usr/local/lib/python2.7/dist-packages/idna/core.py", line 253, in check_label
    raise InvalidCodepoint('Codepoint {0} at position {1} of {2} not allowed'.format(_unot(cp_value), pos+1, repr(label)))
idna.core.InvalidCodepoint: Codepoint U+003A at position 6 of u'https://example' not allowed

此错误使我相信传递到 optionsForClientTLS 的参数不正确.它需要一个主机名而不是一个完整的URL,因此我将参数简称为 example.com .进行更改后,功能将成功完成.

This error lead me to believe the parameter being passed into optionsForClientTLS were incorrect. It calls for a hostname and not a full url, so I shortened the parameter to simply example.com. Once that change was made, the function completed successfully.

不幸的是,在进行更改之后,脚本现在在调用 agent.request 的行中失败了.它提供的错误是这样的:

Unfortunately though, after making the change, the script now failed at the line invoking agent.request. The error it supplied was this:

Traceback (most recent call last):
  File "https.py", line 19, in <module>
    main()
  File "https.py", line 13, in main
    d = agent.request("GET", "https://example.com/")
  File "/home/amaricich/.local/lib/python2.7/site-packages/twisted/web/client.py", line 1596, in request
    endpoint = self._getEndpoint(parsedURI)
  File "/home/amaricich/.local/lib/python2.7/site-packages/twisted/web/client.py", line 1580, in _getEndpoint
    return self._endpointFactory.endpointForURI(uri)
  File "/home/amaricich/.local/lib/python2.7/site-packages/twisted/web/client.py", line 1456, in endpointForURI
    uri.port)
  File "/home/amaricich/.local/lib/python2.7/site-packages/twisted/web/client.py", line 982, in creatorForNetloc
    context = self._webContextFactory.getContext(hostname, port)
AttributeError: 'ClientTLSOptions' object has no attribute 'getContext'

此错误使我相信,由optionsForClientTLS生成的对象不是在创建时预期传递给代理的对象类型.正在尝试调用一个不存在的函数.话虽如此,我有两个问题.

This error leads me to believe that the object being produced by optionsForClientTLS is not the object type that is expected to be passed into the Agent upon creation. A function is trying to be invoked that does not exist. With all that said, I have two questions.

  1. 是否已弃用此示例?前面发出http请求的示例都像魅力一样工作.我是在做错什么,还是该示例不再有效?
  2. 我只是在寻找一种使用HTTPS从服务器检索数据的简单方法.如果不是通过这种方式解决问题,那么是否有人熟悉如何使用Twisted发出HTTPS请求?

推荐答案

是的,您完全正确地认为文档中的示例是错误的.我注意到使用treq 时,错误.尝试遵循v14中的此示例 .话虽如此,您应该使用 treq ,而不是尝试直接使用Twisted .大多数繁重的工作已经为您解决.这是您的示例的简单转换:

Yes you're absolutely correct that the example on the docs is wrong. I noticed the bug while working w/ treq. Try following this example from v14. With that being said, you should use treq as opposed to trying to use Twisted directly. Most of the heavy lifting has been taken care of for you. Here's an simple conversion of your example:

from __future__ import print_function
import treq
from twisted.internet import defer, task
from twisted.python.log import err

@defer.inlineCallbacks
def display(response):
    content = yield treq.content(response)
    print('Content: {0}'.format(content))

def main(reactor):
    d = treq.get('https://twistedmatrix.com')
    d.addCallback(display)
    d.addErrback(err)
    return d

task.react(main)

如您所见,treq为您处理SSL内容. display()回调函数可用于提取HTTP响应的各种组件,例如标头,状态代码,正文等.如果仅需要单个组件(例如响应正文),则可以进一步简化,例如:

As you can see treq takes care of the SSL stuff for you. The display() callback function can be used to extract various components of the HTTP response, such as headers, status codes, body, etc. If you only need a single component, such as the response body, then you can simplify further like so:

def main(reactor):
    d = treq.get('https://twistedmatrix.com')
    d.addCallback(treq.content)     # get response content when available
    d.addErrback(err)
    d.addCallback(print)
    return d

task.react(main)

这篇关于扭曲的HTTPS客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆