From: Sergey Matveev Date: Sun, 7 Apr 2024 09:43:33 +0000 (+0300) Subject: Ability to download URLs X-Git-Tag: v0.9.0^0 X-Git-Url: http://www.git.stargrave.org/?p=meta4ra.git;a=commitdiff_plain Ability to download URLs --- diff --git a/README b/README index 8f71194..0f8a2f0 100644 --- a/README +++ b/README @@ -5,7 +5,7 @@ meta4ra-create utility is used to create Metalink4 .meta4-file for single specified file. meta4ra-check utility is used to check .meta4 file, extract signatures -and verify corresponding files integrity. +and verify corresponding files integrity. Optionally download files. meta4ra-hash utility can be used to hash the data with a single hash algorithm. It could be useful if you want to use the best found diff --git a/cmd/meta4ra/check.go b/cmd/meta4ra/check.go index 3b3e0a9..95511c0 100644 --- a/cmd/meta4ra/check.go +++ b/cmd/meta4ra/check.go @@ -23,6 +23,7 @@ import ( "io" "io/fs" "log" + "net/http" "os" "path" "strings" @@ -37,6 +38,7 @@ func runCheck() { "hash-name:commandline[,...]") extractSig := flag.Bool("extract-sig", false, "Extract signature files") metaPath := flag.String("meta4", "file.meta4", "Metalink file") + dl := flag.Int("dl", -1, "URL index to download, instead of reading from stdin") flag.Usage = func() { fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [options] [FILE ...]\n", os.Args[0]) @@ -46,6 +48,10 @@ If no FILEs are specified, then all s from metalink are searched and verified if they exist. Otherwise only specified FILEs are checked. If you want to skip any verification (for example only to validate the format and -extract-sig, then you can just specify an empty ("") FILE. + +If -dl (> 0) is specified, then it automatically implies -pipe, but +downloads data by specified URLs index, instead of reading from stdin. +That can be used as a downloading utility. `) } flag.Parse() @@ -73,6 +79,9 @@ and -extract-sig, then you can just specify an empty ("") FILE. for _, fn := range flag.Args() { toCheck[path.Base(fn)] = fn } + if *dl != -1 { + *pipe = true + } if *pipe && len(toCheck) != 1 { log.Fatalln("exactly single FILE must be specified when using -pipe") } @@ -155,19 +164,38 @@ and -extract-sig, then you can just specify an empty ("") FILE. continue HashFound: - fd := os.Stdin + var src io.ReadCloser + src = os.Stdin if !*pipe { - fd, err = os.Open(fullPath) + src, err = os.Open(fullPath) if err != nil { log.Println("Error:", f.Name, err) bad = true continue } } + if *dl != -1 { + resp, err := http.Get(f.URLs[*dl].URL) + if err != nil { + log.Println("Error:", f.Name, err) + bad = true + continue + } + log.Println("HTTP response:") + for k := range resp.Header { + log.Println("\t"+k+":", resp.Header.Get(k)) + } + if resp.StatusCode != http.StatusOK { + log.Println("Bad status code:", f.Name, resp.Status) + bad = true + continue + } + src = resp.Body + } err = hasher.Start() if err != nil { if !*pipe { - fd.Close() + src.Close() } hasher.Stop() log.Println("Error:", f.Name, err) @@ -180,9 +208,9 @@ and -extract-sig, then you can just specify an empty ("") FILE. } else { w = hasher } - _, err = io.Copy(w, bufio.NewReaderSize(fd, meta4ra.BufLen)) - if !*pipe { - fd.Close() + _, err = io.Copy(w, bufio.NewReaderSize(src, meta4ra.BufLen)) + if !*pipe || *dl != -1 { + src.Close() } if err != nil { hasher.Stop() diff --git a/internal/common.go b/internal/common.go index cc62ce7..5f52548 100644 --- a/internal/common.go +++ b/internal/common.go @@ -21,7 +21,7 @@ import ( ) const ( - Generator = "meta4ra/0.8.0" + Generator = "meta4ra/0.9.0" SigMediaTypePGP = "application/pgp-signature" SigMediaTypeSSH = "application/ssh-signature" BufLen = 1 << 20