diff --git a/README.md b/README.md index 06b9c99..f0d01d0 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ High-level overview: ```hosts echo '127.0.0.1 docker.local' | sudo tee -a /etc/hosts + echo '::1 docker.local' | sudo tee -a /etc/hosts ``` - Flush local DNS cache: diff --git a/netutil/netutil.go b/netutil/netutil.go index 6cda177..034ff87 100644 --- a/netutil/netutil.go +++ b/netutil/netutil.go @@ -3,10 +3,40 @@ package netutil import ( "errors" "net" + "net/http" "regexp" "strconv" + "time" ) +// Default http client with timeout +// https://golang.org/pkg/net/http/#pkg-examples +// Clients and Transports are safe for concurrent use by multiple goroutines. +var defaultClient = &http.Client{ + Timeout: time.Second * 10, + Transport: defaultTransport, +} + +// https://golang.org/src/net/http/transport.go +var defaultTransport = &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: 10 * time.Second, + KeepAlive: 10 * time.Second, + DualStack: true, + }).DialContext, + ForceAttemptHTTP2: true, + MaxIdleConns: 10, + IdleConnTimeout: 10 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, +} + +// Get issues a GET to the specified URL - a drop-in replacement for http.Get with timeouts. +func Get(url string) (resp *http.Response, err error) { + return defaultClient.Get(url) +} + // GetFreePort asks the kernel for a free open port that is ready to use. func GetFreePort() (int, error) { ip, err := LocalIP() diff --git a/regutil/regutil.go b/regutil/regutil.go index 36d72b8..8524515 100644 --- a/regutil/regutil.go +++ b/regutil/regutil.go @@ -8,6 +8,8 @@ import ( "regexp" "strings" + "github.com/miguelmota/ipdr/netutil" + cid "github.com/ipfs/go-cid" base58 "github.com/jbenet/go-base58" mbase "github.com/multiformats/go-multibase" @@ -86,7 +88,7 @@ func ToB32(s string) string { func Dig(gw string, short bool, name string) (string, error) { uri := fmt.Sprintf("http://%s/dig?q=%s&short=%v", gw, name, short) - resp, err := http.Get(uri) + resp, err := netutil.Get(uri) if err != nil { return "", err } diff --git a/server/registry/blobs.go b/server/registry/blobs.go index 18ba00c..3c039be 100644 --- a/server/registry/blobs.go +++ b/server/registry/blobs.go @@ -26,6 +26,8 @@ import ( "path" "strings" "sync" + + "github.com/miguelmota/ipdr/netutil" ) // Returns whether this url should be handled by the blob handler @@ -148,7 +150,7 @@ func (b *blobs) handle(resp http.ResponseWriter, req *http.Request) *regError { } } uri := b.registry.ipfsURL([]string{cid, "blobs", target}) - ipfsResp, err := http.Get(uri) + ipfsResp, err := netutil.Get(uri) if err != nil { return ®Error{ Status: http.StatusNotFound, diff --git a/server/registry/cids.go b/server/registry/cids.go index d08a6d7..dc0c51e 100644 --- a/server/registry/cids.go +++ b/server/registry/cids.go @@ -18,9 +18,6 @@ type cidStore struct { } func key(repo, ref string) string { - if ref == "" { - ref = "latest" - } return repo + ":" + ref } diff --git a/server/registry/registry.go b/server/registry/registry.go index edd8905..ade701f 100644 --- a/server/registry/registry.go +++ b/server/registry/registry.go @@ -176,6 +176,8 @@ func (r *registry) resolveCID(repo, reference string) (string, error) { } func (r *registry) resolve(repo, reference string) []string { + r.log.Printf("resolving CID: %s:%s", repo, reference) + // local/cached if cid, ok := r.cids.Get(repo, reference); ok { return []string{cid} diff --git a/server/registry/util.go b/server/registry/util.go index bf6a667..2e08a65 100644 --- a/server/registry/util.go +++ b/server/registry/util.go @@ -5,12 +5,13 @@ import ( "io/ioutil" "net/http" + "github.com/miguelmota/ipdr/netutil" "github.com/miguelmota/ipdr/regutil" ) func getContent(gw string, cid string, s []string) ([]byte, error) { uri := regutil.IpfsURL(gw, append([]string{cid}, s...)) - resp, err := http.Get(uri) + resp, err := netutil.Get(uri) if err != nil { return nil, err }