mirror of
https://gitea.intern.drachenfels.de/ruben/goget.git
synced 2026-02-08 12:48:01 +00:00
Initial implementation.
This commit is contained in:
12
Makefile
Normal file
12
Makefile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
BUILD_HASH := $(shell git describe --always --tags --long)
|
||||||
|
LDFLAGS := "-X main.version=${BUILD_HASH} -s -w"
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
|
install:
|
||||||
|
go fmt ./...
|
||||||
|
go install -ldflags ${LDFLAGS} ./...
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
build:
|
||||||
|
go fmt ./...
|
||||||
|
go build -ldflags ${LDFLAGS} ./...
|
||||||
118
goget.go
Normal file
118
goget.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var version string
|
||||||
|
|
||||||
|
type client struct {
|
||||||
|
User string
|
||||||
|
Password string
|
||||||
|
Insecure bool // disable certificate check
|
||||||
|
ConnectTimeout time.Duration
|
||||||
|
ReadTimeout time.Duration
|
||||||
|
Retries int
|
||||||
|
RetryWait time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c := client{}
|
||||||
|
var filename string
|
||||||
|
var showVersion bool
|
||||||
|
|
||||||
|
flag.StringVar(&c.User, "http-user", "", "HTTP auth username")
|
||||||
|
flag.StringVar(&c.Password, "http-password", "", "HTTP auth password")
|
||||||
|
flag.IntVar(&c.Retries, "retries", 1, "Number of retries in case of download errors.")
|
||||||
|
flag.DurationVar(&c.RetryWait, "retry-wait", 2*time.Second, "Time to wait before retrying download.")
|
||||||
|
flag.DurationVar(&c.ConnectTimeout, "connect-timeout", 5*time.Second, "TCP connections that take longer to establish will be aborted")
|
||||||
|
flag.DurationVar(&c.ReadTimeout, "read-timeout", 10*time.Second, "TCP connections that that are longer idle will be aborted")
|
||||||
|
flag.BoolVar(&c.Insecure, "insecure", false, "Disable TLS certificate verification.")
|
||||||
|
flag.BoolVar(&showVersion, "version", false, "Show version and exit.")
|
||||||
|
|
||||||
|
flag.StringVar(&filename, "filename", "", "Filename / path where to write downloaded file to. Defaults to filename of the URL.")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if showVersion {
|
||||||
|
println("version:", version)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadURI := flag.Args()[0]
|
||||||
|
|
||||||
|
if filename == "" {
|
||||||
|
uri, err := url.Parse(downloadURI)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
filename = path.Base(uri.Path)
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
for i := 0; i < c.Retries; i++ {
|
||||||
|
err = c.DownloadFile(filename, downloadURI)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
println(err.Error())
|
||||||
|
if c.RetryWait > 0 {
|
||||||
|
time.Sleep(c.RetryWait)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) DownloadFile(filename string, url string) (err error) {
|
||||||
|
println("Downloading %s to file %s\n", url, filename)
|
||||||
|
// Create the target file
|
||||||
|
out, err := os.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer out.Close()
|
||||||
|
|
||||||
|
tr := &http.Transport{
|
||||||
|
MaxIdleConns: 10,
|
||||||
|
IdleConnTimeout: c.ReadTimeout,
|
||||||
|
DisableCompression: true,
|
||||||
|
DialContext: (&net.Dialer{
|
||||||
|
Timeout: c.ConnectTimeout, // connect timeout
|
||||||
|
}).DialContext,
|
||||||
|
// TLSHandshakeTimeout: 5 * time.Second,
|
||||||
|
TLSClientConfig: &tls.Config{
|
||||||
|
InsecureSkipVerify: c.Insecure,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &http.Client{Transport: tr}
|
||||||
|
|
||||||
|
// Get the data
|
||||||
|
resp, err := client.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
// Check server response
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return fmt.Errorf("bad status: %s", resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writer the body to file
|
||||||
|
_, err = io.Copy(out, resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user