Skip to content

Instantly share code, notes, and snippets.

@aryszka
Created January 24, 2020 15:08
Show Gist options
  • Save aryszka/1068130c053af3cb785a649c017d30aa to your computer and use it in GitHub Desktop.
Save aryszka/1068130c053af3cb785a649c017d30aa to your computer and use it in GitHub Desktop.
package main
/*
This tool can be used to make hanging read or write requests.
To test:
skipper -inline-routes '
read: Path("/read") -> randomContent(1000000000) -> <shunt>;
write: Path("/write") -> absorb() -> <shunt>;
' &
go run ./streaming-blocking-client.go read http://localhost:9090/read
^C
go run ./streaming-blocking-client.go write http://localhost:9090/write
^C
*/
import (
"errors"
"io"
"log"
"math/rand"
"net/http"
"os"
)
const (
messageCount = 9
minMessageBytes = 512
maxMessageBytes = 512 * 512
)
var (
errNotEnoughArgs = errors.New("not enough args: <read|write> <url>")
errInvalidCommand = errors.New("invalid command: <read|write> <url>")
)
func check(err error) {
if err != nil {
log.Fatalln(err)
}
}
func args() (cmd string, url string, err error) {
if len(os.Args) < 3 {
err = errNotEnoughArgs
return
}
switch os.Args[1] {
case "read", "write":
cmd = os.Args[1]
default:
err = errInvalidCommand
}
url = os.Args[2]
return
}
func messageBytes() int {
return minMessageBytes + rand.Intn(maxMessageBytes-minMessageBytes)
}
func randomBytes() []byte {
l := messageBytes()
b := make([]byte, l)
for i := 0; i < l; i++ {
b[i] = byte(rand.Intn(256))
}
return b
}
func write(url string) {
reader, writer := io.Pipe()
req, err := http.NewRequest("POST", url, reader)
check(err)
tr := &http.Transport{}
go func() {
_, err = tr.RoundTrip(req)
check(err)
}()
for i := 0; i < messageCount; i++ {
_, err := writer.Write(randomBytes())
check(err)
println("wrote buffer")
}
println("write finished, hanging")
select {}
}
func read(url string) {
req, err := http.NewRequest("GET", url, nil)
check(err)
tr := &http.Transport{}
rsp, err := tr.RoundTrip(req)
check(err)
for i := 0; i < messageCount; i++ {
b := make([]byte, messageBytes())
_, err := rsp.Body.Read(b)
check(err)
println("read buffer")
}
println("read finished, hanging")
select {}
}
func main() {
cmd, url, err := args()
check(err)
switch cmd {
case "write":
write(url)
default:
read(url)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment