[mirror] Scalable static site server for Git forges (like GitHub Pages)
at main 112 lines 2.0 kB view raw
1package main 2 3import ( 4 "archive/tar" 5 "bytes" 6 "flag" 7 "fmt" 8 "io" 9 "net/http" 10 "sync" 11 "time" 12) 13 14func makeInit() []byte { 15 writer := bytes.NewBuffer(nil) 16 archive := tar.NewWriter(writer) 17 archive.WriteHeader(&tar.Header{ 18 Typeflag: tar.TypeReg, 19 Name: "index.html", 20 }) 21 archive.Write([]byte{}) 22 archive.Flush() 23 return writer.Bytes() 24} 25 26func initSite() { 27 req, err := http.NewRequest(http.MethodPut, "http://localhost:3000", 28 bytes.NewReader(makeInit())) 29 if err != nil { 30 panic(err) 31 } 32 33 req.Header.Add("Content-Type", "application/x-tar") 34 resp, err := http.DefaultClient.Do(req) 35 if err != nil { 36 panic(err) 37 } 38 defer resp.Body.Close() 39} 40 41func makePatch(n int) []byte { 42 writer := bytes.NewBuffer(nil) 43 archive := tar.NewWriter(writer) 44 archive.WriteHeader(&tar.Header{ 45 Typeflag: tar.TypeReg, 46 Name: fmt.Sprintf("%d.txt", n), 47 }) 48 archive.Write([]byte{}) 49 archive.Flush() 50 return writer.Bytes() 51} 52 53func patchRequest(n int) int { 54 req, err := http.NewRequest(http.MethodPatch, "http://localhost:3000", 55 bytes.NewReader(makePatch(n))) 56 if err != nil { 57 panic(err) 58 } 59 60 req.Header.Add("Atomic", "no") 61 req.Header.Add("Content-Type", "application/x-tar") 62 resp, err := http.DefaultClient.Do(req) 63 if err != nil { 64 panic(err) 65 } 66 defer resp.Body.Close() 67 68 data, err := io.ReadAll(resp.Body) 69 if err != nil { 70 panic(err) 71 } 72 73 fmt.Printf("%d: %s %q\n", n, resp.Status, string(data)) 74 return resp.StatusCode 75} 76 77func concurrentWriter(wg *sync.WaitGroup, n int) { 78 for { 79 if patchRequest(n) == 200 { 80 break 81 } 82 } 83 wg.Done() 84} 85 86var count = flag.Int("count", 10, "request count") 87 88func main() { 89 flag.Parse() 90 91 initSite() 92 time.Sleep(time.Second) 93 94 wg := &sync.WaitGroup{} 95 for n := range *count { 96 wg.Add(1) 97 go concurrentWriter(wg, n) 98 } 99 wg.Wait() 100 101 success := 0 102 for n := range *count { 103 resp, err := http.Get(fmt.Sprintf("http://localhost:3000/%d.txt", n)) 104 if err != nil { 105 panic(err) 106 } 107 if resp.StatusCode == 200 { 108 success++ 109 } 110 } 111 fmt.Printf("written: %d of %d\n", success, *count) 112}