This is about the processing of the previously related transfer encoding of the chunk encoding transmission. Did not do the compression decoding processing.
ImportTornado.ioloopImportTornado.iostreamImportSocketclassWebRequest (object): Line_end= b'\ r \ n' def __init__(Self, host, port=80, callback=None): Self.host=host Self.port=Port Self.headers={} self.data="'Self.callback=Callback Self.transfer='Stream'Self.http_ver_with_status="'s=Socket.socket (socket.af_inet, socket. Sock_stream, 0) Self.stream=Tornado.iostream.IOStream (s) self.stream.connect ((Self.host, Self.port), self.send_request) defsend_request (self): Self.stream.write (b"get/http/1.0\r\nhost:%s\r\n\r\n"%self.host) Self.stream.read_until (self. Line_end* *, Self.on_headers)defon_headers (self, data): Lines=Data.split (self. Line_end) Self.http_ver_with_status=lines.pop (0) forLineinchLines:parts= Line.split (b":", 1) ifLen (Parts) = = 2: Self.headers[parts[0].strip ()]= Parts[1].strip ()if 'Content-length' inchself.headers:ifInt (self.headers[b"Content-length"]) >0:self.transfer='content_length'self.stream.read_bytes (int (self.headers[b"Content-length"]), self.on_body)Else: Self.callback (self) self.stream.close ()elifSelf.headers.get (b'transfer-encoding') =='chunked': Self.transfer='chunked'Self.on_chunk ()Else: Self.transfer='Stream'Callback=Lambdadata:self.on_stream (data, True) Streaming_callback=Lambdadata:self.on_stream (data, False) Self.stream.read_until_close (callback, Streaming_callback)defon_body (self, data): Self.data+=data Self.callback (self) self.stream.close ()defOn_chunk (self): Self.stream.read_until_regex (self). Line_end, Self.on_chunk_header)defOn_chunk_header (self, data): Data=Data.strip (self. Line_end) Length= Int (data, 16) ifLength >0:self.stream.read_bytes (Length+Len (self. Line_end), Self.on_chunk_data)Else: self.stream.read_bytes (length+Len (self. Line_end), Self.on_chunk_end)defon_chunk_end (self, data): Self.callback (self) self.stream.close ()defOn_chunk_data (self, data): Self.data+=Data self.on_chunk ()defOn_stream (self, data, finish=False):#Do some thing ifFinish:self.data+=data Self.callback (self) self.stream.close ()Else: Self.data+=DatadefCallback (req):PrintReq.http_ver_with_statusPrint "Transfer:", Req.transferPrint "Headers:", Req.headers#print "Data:", Req.datareq = WebRequest ('cn.bing.com', 80, on_bing)defon_bing (req):PrintReq.http_ver_with_statusPrint "Transfer:", Req.transferPrint "Headers:", Req.headers#print "Data:", Req.datatornado.ioloop.IOLoop.instance (). Stop ()if __name__=='__main__': Req= WebRequest ('valpha.gameloft.com', 20000, Callback) Tornado.ioloop.IOLoop.instance (). Start ()
Python Tornado simple HTTP request