如何在 pycurl 的 OPENSOCKETFUNCTION 中引发异常
How to raise Exception in OPENSOCKETFUNCTION of pycurl
根据https://curl.haxx.se/libcurl/c/CURLOPT_OPENSOCKETFUNCTION.html,
libcurl文档说这个回调可以用于IP地址黑名单,所以我决定用它来屏蔽所有私有IP地址。
我已在我的自定义回调函数中直接尝试 raise Exception
,但它不会将任何异常传播到 curl.perform
,除非发生超时。
是否可以从 curl.perform()
捕获我在回调函数中引发的异常?
提前致谢。
回调函数是纯C函数,C中没有异常。一个普通的C库,它对异常一无所知。
您可以在此处找到详细信息。gl/SLrKCF
pycurl 可能会在 perform
调用的回调中传播 Python 异常,但这目前尚未实现。现在每个回调都应该 return 一个适当的值来指示错误;在 opensocket 回调的情况下,此值为 CURL_SOCKET_BAD。 (不幸的是,pycurl 目前也没有公开这个常量;请改用 -1
。)
提供丰富错误信息的一种方法是将其存储在 Curl 对象本身上,如下所示:
import pycurl, random, socket
class ConnectionRejected(Exception): pass
def opensocket(curl, purpose, curl_address):
if random.random() < 0.5:
curl.exception = ConnectionRejected('Rejecting connection attempt in opensocket callback')
# should be pycurl.SOCKET_BAD in the next release
return -1
family, socktype, protocol, address = curl_address
s = socket.socket(family, socktype, protocol)
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
return s
c = pycurl.Curl()
c.setopt(c.URL, 'http://pycurl.io')
c.exception = None
c.setopt(c.OPENSOCKETFUNCTION,
lambda purpose, address: opensocket(c, purpose, address))
try:
c.perform()
except pycurl.error as e:
if e.args[0] == pycurl.E_COULDNT_CONNECT and c.exception:
print(c.exception)
else:
print(e)
此外,pycurl 目前没有正确处理 -1/CURL_SOCKET_BAD return - 它抱怨 -1 不是有效的 return 值(但功能不受影响). https://github.com/pycurl/pycurl/pull/484 将修复此问题。
根据https://curl.haxx.se/libcurl/c/CURLOPT_OPENSOCKETFUNCTION.html, libcurl文档说这个回调可以用于IP地址黑名单,所以我决定用它来屏蔽所有私有IP地址。
我已在我的自定义回调函数中直接尝试 raise Exception
,但它不会将任何异常传播到 curl.perform
,除非发生超时。
是否可以从 curl.perform()
捕获我在回调函数中引发的异常?
提前致谢。
回调函数是纯C函数,C中没有异常。一个普通的C库,它对异常一无所知。
您可以在此处找到详细信息。gl/SLrKCF
pycurl 可能会在 perform
调用的回调中传播 Python 异常,但这目前尚未实现。现在每个回调都应该 return 一个适当的值来指示错误;在 opensocket 回调的情况下,此值为 CURL_SOCKET_BAD。 (不幸的是,pycurl 目前也没有公开这个常量;请改用 -1
。)
提供丰富错误信息的一种方法是将其存储在 Curl 对象本身上,如下所示:
import pycurl, random, socket
class ConnectionRejected(Exception): pass
def opensocket(curl, purpose, curl_address):
if random.random() < 0.5:
curl.exception = ConnectionRejected('Rejecting connection attempt in opensocket callback')
# should be pycurl.SOCKET_BAD in the next release
return -1
family, socktype, protocol, address = curl_address
s = socket.socket(family, socktype, protocol)
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
return s
c = pycurl.Curl()
c.setopt(c.URL, 'http://pycurl.io')
c.exception = None
c.setopt(c.OPENSOCKETFUNCTION,
lambda purpose, address: opensocket(c, purpose, address))
try:
c.perform()
except pycurl.error as e:
if e.args[0] == pycurl.E_COULDNT_CONNECT and c.exception:
print(c.exception)
else:
print(e)
此外,pycurl 目前没有正确处理 -1/CURL_SOCKET_BAD return - 它抱怨 -1 不是有效的 return 值(但功能不受影响). https://github.com/pycurl/pycurl/pull/484 将修复此问题。