func isURL(s string) bool {
	return strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://")
}
isURL returns true if the string appears to be a URL.
package dockerclient
import (
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"path"
	"path/filepath"
	"strings"
)
type CopyInfo struct {
	os.FileInfo
	Path       string
	Decompress bool
	FromDir    bool
}
func CalcCopyInfo(origPath, rootPath string, allowWildcards bool) ([]CopyInfo, error) {
	explicitDir := origPath == "." || origPath == "/" || strings.HasSuffix(origPath, "/.") || strings.HasSuffix(origPath, "/")
	infos, err := calcCopyInfo(origPath, rootPath, allowWildcards, explicitDir)
	if err != nil {
		return nil, err
	}
	return infos, nil
}
func calcCopyInfo(origPath, rootPath string, allowWildcards, explicitDir bool) ([]CopyInfo, error) {
	origPath = trimLeadingPath(origPath)
	if allowWildcards && containsWildcards(origPath) {
		matchPath := filepath.Join(rootPath, origPath)
		var copyInfos []CopyInfo
		if err := filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error {
			if err != nil {
				return err
			}
			if info.Name() == "" {
				return nil
			}
			if match, _ := filepath.Match(matchPath, path); !match {
				return nil
			}
			subInfos, err := calcCopyInfo(trimLeadingPath(strings.TrimPrefix(path, rootPath)), rootPath, false, explicitDir)
			if err != nil {
				return err
			}
			copyInfos = append(copyInfos, subInfos...)
			return nil
		}); err != nil {
			return nil, err
		}
		return copyInfos, nil
	}
	fi, err := os.Stat(filepath.Join(rootPath, origPath))
	if err != nil {
		return nil, err
	}
	if origPath == "." {
		if !fi.IsDir() {
			return []CopyInfo{{FileInfo: fi, Path: origPath, FromDir: false}}, nil
		}
		var copyInfos []CopyInfo
		infos, err := ioutil.ReadDir(rootPath)
		if err != nil {
			return nil, err
		}
		for _, info := range infos {
			copyInfos = append(copyInfos, CopyInfo{FileInfo: info, Path: info.Name(), FromDir: explicitDir})
		}
		return copyInfos, nil
	}
	origPath = trimTrailingDot(origPath)
	return []CopyInfo{{FileInfo: fi, Path: origPath, FromDir: explicitDir}}, nil
}
func DownloadURL(src, dst, tempDir string) ([]CopyInfo, string, error) {
	u, err := url.Parse(src)
	if err != nil {
		return nil, "", err
	}
	base := path.Base(u.Path)
	if base == "." {
		return nil, "", fmt.Errorf("cannot determine filename from url: %s", u)
	}
	resp, err := http.Get(src)
	if err != nil {
		return nil, "", err
	}
	defer resp.Body.Close()
	if resp.StatusCode >= 400 {
		return nil, "", fmt.Errorf("server returned a status code >= 400: %s", resp.Status)
	}
	tmpDir, err := ioutil.TempDir(tempDir, "dockerbuildurl-")
	if err != nil {
		return nil, "", err
	}
	tmpFileName := filepath.Join(tmpDir, base)
	tmpFile, err := os.OpenFile(tmpFileName, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
	if err != nil {
		os.RemoveAll(tmpDir)
		return nil, "", err
	}
	if _, err := io.Copy(tmpFile, resp.Body); err != nil {
		os.RemoveAll(tmpDir)
		return nil, "", err
	}
	if err := tmpFile.Close(); err != nil {
		os.RemoveAll(tmpDir)
		return nil, "", err
	}
	info, err := os.Stat(tmpFileName)
	if err != nil {
		os.RemoveAll(tmpDir)
		return nil, "", err
	}
	return []CopyInfo{{FileInfo: info, Path: base}}, tmpDir, nil
}
func trimLeadingPath(origPath string) string {
	origPath = filepath.FromSlash(origPath)
	if origPath != "" && origPath[0] == os.PathSeparator && len(origPath) > 1 {
		origPath = origPath[1:]
	}
	origPath = strings.TrimPrefix(origPath, "."+string(os.PathSeparator))
	return origPath
}
func trimTrailingSlash(origPath string) string {
	if origPath == "/" {
		return origPath
	}
	return strings.TrimSuffix(origPath, "/")
}
func trimTrailingDot(origPath string) string {
	if strings.HasSuffix(origPath, string(os.PathSeparator)+".") {
		return strings.TrimSuffix(origPath, ".")
	}
	return origPath
}
func containsWildcards(name string) bool {
	for i := 0; i < len(name); i++ {
		ch := name[i]
		if ch == '\\' {
			i++
		} else if ch == '*' || ch == '?' || ch == '[' {
			return true
		}
	}
	return false
}