mirror of
https://github.com/aykhans/dodo.git
synced 2025-06-03 04:46:41 +00:00
Value generator initial commit
This commit is contained in:
parent
924bd819ee
commit
f248c2af96
1
go.mod
1
go.mod
@ -5,6 +5,7 @@ go 1.24.2
|
||||
require (
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.7
|
||||
github.com/valyala/fasthttp v1.62.0
|
||||
github.com/brianvoe/gofakeit/v7 v7.2.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
|
2
go.sum
2
go.sum
@ -1,5 +1,7 @@
|
||||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/brianvoe/gofakeit/v7 v7.2.1 h1:AGojgaaCdgq4Adzrd2uWdbGNDyX6MWNhHdQBraNfOHI=
|
||||
github.com/brianvoe/gofakeit/v7 v7.2.1/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.7 h1:m+LbHpm0aIAPLzLbMfn8dc3Ht8MW7lsSO4MPItz/Uuo=
|
||||
|
@ -1,14 +1,18 @@
|
||||
package requests
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/aykhans/dodo/config"
|
||||
"github.com/aykhans/dodo/types"
|
||||
"github.com/aykhans/dodo/utils"
|
||||
"github.com/brianvoe/gofakeit/v7"
|
||||
"github.com/valyala/fasthttp"
|
||||
)
|
||||
|
||||
@ -21,6 +25,11 @@ type Request struct {
|
||||
getRequest RequestGeneratorFunc
|
||||
}
|
||||
|
||||
type keyValueGenerator struct {
|
||||
key func() string
|
||||
value func() string
|
||||
}
|
||||
|
||||
// Send sends the HTTP request using the fasthttp client with a specified timeout.
|
||||
// It returns the HTTP response or an error if the request fails or times out.
|
||||
func (r *Request) Send(ctx context.Context, timeout time.Duration) (*fasthttp.Response, error) {
|
||||
@ -101,17 +110,10 @@ func getRequestGeneratorFunc(
|
||||
bodies []string,
|
||||
localRand *rand.Rand,
|
||||
) RequestGeneratorFunc {
|
||||
bodiesLen := len(bodies)
|
||||
getBody := func() string { return "" }
|
||||
if bodiesLen == 1 {
|
||||
getBody = func() string { return bodies[0] }
|
||||
} else if bodiesLen > 1 {
|
||||
getBody = utils.RandomValueCycle(bodies, localRand)
|
||||
}
|
||||
|
||||
getParams := getKeyValueGeneratorFunc(params, localRand)
|
||||
getHeaders := getKeyValueGeneratorFunc(headers, localRand)
|
||||
getCookies := getKeyValueGeneratorFunc(cookies, localRand)
|
||||
getBody := getValueFunc(bodies, newFuncMap(localRand), localRand)
|
||||
|
||||
return func() *fasthttp.Request {
|
||||
return newFasthttpRequest(
|
||||
@ -199,45 +201,75 @@ func getKeyValueGeneratorFunc[
|
||||
keyValueSlice []types.KeyValue[string, []string],
|
||||
localRand *rand.Rand,
|
||||
) func() T {
|
||||
getKeyValueSlice := []map[string]func() string{}
|
||||
isRandom := false
|
||||
keyValueGenerators := make([]keyValueGenerator, len(keyValueSlice))
|
||||
|
||||
for _, kv := range keyValueSlice {
|
||||
if valuesLen := len(kv.Value); valuesLen > 1 {
|
||||
isRandom = true
|
||||
funcMap := newFuncMap(localRand)
|
||||
|
||||
for i, kv := range keyValueSlice {
|
||||
keyValueGenerators[i] = keyValueGenerator{
|
||||
key: getKeyFunc(kv.Key, funcMap),
|
||||
value: getValueFunc(kv.Value, funcMap, localRand),
|
||||
}
|
||||
|
||||
getKeyValueSlice = append(
|
||||
getKeyValueSlice,
|
||||
map[string]func() string{
|
||||
kv.Key: utils.RandomValueCycle(kv.Value, localRand),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
if isRandom {
|
||||
return func() T {
|
||||
keyValues := make(T, len(getKeyValueSlice))
|
||||
for i, keyValue := range getKeyValueSlice {
|
||||
for key, value := range keyValue {
|
||||
keyValues[i] = types.KeyValue[string, string]{
|
||||
Key: key,
|
||||
Value: value(),
|
||||
}
|
||||
}
|
||||
}
|
||||
return keyValues
|
||||
}
|
||||
} else {
|
||||
keyValues := make(T, len(getKeyValueSlice))
|
||||
for i, keyValue := range getKeyValueSlice {
|
||||
for key, value := range keyValue {
|
||||
keyValues[i] = types.KeyValue[string, string]{
|
||||
Key: key,
|
||||
Value: value(),
|
||||
}
|
||||
return func() T {
|
||||
keyValues := make(T, len(keyValueGenerators))
|
||||
for i, keyValue := range keyValueGenerators {
|
||||
keyValues[i] = types.KeyValue[string, string]{
|
||||
Key: keyValue.key(),
|
||||
Value: keyValue.value(),
|
||||
}
|
||||
}
|
||||
return func() T { return keyValues }
|
||||
return keyValues
|
||||
}
|
||||
}
|
||||
|
||||
func getKeyFunc(key string, funcMap template.FuncMap) func() string {
|
||||
t, err := template.New("default").Funcs(funcMap).Parse(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return func() string {
|
||||
var buf bytes.Buffer
|
||||
_ = t.Execute(&buf, nil)
|
||||
return buf.String()
|
||||
}
|
||||
}
|
||||
|
||||
func getValueFunc(
|
||||
values []string,
|
||||
funcMap template.FuncMap,
|
||||
localRand *rand.Rand,
|
||||
) func() string {
|
||||
templates := make([]*template.Template, len(values))
|
||||
|
||||
for i, value := range values {
|
||||
t, err := template.New("default").Funcs(funcMap).Parse(value)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
templates[i] = t
|
||||
}
|
||||
|
||||
randomTemplateFunc := utils.RandomValueCycle(templates, localRand)
|
||||
|
||||
return func() string {
|
||||
if tmpl := randomTemplateFunc(); tmpl == nil {
|
||||
return ""
|
||||
} else {
|
||||
var buf bytes.Buffer
|
||||
_ = tmpl.Execute(&buf, nil)
|
||||
return buf.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func newFuncMap(localRand *rand.Rand) template.FuncMap {
|
||||
localFaker := gofakeit.NewFaker(localRand, false)
|
||||
|
||||
return template.FuncMap{
|
||||
"upper": strings.ToUpper,
|
||||
"fakeit_Name": localFaker.Name,
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ func releaseDodos(
|
||||
|
||||
wg.Add(int(dodosCount))
|
||||
streamWG.Add(1)
|
||||
streamCtx, streamCtxCancel := context.WithCancel(context.Background())
|
||||
streamCtx, streamCtxCancel := context.WithCancel(ctx)
|
||||
|
||||
go streamProgress(streamCtx, &streamWG, requestConfig.RequestCount, "Dodos Working🔥", increase)
|
||||
|
||||
|
@ -19,19 +19,15 @@ func Flatten[T any](nested [][]*T) []*T {
|
||||
// reset and start cycling through the values in a random order again.
|
||||
// The returned function isn't thread-safe and should be used in a single-threaded context.
|
||||
func RandomValueCycle[T any](values []T, localRand *rand.Rand) func() T {
|
||||
var (
|
||||
valuesLen = len(values)
|
||||
currentIndex = localRand.Intn(valuesLen)
|
||||
stopIndex = currentIndex
|
||||
)
|
||||
|
||||
switch valuesLen {
|
||||
switch valuesLen := len(values); valuesLen {
|
||||
case 0:
|
||||
var zero T
|
||||
return func() T { return zero }
|
||||
case 1:
|
||||
return func() T { return values[0] }
|
||||
default:
|
||||
currentIndex := localRand.Intn(valuesLen)
|
||||
stopIndex := currentIndex
|
||||
return func() T {
|
||||
value := values[currentIndex]
|
||||
currentIndex++
|
||||
|
Loading…
x
Reference in New Issue
Block a user