I asked a question o tym, jak zdławić przesyłanie Pythona, który wysłał mnie do this answer, gdzie zostałem poinformowany o małej bibliotece pomocniczej o nazwie socket-throttle
. To wszystko w porządku i dandy dla zwykłego HTTP i prawdopodobnie również dla większości zwykłych zastosowań gniazda. Jednak staram się udusić połączenia SSL i próbuje połączyć socket-throttle
z biblioteką Zdjęcie SSL (stosowane w sposób dorozumiany przez requests
) powoduje wyjątek głęboko w trzewiach biblioteki:Przepustowość przepustowości połączenia SSL
File "***.py", line 590, in request
r = self.session.get(url, headers=extra_headers)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 394, in get
return self.request('GET', url, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 382, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 485, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 324, in send
timeout=timeout
File "/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py", line 478, in urlopen
body=body, headers=headers)
File "/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py", line 285, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/lib/python2.7/httplib.py", line 973, in request
self._send_request(method, url, body, headers)
File "/usr/lib/python2.7/httplib.py", line 1007, in _send_request
self.endheaders(body)
File "/usr/lib/python2.7/httplib.py", line 969, in endheaders
self._send_output(message_body)
File "/usr/lib/python2.7/httplib.py", line 829, in _send_output
self.send(msg)
File "/usr/lib/python2.7/httplib.py", line 791, in send
self.connect()
File "/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connection.py", line 95, in connect
ssl_version=resolved_ssl_version)
File "/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util.py", line 643, in ssl_wrap_socket
ssl_version=ssl_version)
File "/usr/lib/python2.7/ssl.py", line 487, in wrap_socket
ciphers=ciphers)
File "/usr/lib/python2.7/ssl.py", line 211, in __init__
socket.__init__(self, _sock=sock._sock)
File "***/socket_throttle.py", line 54, in __getattr__
return getattr(self._wrappedsock, attr)
AttributeError: '_socket.socket' object has no attribute '_sock'
Dobrze, że to downer. Jak można się przekonać, pakiet ssl
próbuje użyć jednego z prywatnych pól gniazda, _sock
zamiast samego socket
. (Czy nie chodzi o prywatne pola, do których nie ma się dostępu z zewnątrz?) Jeśli spróbuję wstrzyknąć się w to pole na moim obiekcie ThrottledSocket
, natknę się na ten problem:
File "/home/alex/dev/jottalib/src/jottalib/JFS.py", line 590, in request
r = self.session.get(url, headers=extra_headers)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 394, in get
return self.request('GET', url, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 382, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 485, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 324, in send
timeout=timeout
File "/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py", line 478, in urlopen
body=body, headers=headers)
File "/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py", line 285, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/lib/python2.7/httplib.py", line 973, in request
self._send_request(method, url, body, headers)
File "/usr/lib/python2.7/httplib.py", line 1007, in _send_request
self.endheaders(body)
File "/usr/lib/python2.7/httplib.py", line 969, in endheaders
self._send_output(message_body)
File "/usr/lib/python2.7/httplib.py", line 829, in _send_output
self.send(msg)
File "/usr/lib/python2.7/httplib.py", line 791, in send
self.connect()
File "/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connection.py", line 95, in connect
ssl_version=resolved_ssl_version)
File "/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util.py", line 643, in ssl_wrap_socket
ssl_version=ssl_version)
File "/usr/lib/python2.7/ssl.py", line 487, in wrap_socket
ciphers=ciphers)
File "/usr/lib/python2.7/ssl.py", line 241, in __init__
ciphers)
TypeError: must be _socket.socket, not ThrottledSocket
Co teraz? Czy jest jeszcze gdzieś w tym miejscu, gdzie mogę ograniczyć szybkość komunikacji Pythona? Czy jest to czystszy sposób na to, niż zastąpienie implementacji gniazda? Co zresztą okazuje się być dyskusyjne, ponieważ pakiet ssl
próbuje go ominąć.
Powodem 'ssl' jest zakorzenienie w prywatnych' wokół pól socket' jest, pod spodem C Biblioteka dla TLS, 'openssl', bardzo chce rozmawiać bezpośrednio do Ja- deskryptor gniazda poziomu. Zamiast tego można zmienić 'socket-throttle' tak, aby powtarzał' ssl.wrap_socket' * zamiast * 'socket.socket' - potrzebujesz owijki przepustnicy * poza * opakowaniem TLS. Nie mam zamiaru zamieszczać tego jako odpowiedzi, ponieważ nie wiem, czy to zadziała, a nawet jeśli tak się stanie, będzie to prawdopodobnie dużo majsterkowania. Powodzenia? – zwol
Biblioteka ssl nie gniewa się w prywatnych jajach obiektu 'socket.socket'. 'ssl.wrap_socket' zwraca nowy obiekt, który przechowuje oryginalną instancję' socket.socket' na nim jako '_sock'. Ma wszelkie prawo do korzystania z własnego prywatnego atrybutu. Następnym razem przeczytaj źródło przed wydaniem takich oświadczeń o innych bibliotekach. Ponadto, jako punkt porządku, wyjątek pochodzi z 'ssl' /' socket-throttle', ale powoduje przepełnienie żądań. Żądania nie są za to odpowiedzialne. –