倾旋的博客

倾旋的博客

现阶段在进行有效性验证/攻击模拟相关的安全研究工作,我的博客会记录一些我的学习过程和部分安全技术研究成果。

02 Apr 2019

BaseRequestHandler 传参问题

最近在写Cooolis-ms的时候遇到一个坑,学艺不精靠搜索,最终解决了。

问题主要是不知道如何把ArgumentParser处理的参数传递到继承了BaseRequestHandlerclass中。

通常情况下,创建一个TCP的socketserver代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19

import socketserver

class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            try:
                self.data = self.request.recv(1024).strip()
                print("{} wrote:".format(self.client_address[0]))
                print(self.data)
                self.request.send(self.data.upper())
            except ConnectionResetError as e:
                print("err",e)
                break

if __name__ == "__main__":
    HOST,PORT = "localhost",9999
    server = socketserver.ThreadingTCPServer((HOST,PORT),MyTCPHandler)
    server.serve_forever() 

假若我想对MyTCPHandler进行一些修饰,添加一些成员属性,那就需要覆盖__init__函数,很多资料告诉我调用super可以解决,但是BaseRequestHandler是有参数的,这些参数必须由ThreadingTCPServer进行传递。

因此,通过stackoverflow上的一个大神解决了问题:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import socketserver

class MyTCPHandler(socketserver.BaseRequestHandler):
    def __init__(self,request, client_address, server,name):
        self.name = name
        super().__init__(request, client_address, server)
    def handle(self):
        while True:
            try:
                self.data = self.request.recv(1024).strip()
                print("{} wrote:".format(self.client_address[0]))
                print(self.data)
                self.request.send(self.data.upper())
            except ConnectionResetError as e:
                print("err",e)
                break
    @classmethod
    def Creator(cls, *args, **kwargs):
        def _HandlerCreator(request, client_address, server):
            cls(request, client_address, server, *args, **kwargs)
        return _HandlerCreator

if __name__ == "__main__":
    HOST,PORT = "localhost",9999
    name = 'handle'
    server = socketserver.ThreadingTCPServer((HOST,PORT),MyTCPHandler.Creator(name))
    server.serve_forever()

调用Creator就可以传递多余的参数。

这个问题解决了,代码都在Cooolis-ms里体现。