Skip to content

Instantly share code, notes, and snippets.

@valyala
Created April 28, 2012 02:18
Show Gist options
  • Save valyala/2515154 to your computer and use it in GitHub Desktop.
Save valyala/2515154 to your computer and use it in GitHub Desktop.
Spew implementation ( https://github.com/varnish/spew ) in golang
package main
import (
"flag"
"fmt"
"io"
"net"
"os"
"os/signal"
"strings"
)
var (
url = flag.String("url", "/", "The URL to ask for")
server = flag.String("server", "localhost", "Target server to connect to")
port = flag.Int("port", 80, "Port number to connect to")
host_header = flag.String("host_header", "localhost", "Host header to use")
conns = flag.Int("conns", 100, "Number of connections to keep open "+
"concurrently")
reqs = flag.Int("reqs", 100, "Number of requests to send through "+
"a connection before reconnecting")
snd_buff = flag.Int("snd_buff", 1048576000, "Send buffer")
rcv_buff = flag.Int("rcv_buff", 1048576000, "Receive buffer")
msg []byte
signal_chan = make(chan os.Signal)
)
func createMessage() []byte {
single_msg := fmt.Sprintf("GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", *url,
*host_header)
msg := strings.Repeat(single_msg, *reqs-1)
msg += fmt.Sprintf("GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n",
*url, *host_header)
return []byte(msg)
}
func dial(tcp_addr *net.TCPAddr) io.ReadWriteCloser {
c, err := net.DialTCP(tcp_addr.Network(), nil, tcp_addr)
if err != nil {
panic(err)
}
c.SetWriteBuffer(*snd_buff)
c.SetReadBuffer(*rcv_buff)
return c
}
func write(c io.Writer, msg_len int) {
bytes_written := 0
for bytes_written < msg_len {
n, err := c.Write(msg[bytes_written:])
if err != nil {
panic(err)
}
bytes_written += n
}
}
func read(c io.ReadCloser, buf []byte) {
bytes_read := 0
for {
n, err := c.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if n == 0 {
break
}
bytes_read += n
}
}
func client(tcp_addr *net.TCPAddr) {
msg_len := len(msg)
buf := make([]byte, 16384)
for {
c := dial(tcp_addr)
write(c, msg_len)
read(c, buf)
c.Close()
}
}
func main() {
flag.Parse()
msg = createMessage()
addr := fmt.Sprintf("%s:%d", *server, *port)
tcp_addr, err := net.ResolveTCPAddr("tcp", addr)
if err != nil {
panic(err)
}
for i := 0; i < *conns; i++ {
go client(tcp_addr)
}
signal.Notify(signal_chan, os.Interrupt)
<-signal_chan
fmt.Printf("Exiting on user request\n")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment