man kann http.client asyncron benutzen:
HTTPConnection sendet nur -> asyncore.dispatcher_with_send erledigt das fuer uns
und HTTPResponse empfaengt ueber eine makefile() socket -> wir geben ueber den HTTP header an, dass die verbindung geschlossen weden soll und buffern die daten in einen BinaryIO. wenn die verbindung zu ist, wissen wir das nichts mehr kommt und HTTPResponse kann ohne zu blocken lesen.
das mueste aber bei grossen seiten relativ viel arbeitspeicher kosten....
ps:
wie graeslich - die sonne geht auf - gute nacht ^^
Code: Alles auswählen
#python 3
from http import client
import socket
import io
import asyncore
class DirtySocket(asyncore.dispatcher_with_send):
def __init__(self, socket):
asyncore.dispatcher_with_send.__init__(self, socket)
self._in_buffer = io.BytesIO()
self._closed = False
self._cb = None
def handle_read(self):
read = self.socket.recv(1024)
if not read and not self._closed:
# kapier ich net...
self.handle_close()
self.close()
self._closed
return
self._in_buffer.write(read)
def sendall(self, data):
self.send(data)
def makefile(self, mode, buffsize):
self._in_buffer.seek(0)
return self._in_buffer
def set_cb(self, cb):
self._cb = cb
if self._closed:
self._cb()
def handle_close(self):
print('closed')
if self._cb:
self._cb()
self._closed = True
self.close()
#den garbage colector unter die arme nehmen?
del self._in_buffer
class AsyncHTTPConnection(client.HTTPConnection):
def __init__(self, *args, **kw):
client.HTTPConnection.__init__(self, *args, **kw)
def connect(self):
sock = socket.create_connection((self.host, self.port), self.timeout)
self.sock = DirtySocket(sock)
def getresponse(self, response_handler):
def cb():
response_handler(client.HTTPConnection.getresponse(self))
self.sock.set_cb(cb)
def endheaders(self, message_body=None):
self.putheader('Connection', 'close')
client.HTTPConnection.endheaders(self, message_body)
def main():
def handle_response(r):
print(r.status, r.reason)
print('doc size:', r.getheader("Content-Length"))
for i in range(30):
conn = AsyncHTTPConnection("www.python.com")
conn.request("GET", "/index.html")
conn.getresponse(handle_response)
asyncore.loop()
if __name__ == "__main__":
main()