go_dreamfactory/stress/model/request_model.go
2022-12-08 17:03:32 +08:00

215 lines
5.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package model 请求数据模型package model
package model
import (
"errors"
"fmt"
"net/http"
"strings"
"sync"
"time"
)
// 返回 code 码
const (
// HTTPOk 请求成功
HTTPOk = 200
// RequestErr 请求错误
RequestErr = 509
// ParseError 解析错误
ParseError = 510 // 解析错误
)
// 支持协议
const (
/// FormTypeHTTP http 协议
//FormTypeHTTP = "http"
/// FormTypeWebSocket webSocket 协议
FormTypeWebSocket = "webSocket"
/// FormTypeGRPC grpc 协议
//FormTypeGRPC = "grpc"
//FormTypeRadius = "radius"
)
// 校验函数
var (
// verifyMapHTTP http 校验函数
verifyMapHTTP = make(map[string]VerifyHTTP)
// verifyMapHTTPMutex http 并发锁
verifyMapHTTPMutex sync.RWMutex
// verifyMapWebSocket webSocket 校验函数
verifyMapWebSocket = make(map[string]VerifyWebSocket)
// verifyMapWebSocketMutex webSocket 并发锁
verifyMapWebSocketMutex sync.RWMutex
)
// RegisterVerifyWebSocket 注册 webSocket 校验函数
func RegisterVerifyWebSocket(verify string, verifyFunc VerifyWebSocket) {
verifyMapWebSocketMutex.Lock()
defer verifyMapWebSocketMutex.Unlock()
key := fmt.Sprintf("%s.%s", FormTypeWebSocket, verify)
verifyMapWebSocket[key] = verifyFunc
}
// Verify 验证器
type Verify interface {
GetCode() int // 有一个方法返回code为200为成功
GetResult() bool // 返回是否成功
}
// VerifyHTTP http 验证
type VerifyHTTP func(request *Request, response *http.Response) (code int, isSucceed bool)
// VerifyWebSocket webSocket 验证
type VerifyWebSocket func(request *Request, seq string, msg []byte) (code int, isSucceed bool)
// Request 请求数据
type Request struct {
URL string // URL
Form string // http/webSocket/tcp
// Method string // 方法 GET/POST/PUT
// Headers map[string]string // Headers
//Body string // body
Verify string // 验证的方法
Timeout time.Duration // 请求超时时间
Debug bool // 是否开启Debug模式
MaxCon int // 每个连接的请求数
Keepalive bool // 是否开启长连接
Code int // 验证的状态码
}
// getVerifyKey 获取校验 key
func (r *Request) getVerifyKey() (key string) {
return fmt.Sprintf("%s.%s", r.Form, r.Verify)
}
// GetVerifyHTTP 获取数据校验方法
func (r *Request) GetVerifyHTTP() VerifyHTTP {
verify, ok := verifyMapHTTP[r.getVerifyKey()]
if !ok {
panic("GetVerifyHTTP 验证方法不存在:" + r.Verify)
}
return verify
}
// GetVerifyWebSocket 获取数据校验方法
func (r *Request) GetVerifyWebSocket() VerifyWebSocket {
verify, ok := verifyMapWebSocket[r.getVerifyKey()]
if !ok {
panic("GetVerifyWebSocket 验证方法不存在:" + r.Verify)
}
return verify
}
// NewRequest 生成请求结构体
// url 压测的url
// verify 验证方法 在server/verify中 http 支持:statusCode、json webSocket支持:json
// timeout 请求超时时间
// debug 是否开启debug
// path curl文件路径 http接口压测自定义参数设置
func NewRequest(url string, verify string, code int, timeout time.Duration, debug bool,
maxCon int, keepalive bool) (request *Request, err error) {
form := ""
if strings.HasPrefix(url, "ws://") || strings.HasPrefix(url, "wss://") {
form = FormTypeWebSocket
}
if form == "" {
err = fmt.Errorf("url:%s 不合法,必须是完整http、webSocket连接", url)
return
}
var ok bool
switch form {
case FormTypeWebSocket:
// verify
if verify == "" {
verify = "json"
}
key := fmt.Sprintf("%s.%s", form, verify)
_, ok = verifyMapWebSocket[key]
if !ok {
err = errors.New("验证器不存在:" + key)
return
}
}
if timeout == 0 {
timeout = 30 * time.Second
}
request = &Request{
URL: url,
Form: form,
Verify: verify,
Timeout: timeout,
Debug: debug,
MaxCon: maxCon,
Keepalive: keepalive,
Code: code,
}
return
}
// getHeaderValue 获取 header
func getHeaderValue(v string, headers map[string]string) {
index := strings.Index(v, ":")
if index < 0 {
return
}
vIndex := index + 1
if len(v) >= vIndex {
value := strings.TrimPrefix(v[vIndex:], " ")
if _, ok := headers[v[:index]]; ok {
headers[v[:index]] = fmt.Sprintf("%s; %s", headers[v[:index]], value)
} else {
headers[v[:index]] = value
}
}
}
// Print 格式化打印
func (r *Request) Print() {
if r == nil {
return
}
result := fmt.Sprintf("request:\n form:%s \n url:%s \n", r.Form, r.URL)
//result = fmt.Sprintf("%s data:%v \n", result, r.Body)
result = fmt.Sprintf("%s verify:%s \n timeout:%s \n debug:%v \n", result, r.Verify, r.Timeout, r.Debug)
//result = fmt.Sprintf("%s http2.0%v \n keepalive%v \n maxCon:%v ", result, r.HTTP2, r.Keepalive, r.MaxCon)
fmt.Println(result)
return
}
// GetDebug 获取 debug 参数
func (r *Request) GetDebug() bool {
return r.Debug
}
// IsParameterLegal 参数是否合法
func (r *Request) IsParameterLegal() (err error) {
r.Form = "http"
// statusCode json
r.Verify = "json"
key := fmt.Sprintf("%s.%s", r.Form, r.Verify)
_, ok := verifyMapHTTP[key]
if !ok {
return errors.New("验证器不存在:" + key)
}
return
}
// RequestResults 请求结果
type RequestResults struct {
ID string // 消息ID
ChanID uint64 // 消息ID
Time uint64 // 请求时间 纳秒
IsSucceed bool // 是否请求成功
ErrCode int // 错误码
ReceivedBytes int64
}
// SetID 设置请求唯一ID
func (r *RequestResults) SetID(chanID uint64, number uint64) {
id := fmt.Sprintf("%d_%d", chanID, number)
r.ID = id
r.ChanID = chanID
}