Skip to content

Commit e475ffb

Browse files
committed
Add ./bin/dummy_server.go
1 parent de28ab1 commit e475ffb

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//usr/bin/env go run $0 $@ ; exit
2+
3+
package main
4+
5+
import (
6+
"flag"
7+
"fmt"
8+
"io/ioutil"
9+
"log"
10+
"math/rand"
11+
"net/http"
12+
"os"
13+
"strconv"
14+
"strings"
15+
"time"
16+
)
17+
18+
func main() {
19+
rand.Seed(time.Now().UnixNano())
20+
21+
flg := flag.NewFlagSet("test", flag.ExitOnError)
22+
23+
port := flg.Int("port", 8080, "Port on which the dummy server listens.")
24+
failureRate := flg.Int("failure-rate", 0, "Probability to return InternalServerError.")
25+
maxDelay := flg.Duration("max-delay", time.Second, "Maximum time delay randomly applied from receiving a request until returning a response.")
26+
27+
flg.Parse(os.Args[1:])
28+
29+
fmt.Print(`--------------------------------------------------------------------------------
30+
# Endpoint
31+
32+
GET /foo.png // Get a gopher image
33+
34+
# Command-line options**
35+
36+
`)
37+
flg.PrintDefaults()
38+
fmt.Println("--------------------------------------------------------------------------------")
39+
40+
contents := func() string {
41+
b, err := ioutil.ReadFile("./downloading/testdata/foo.png")
42+
if err != nil {
43+
panic(err)
44+
}
45+
return string(b)
46+
}()
47+
48+
handler := func(w http.ResponseWriter, req *http.Request) {
49+
if req.Method != "HEAD" {
50+
time.Sleep(time.Duration(rand.Intn(int(*maxDelay))))
51+
}
52+
53+
w.Header().Set("Accept-Ranges", "bytes")
54+
55+
var body string
56+
var statusCode int
57+
if req.Method == "GET" && rand.Intn(100) < *failureRate {
58+
body = "Internal Server Error"
59+
statusCode = http.StatusInternalServerError
60+
} else {
61+
body = func(req *http.Request) string {
62+
rangeHeader := req.Header.Get("Range") // e.g. "bytes=0-99"
63+
if rangeHeader == "" {
64+
return contents
65+
}
66+
c := strings.Split(strings.Split(rangeHeader, "=")[1], "-")
67+
min, _ := strconv.Atoi(c[0])
68+
max, _ := strconv.Atoi(c[1])
69+
return contents[min : max+1]
70+
}(req)
71+
statusCode = http.StatusPartialContent
72+
}
73+
74+
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(body)))
75+
w.WriteHeader(statusCode)
76+
fmt.Fprint(w, body)
77+
78+
log.Printf("%s %s %d %s\n", req.Method, req.RequestURI, statusCode, req.Header.Get("Range"))
79+
}
80+
81+
http.HandleFunc("/foo.png", handler)
82+
83+
if *failureRate > 0 {
84+
log.Printf("Server starting with a failure rate of %d%% on http://localhost:%d\n", *failureRate, *port)
85+
} else {
86+
log.Printf("Server starting on http://localhost:%d\n", *port)
87+
}
88+
89+
err := http.ListenAndServe(fmt.Sprintf(":%d", *port), nil)
90+
if err != nil {
91+
log.Fatal(err)
92+
}
93+
}

0 commit comments

Comments
 (0)