定义Request、Response和Url类

1、介绍

定义Request、Response和Url类分别用于管理http请求、响应和url的数据与方法。

这三个类所对应的数据和方法,在渗透测试业务中应用非常广泛,同时存在高度的定制化需求,比如Request的id对象属性、send_time和wait_time对象属性等。

而同时,requests模块、mitmporxy模块等所使用的这三个类,要么比较封闭不支持外部引用,要么提供的属性和方法简陋、体验不佳。

综合来看,定义这三个类,是非常有必要的。能够高度定制与优化,且方便掌握。

2、Request类

编程规范之一:通过属性持有变量和方法,比直接继承属性和方法更好。

结合需求来说,就是Request和Response的共同需求主要是集中在头部处理。但不建议定义父类,来进行头部操作。而是分别基于头部对象Headers()实现操作。

而除了头部操作,Request和Response几乎没有必要再定义父类。

2.1 类初始化方法

def __init__(self, url: str = '', https_flag: bool = False, message: str = ''):
  • 定义了两类设置方法:url和请求报文
  • url,str类型。如果使用,则其包括协议在内的url
  • https_flag,bool类型。表示请求报文的协议是否为https
  • message,str类型。完整的请求报文。解析前会替换\r为空字符串

2.2 对象属性

# 请求方法,默认是get
self.method = 'GET'
# 协议版本
self.protocol_version = 'HTTP/1.1'
# 请求头部,至少有host这个头部字段。
self.headers = Headers()
# 请求体部
self.body = ''
# url,主要是包含协议部分。
self.url = ''
# 编号,默认为-1,从1开始递增
self.id = -1
# 请求的发送时间,格式是20230423 10:00:00
self.send_time = ''
# 响应时延,float类型,单位是秒
self.wait_time = -1
# 响应对象
self.res = None

2.3 方法

(1)send

def send(self, timeout: float = None, d: dict = None):
  • 发送请求
  • timeout,float类型,设置如果发送之后多长时间未接收到响应会报异常,单位为秒。
    • 实际上,该参数是作为requests.request函数的参数,而产生作用。
    • 对于requests.request函数,timeout参数如果设置为0或负数,并不会发出请求,而是直接报异常,没有意义。而如果设置为None,则表示一直等待响应
    • 所以,在本方法中,会预先判断timeout如果是小于等于0,则转为None值
  • d,dict类型,即请求头部。其作用是设置固有的头部字段,以覆盖临时的请求头部字段。常用于user-agent
  • 该方法,实际上是调用requests.request函数执行请求,将响应结果通过Response类转化,并记录请求过程相关数据,包括send_time和wait_time等
  • 方法执行过程中,会将请求的实际头部重新赋值给给请求的头部headers对象

(2)get_message

def get_message(self):
    """get_message()->str"""
  • 获取请求报文
  • 值得注意的是,请求头部为空时的换行情况,虽然不可能出现头部为空,至少有host字段 

(3)clone

def clone(self):
    """clone() -> Request""
  • 克隆、且为深度克隆,返回Request对象
  • 只克隆请求状态相关的属性,而包括响应在内的其它属性为初始值。该方法主要用于渗透测试时,重复性测试,或者在样本基础上更改url、请求头部、请求体部中某一部分的测试
  • headers也被深度克隆,即克隆对象操作headers属性不影响被克隆对象

3、Response类

3.1 类初始方法

def __init__(self, res=None):
  • res为None,表示不是直接解析,而是手动为响应的各属性赋值
  • res为str,且不为空字符串,则是读取日志进行解析
  • res为requests.Resposne对象,即对requests.request函数执行结果进行解析,封装为自定义Response对象

3.2 对象属性

# 协议/版本
self.protocol_version = 'HTTP/1.1'
# 响应状态码
self.status_code = ''
# 响应状态描述符
self.reason = ''
# 响应头部字段
self.headers = Headers()
# 响应体部
self.body = ''

3.3 方法

def get_message(self):
    """get_message() -> str"""
  • 获取请求报文
  • 值得注意的是,请求头部为空时的换行情况,此时处理为响应行与响应体部之间\n\n分隔

4、Url类

4.1 类初始化方法

def __init__(self, string=''):
  • 为空字符串,表示不是直接解析,而是手动为url的各属性赋值
  • 不为空字符串,则进行url解析

4.2 对象属性

# 协议名称,一般为http://或https://
self.schema = ''
# 主机名称,可能包含用户名和密码部分,可能是ip、域名或者是localhost
self.hostname = ''
# 端口,可能不存在。如果存在,为:8080形式
self.port = ''
# 路径,可能不存在。如果存在,为/a/b/c形式
self.path = ''
# 直接参数,可能不存在。如果存在,为?name=&password=形式
self.query = ''
# hash部分,可能不存在。如果存在,为#123456形式
self.fragment = ''

4.3 方法

def set_url(self, args):
def toString(self):
def clone(self):
def address_arr(self):

 

posted @ 2023-05-18 17:42  挖洞404  阅读(33)  评论(0编辑  收藏  举报