Check executes a HTTP healthcheck.
(timeout time.Duration)
| 84 | |
| 85 | // Check executes a HTTP healthcheck. |
| 86 | func (hc *HTTPChecker) Check(timeout time.Duration) *Result { |
| 87 | msg := fmt.Sprintf("HTTP %s to %s", hc.Method, hc.addr()) |
| 88 | start := time.Now() |
| 89 | if timeout == time.Duration(0) { |
| 90 | timeout = defaultHTTPTimeout |
| 91 | } |
| 92 | |
| 93 | u, err := url.Parse(hc.Request) |
| 94 | if err != nil { |
| 95 | return complete(start, "", false, err) |
| 96 | } |
| 97 | if hc.Secure { |
| 98 | u.Scheme = "https" |
| 99 | } else { |
| 100 | u.Scheme = "http" |
| 101 | } |
| 102 | if u.Host == "" { |
| 103 | u.Host = hc.addr() |
| 104 | } |
| 105 | |
| 106 | proxy := (func(*http.Request) (*url.URL, error))(nil) |
| 107 | if hc.Proxy { |
| 108 | proxy = http.ProxyURL(u) |
| 109 | } |
| 110 | |
| 111 | var dialer func(network, addr string) (net.Conn, error) |
| 112 | |
| 113 | // Both DSR and TUN mode requires socket marks |
| 114 | if hc.Mode != seesaw.HCModePlain { |
| 115 | conn, err := dialTCP(hc.network(), hc.addr(), timeout, hc.Mark) |
| 116 | if err != nil { |
| 117 | return complete(start, "", false, err) |
| 118 | } |
| 119 | defer conn.Close() |
| 120 | |
| 121 | dialer = func(net string, addr string) (net.Conn, error) { |
| 122 | return conn, nil |
| 123 | } |
| 124 | } |
| 125 | tlsConfig := &tls.Config{ |
| 126 | InsecureSkipVerify: !hc.TLSVerify, |
| 127 | } |
| 128 | client := &http.Client{ |
| 129 | CheckRedirect: func(req *http.Request, via []*http.Request) error { |
| 130 | return errors.New("redirect not permitted") |
| 131 | }, |
| 132 | Transport: &http.Transport{ |
| 133 | Dial: dialer, |
| 134 | Proxy: proxy, |
| 135 | TLSClientConfig: tlsConfig, |
| 136 | }, |
| 137 | Timeout: timeout, |
| 138 | } |
| 139 | req, err := http.NewRequest(hc.Method, hc.Request, nil) |
| 140 | req.URL = u |
| 141 | |
| 142 | // If we received a response we want to process it, even in the |
| 143 | // presence of an error - a redirect 3xx will result in both the |