说明
server.py写了一个tornado服务,监听了8956端口,client.py组装请求并发送到这个端口,需要先启动server.py,然后再启动client.py才能看到测试效果。
server.py
#server.pyimport jsonfrom sys import getsizeofimport tornadoimport tornado.httpserverimport tornado.ioloopimport tornado.webclass TestHandler(tornado.web.RequestHandler): def post(self): # 获取请求头部的大小 print("请求报文头部: {0}".format(self.request.headers.__dict__)) print("请求报文内容大小: {0}".format(self.request.headers["Content-Length"])) print("请求报文内容解压后的大小: {0}".format(getsizeof(self.request.body))) return self.finish(self.request.body)class Application(tornado.web.Application): def __init__(self): handlers = [ (r'/test',TestHandler) ] settings = dict( ) tornado.web.Application.__init__(self, handlers, **settings)if __name__ == '__main__': app_port = 8965 app = Application() http_server = tornado.httpserver.HTTPServer(app, decompress_request=True) http_server.listen(app_port) print("http://localhost:8965") tornado.ioloop.IOLoop.instance().start()
与没有特殊设置的tornado配置相比只是在初始化时对httpserver增加了一个配置项
decompress_request=True
在有这个配置项的时候,如果post请求的报文头部有说明编码方式是 gzip时,tornado将会对这个请求进行解压操作。
如果不设置这个操作,当收到gzip类型的请求时会出现一句告警日志
WARNING:tornado.general:Unsupported Content-Encoding: gzip
并且不会对请求进行解压操作。
client.py
import gzipimport jsonfrom io import BytesIOfrom sys import getsizeof#client.pyfrom tornado.escape import utf8from tornado.httpclient import HTTPRequest, HTTPClientif __name__ == '__main__': url = 'http://localhost:8965/test' try: #请求内容 requ_data = "111111111111111111111111111111111111111111111"*6000 #对请求内容进行gzip压缩操作 bytesio = BytesIO() gzip_file = gzip.GzipFile(mode='w', fileobj=bytesio) gzip_file.write(utf8(requ_data)) gzip_file.close() compressed_requ_data = bytesio.getvalue() print("请求内容压缩前的大小: {0}".format(getsizeof(requ_data))) print("请求内容压缩后的大小: {0}".format(getsizeof(compressed_requ_data))) # 发送未压缩的请求 # request = HTTPRequest(url=url, method='POST', body=requ_data) # 发送压缩后的请求 request = HTTPRequest(url=url, method='POST', headers={'Content-Encoding': 'gzip'}, body=compressed_requ_data) http_client = HTTPClient() response = http_client.fetch(request) #由于回复的内容太大了,因此注释掉了输出 #print("回复内容: {0}".format(response.body.decode())) print("请求报文头部: {0}".format(request.headers.__dict__)) print("请求报文内容大小: {0}".format(request.headers["Content-Length"])) print("回复头部: {0}".format(request.response.__dict__)) print("回复报文内容大小: {0}".format(response.headers["Content-Length"])) print("回复报文内容解压后大小: {0}".format(getsizeof(response.body))) except Exception as e: print('异常', e)
在发送压缩请求时需要设置报文的头部
headers={'Content-Encoding': 'gzip'}
上面的server.py收到这种类型的请求时就会进行解压操作
测试输出:
client
请求内容压缩前的大小: 270049请求内容压缩后的大小: 331请求报文头部: {'_as_list': {'Connection': ['close'], 'Content-Encoding': ['gzip'], 'Accept-Encoding': ['gzip'], 'Content-Length': ['298'], 'Host': ['localhost:8965'], 'Content-Type': ['application/x-www-form-urlencoded']}, '_last_key': None, '_dict': {'Connection': 'close', 'Content-Encoding': 'gzip', 'Accept-Encoding': 'gzip', 'Content-Length': '298', 'Host': 'localhost:8965', 'Content-Type': 'application/x-www-form-urlencoded'}}请求报文内容大小: 298回复头部: {'_as_list': {'Connection': ['close'], 'Content-Encoding': ['gzip'], 'Accept-Encoding': ['gzip'], 'Content-Length': ['298'], 'Host': ['localhost:8965'], 'Content-Type': ['application/x-www-form-urlencoded']}, '_last_key': None, '_dict': {'Connection': 'close', 'Content-Encoding': 'gzip', 'Accept-Encoding': 'gzip', 'Content-Length': '298', 'Host': 'localhost:8965', 'Content-Type': 'application/x-www-form-urlencoded'}}回复报文内容大小: 298
server
请求报文头部: {'_as_list': {'Accept-Encoding': ['gzip'], 'Content-Length': ['298'], 'X-Consumed-Content-Encoding': ['gzip'], 'Connection': ['close'], 'Content-Type': ['application/x-www-form-urlencoded'], 'Host': ['localhost:8965']}, '_dict': {'Accept-Encoding': 'gzip', 'Content-Length': '298', 'X-Consumed-Content-Encoding': 'gzip', 'Connection': 'close', 'Content-Type': 'application/x-www-form-urlencoded', 'Host': 'localhost:8965'}, '_last_key': 'X-Consumed-Content-Encoding'}请求报文内容大小: 298请求报文内容解压后的大小: 270033
对回复进行压缩
tornado初始话时增加一个
compress_response=True
如下
class Application(tornado.web.Application): def __init__(self): handlers = [ (r'/test',TestHandler) ] settings = dict( compress_response=True ) tornado.web.Application.__init__(self, handlers, **settings)
如果请求的报文头部里面有要求 'Accept-Encoding': 'gzip', 那么tornado会对回复的报文进行压缩操作, 请求方收到回复时需要自己手动对这个进行解压操作。
如果使用tornado的HTTPClient话只需要添加如下设置即可
decompress_response=True
如下
request = HTTPRequest(url=url, method='POST', headers={'Content-Encoding': 'gzip', 'Accept-Encoding': 'gzip'}, body=compressed_requ_data, decompress_response=True)