Created
June 28, 2024 15:33
-
-
Save dyipon/49767a7b41adf328053e59d1d6854752 to your computer and use it in GitHub Desktop.
golang http stress test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# go run main.go https://index.hu/test 1 100 10.0.5.1-10.0.5.200 | |
package main | |
import ( | |
"fmt" | |
"io/ioutil" | |
"math/rand" | |
"net" | |
"net/http" | |
"os" | |
"strconv" | |
"strings" | |
"sync" | |
"time" | |
) | |
func main() { | |
if len(os.Args) < 5 { | |
fmt.Println("Usage: go run main.go <url> <num_threads> <num_requests> <ip1> <ip2> ... <ipN>") | |
return | |
} | |
targetURL := os.Args[1] | |
numThreads, err := strconv.Atoi(os.Args[2]) | |
if err != nil { | |
fmt.Println("Invalid number of threads:", os.Args[2]) | |
return | |
} | |
numRequests, err := strconv.Atoi(os.Args[3]) | |
if err != nil { | |
fmt.Println("Invalid number of requests:", os.Args[3]) | |
return | |
} | |
ipRanges := os.Args[4:] | |
if len(ipRanges) == 0 { | |
fmt.Println("Please provide at least one IP address or range.") | |
return | |
} | |
var ipAddresses []string | |
for _, ipRange := range ipRanges { | |
if strings.Contains(ipRange, "-") { | |
expandedIPs, err := expandIPRange(ipRange) | |
if err != nil { | |
fmt.Println("Error expanding IP range:", err) | |
return | |
} | |
ipAddresses = append(ipAddresses, expandedIPs...) | |
} else { | |
ipAddresses = append(ipAddresses, ipRange) | |
} | |
} | |
rand.Seed(time.Now().UnixNano()) | |
var wg sync.WaitGroup | |
requestsPerThread := numRequests / numThreads | |
for i := 0; i < numThreads; i++ { | |
wg.Add(1) | |
go func() { | |
defer wg.Done() | |
for j := 0; j < requestsPerThread; j++ { | |
randomIP := ipAddresses[rand.Intn(len(ipAddresses))] | |
responseSize, err := fetchURLWithIP(targetURL, randomIP) | |
if err != nil { | |
fmt.Println("Error fetching URL:", err) | |
return | |
} | |
fmt.Printf("Response from %s: %d bytes\n", randomIP, responseSize) | |
} | |
}() | |
} | |
// Handle any remaining requests | |
remainingRequests := numRequests % numThreads | |
for i := 0; i < remainingRequests; i++ { | |
wg.Add(1) | |
go func() { | |
defer wg.Done() | |
randomIP := ipAddresses[rand.Intn(len(ipAddresses))] | |
responseSize, err := fetchURLWithIP(targetURL, randomIP) | |
if err != nil { | |
fmt.Println("Error fetching URL:", err) | |
return | |
} | |
fmt.Printf("Response from %s: %d bytes\n", randomIP, responseSize) | |
}() | |
} | |
wg.Wait() | |
} | |
func fetchURLWithIP(targetURL string, ip string) (int, error) { | |
dialer := &net.Dialer{ | |
LocalAddr: &net.TCPAddr{IP: net.ParseIP(ip)}, | |
} | |
transport := &http.Transport{ | |
DialContext: dialer.DialContext, | |
} | |
client := &http.Client{ | |
Transport: transport, | |
} | |
req, err := http.NewRequest("GET", targetURL, nil) | |
if err != nil { | |
return 0, err | |
} | |
resp, err := client.Do(req) | |
if err != nil { | |
return 0, err | |
} | |
defer resp.Body.Close() | |
body, err := ioutil.ReadAll(resp.Body) | |
if err != nil { | |
return 0, err | |
} | |
return len(body), nil | |
} | |
func expandIPRange(ipRange string) ([]string, error) { | |
parts := strings.Split(ipRange, "-") | |
if len(parts) != 2 { | |
return nil, fmt.Errorf("invalid IP range format: %s", ipRange) | |
} | |
startIP := net.ParseIP(parts[0]) | |
endIP := net.ParseIP(parts[1]) | |
if startIP == nil || endIP == nil { | |
return nil, fmt.Errorf("invalid IP address in range: %s", ipRange) | |
} | |
var ips []string | |
for ip := startIP; !ip.Equal(endIP); ip = incrementIP(ip) { | |
ips = append(ips, ip.String()) | |
} | |
ips = append(ips, endIP.String()) // include the end IP in the range | |
return ips, nil | |
} | |
func incrementIP(ip net.IP) net.IP { | |
ip = ip.To4() | |
for i := len(ip) - 1; i >= 0; i-- { | |
ip[i]++ | |
if ip[i] > 0 { | |
break | |
} | |
} | |
return ip | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment