github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/thirdparty/pollEndpoint/main.go (about)

     1  // pollEndpoint is a helper utility that waits for a http endpoint to be reachable and return with http.StatusOK
     2  package main
     3  
     4  import (
     5  	"flag"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"net/http"
     9  	"net/url"
    10  	"os"
    11  	"time"
    12  
    13  	log "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/Sirupsen/logrus"
    14  	ma "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
    15  	manet "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
    16  )
    17  
    18  var (
    19  	host     = flag.String("host", "/ip4/127.0.0.1/tcp/5001", "the multiaddr host to dial on")
    20  	endpoint = flag.String("ep", "/version", "which http endpoint path to hit")
    21  	tries    = flag.Int("tries", 10, "how many tries to make before failing")
    22  	timeout  = flag.Duration("tout", time.Second, "how long to wait between attempts")
    23  	verbose  = flag.Bool("v", false, "verbose logging")
    24  )
    25  
    26  func main() {
    27  	flag.Parse()
    28  
    29  	// extract address from host flag
    30  	addr, err := ma.NewMultiaddr(*host)
    31  	if err != nil {
    32  		log.WithField("err", err).Fatal("NewMultiaddr() failed")
    33  	}
    34  	p := addr.Protocols()
    35  	if len(p) < 2 {
    36  		log.WithField("addr", addr).Fatal("need two protocols in host flag (/ip/tcp)")
    37  	}
    38  	_, host, err := manet.DialArgs(addr)
    39  	if err != nil {
    40  		log.WithField("err", err).Fatal("manet.DialArgs() failed")
    41  	}
    42  
    43  	if *verbose { // lower log level
    44  		log.SetLevel(log.DebugLevel)
    45  	}
    46  
    47  	// construct url to dial
    48  	var u url.URL
    49  	u.Scheme = "http"
    50  	u.Host = host
    51  	u.Path = *endpoint
    52  
    53  	// show what we got
    54  	start := time.Now()
    55  	log.WithFields(log.Fields{
    56  		"when":    start,
    57  		"tries":   *tries,
    58  		"timeout": *timeout,
    59  		"url":     u.String(),
    60  	}).Debug("starting")
    61  
    62  	for *tries > 0 {
    63  		f := log.Fields{"tries": *tries}
    64  
    65  		err := checkOK(http.Get(u.String()))
    66  		if err == nil {
    67  			f["took"] = time.Since(start)
    68  			log.WithFields(f).Println("status ok - endpoint reachable")
    69  			os.Exit(0)
    70  		}
    71  		f["error"] = err
    72  		log.WithFields(f).Debug("get failed")
    73  		time.Sleep(*timeout)
    74  		*tries--
    75  	}
    76  
    77  	log.Println("failed.")
    78  	os.Exit(1)
    79  }
    80  
    81  func checkOK(resp *http.Response, err error) error {
    82  	if err == nil { // request worked
    83  		defer resp.Body.Close()
    84  		if resp.StatusCode == http.StatusOK {
    85  			return nil
    86  		}
    87  		body, err := ioutil.ReadAll(resp.Body)
    88  		if err != nil {
    89  			fmt.Fprintf(os.Stderr, "pollEndpoint: ioutil.ReadAll() Error: %s", err)
    90  		}
    91  		return fmt.Errorf("Response not OK. %d %s %q", resp.StatusCode, resp.Status, string(body))
    92  	}
    93  	return err
    94  }