vk-webhook-flooder-mock/handler/app.go

117 lines
3.2 KiB
Go
Raw Permalink Normal View History

2023-01-13 13:28:05 +03:00
package handler
import (
"fmt"
"net/http"
"os"
"strconv"
"strings"
"sync"
"time"
"github.com/gin-gonic/gin"
)
var (
vkToken = os.Getenv("VK_TOKEN")
bodyTemplate = `{"group_id":183208397,"type":"message_new","event_id":"7dff3c1982dfbd9e6011948ab9b5da352d903c94","v":"5.131","object":{"message":{"date":%d,"from_id":%d,"id":%d,"out":0,"attachments":[],"conversation_message_id":%d,"fwd_messages":[],"important":false,"is_hidden":false,"peer_id":199640727,"random_id":0,"text":"Test message #%d"},"client_info":{"button_actions":["text","vkpay","open_app","location","open_link","callback","intent_subscribe","intent_unsubscribe"],"keyboard":true,"inline_keyboard":true,"carousel":true,"lang_id":0}}}`
)
func init() {
}
func FloodHandler(c *gin.Context) {
countStr := c.Query("count")
if countStr == "" {
c.String(http.StatusBadRequest, "Please specify the amount of requests in count query parameter")
return
}
count, err := strconv.Atoi(countStr)
if err != nil || count <= 0 {
c.String(http.StatusBadRequest, "Invalid count parameter value")
return
}
var sb strings.Builder
sb.Grow(100 * count)
for i := 0; i < count; i++ {
now, st, err := performRequest()
if err != nil {
sb.WriteString(fmt.Sprintf("%d: cannot perform request: %s\n", now, err))
continue
}
sb.WriteString(fmt.Sprintf("%d: received a response with code: %d\n", now, st))
}
c.String(http.StatusOK, sb.String())
}
func ConcurrentFloodHandler(c *gin.Context) {
workersStr := c.Query("workers")
if workersStr == "" {
c.String(http.StatusBadRequest, "Please specify the amount of workers in workers query parameter")
return
}
workers, err := strconv.Atoi(workersStr)
if err != nil || workers <= 0 {
c.String(http.StatusBadRequest, "Invalid workers parameter value")
return
}
countStr := c.Query("count")
if countStr == "" {
c.String(http.StatusBadRequest, "Please specify the amount of requests per worker in the count query parameter")
return
}
count, err := strconv.Atoi(countStr)
if err != nil || workers <= 0 {
c.String(http.StatusBadRequest, "Invalid count parameter value")
return
}
var (
wg sync.WaitGroup
sb strings.Builder
sbLock sync.Mutex
)
sb.Grow(100 * count * workers)
wg.Add(workers)
for i := 0; i < workers; i++ {
go func() {
var workerSb strings.Builder
workerSb.Grow(100 * count)
for l := 0; l < count; l++ {
now, st, err := performRequest()
if err != nil {
workerSb.WriteString(fmt.Sprintf("%d: cannot perform request: %s\n", now, err))
continue
}
workerSb.WriteString(fmt.Sprintf("%d: received a response with code: %d\n", now, st))
}
defer sbLock.Unlock()
sbLock.Lock()
sb.WriteString(workerSb.String())
wg.Done()
}()
}
wg.Wait()
c.String(http.StatusOK, sb.String())
}
func performRequest() (int64, int, error) {
now := time.Now().UnixNano()
req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://127.0.0.1:8000/vk/%s", vkToken), strings.NewReader(fmt.Sprintf(bodyTemplate, now, now, now, now, now)))
if err != nil {
return now, 0, err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return now, 0, err
}
resp.Body.Close()
return now, resp.StatusCode, nil
}