-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
118 lines (101 loc) · 2.61 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// pollEndpoint is a helper utility that waits for a http endpoint to be reachable and return with http.StatusOK
package main
import (
"context"
"flag"
"io"
"net"
"net/http"
"os"
"time"
logging "github.com/ipfs/go-log"
ma "github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr/net"
)
var (
host = flag.String("host", "/ip4/127.0.0.1/tcp/5001", "the multiaddr host to dial on")
tries = flag.Int("tries", 10, "how many tries to make before failing")
timeout = flag.Duration("tout", time.Second, "how long to wait between attempts")
httpURL = flag.String("http-url", "", "HTTP URL to fetch")
httpOut = flag.Bool("http-out", false, "Print the HTTP response body to stdout")
verbose = flag.Bool("v", false, "verbose logging")
)
var log = logging.Logger("pollEndpoint")
func main() {
flag.Parse()
// extract address from host flag
addr, err := ma.NewMultiaddr(*host)
if err != nil {
log.Fatal("NewMultiaddr() failed: ", err)
}
if *verbose { // lower log level
logging.SetDebugLogging()
}
// show what we got
start := time.Now()
log.Debugf("starting at %s, tries: %d, timeout: %s, addr: %s", start, *tries, *timeout, addr)
connTries := *tries
for connTries > 0 {
c, err := manet.Dial(addr)
if err == nil {
log.Debugf("ok - endpoint reachable with %d tries remaining, took %s", *tries, time.Since(start))
c.Close()
break
}
log.Debug("connect failed: ", err)
time.Sleep(*timeout)
connTries--
}
if err != nil {
goto Fail
}
if *httpURL != "" {
dialer := &connDialer{addr: addr}
httpClient := http.Client{Transport: &http.Transport{
DialContext: dialer.DialContext,
}}
reqTries := *tries
for reqTries > 0 {
try := (*tries - reqTries) + 1
log.Debugf("trying HTTP req %d: '%s'", try, *httpURL)
if tryHTTPGet(&httpClient, *httpURL) {
log.Debugf("HTTP req %d to '%s' succeeded", try, *httpURL)
goto Success
}
log.Debugf("HTTP req %d to '%s' failed", try, *httpURL)
time.Sleep(*timeout)
reqTries--
}
goto Fail
}
Success:
os.Exit(0)
Fail:
log.Error("failed")
os.Exit(1)
}
func tryHTTPGet(client *http.Client, url string) bool {
resp, err := client.Get(*httpURL)
if resp != nil && resp.Body != nil {
defer resp.Body.Close()
}
if err != nil {
return false
}
if resp.StatusCode != http.StatusOK {
return false
}
if *httpOut {
_, err := io.Copy(os.Stdout, resp.Body)
if err != nil {
panic(err)
}
}
return true
}
type connDialer struct {
addr ma.Multiaddr
}
func (d connDialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
return (&manet.Dialer{}).DialContext(ctx, d.addr)
}