117 lines
3.2 KiB
Go
117 lines
3.2 KiB
Go
|
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
|
||
|
}
|