Blame


1 1a048c00 2022-11-15 o package main
2 1a048c00 2022-11-15 o
3 1a048c00 2022-11-15 o import (
4 1a048c00 2022-11-15 o "archive/tar"
5 1a048c00 2022-11-15 o "errors"
6 1a048c00 2022-11-15 o "fmt"
7 1a048c00 2022-11-15 o "io"
8 1a048c00 2022-11-15 o "io/fs"
9 1a048c00 2022-11-15 o "log"
10 1a048c00 2022-11-15 o "net/http"
11 1a048c00 2022-11-15 o "os"
12 1a048c00 2022-11-15 o "path"
13 1a048c00 2022-11-15 o "time"
14 1a048c00 2022-11-15 o )
15 1a048c00 2022-11-15 o
16 1a048c00 2022-11-15 o func cacheDir() (string, error) {
17 1a048c00 2022-11-15 o d, err := os.UserCacheDir()
18 1a048c00 2022-11-15 o return path.Join(d, "tarweb"), err
19 1a048c00 2022-11-15 o }
20 1a048c00 2022-11-15 o
21 1a048c00 2022-11-15 o func Extract(r *tar.Reader, dir string) error {
22 1a048c00 2022-11-15 o for {
23 1a048c00 2022-11-15 o hdr, err := r.Next()
24 1a048c00 2022-11-15 o if err == io.EOF {
25 1a048c00 2022-11-15 o break // End of archive
26 1a048c00 2022-11-15 o }
27 1a048c00 2022-11-15 o if err != nil {
28 1a048c00 2022-11-15 o return err
29 1a048c00 2022-11-15 o }
30 1a048c00 2022-11-15 o fmt.Println(hdr.Name)
31 1a048c00 2022-11-15 o if hdr.FileInfo().IsDir() {
32 1a048c00 2022-11-15 o err := os.MkdirAll(path.Join(dir, hdr.Name), 0755)
33 1a048c00 2022-11-15 o if err != nil && !errors.Is(err, fs.ErrExist) {
34 1a048c00 2022-11-15 o return fmt.Errorf("extract %s: %w", hdr.Name, err)
35 1a048c00 2022-11-15 o }
36 1a048c00 2022-11-15 o continue
37 1a048c00 2022-11-15 o }
38 1a048c00 2022-11-15 o dst := path.Join(dir, hdr.Name)
39 1a048c00 2022-11-15 o f, err := os.Create(dst)
40 1a048c00 2022-11-15 o if err != nil {
41 1a048c00 2022-11-15 o return fmt.Errorf("extract %s: %v", hdr.Name, err)
42 1a048c00 2022-11-15 o }
43 1a048c00 2022-11-15 o if _, err := io.Copy(f, r); err != nil {
44 1a048c00 2022-11-15 o return fmt.Errorf("extract %s: %v", hdr.Name, err)
45 1a048c00 2022-11-15 o }
46 1a048c00 2022-11-15 o f.Close()
47 1a048c00 2022-11-15 o }
48 1a048c00 2022-11-15 o return nil
49 1a048c00 2022-11-15 o }
50 1a048c00 2022-11-15 o
51 1a048c00 2022-11-15 o var urls []string = []string{"http://127.0.0.1:8000/test.tar"}
52 1a048c00 2022-11-15 o
53 1a048c00 2022-11-15 o var archives = make(map[string]time.Time)
54 1a048c00 2022-11-15 o
55 1a048c00 2022-11-15 o func getIfModified(url string, since time.Time) (*http.Response, error) {
56 1a048c00 2022-11-15 o req, err := http.NewRequest(http.MethodGet, url, nil)
57 1a048c00 2022-11-15 o if err != nil {
58 1a048c00 2022-11-15 o return nil, err
59 1a048c00 2022-11-15 o }
60 1a048c00 2022-11-15 o req.Header.Add("If-Modified-Since", since.UTC().Format(time.RFC1123Z))
61 1a048c00 2022-11-15 o return http.DefaultClient.Do(req)
62 1a048c00 2022-11-15 o }
63 1a048c00 2022-11-15 o
64 1a048c00 2022-11-15 o func fetchloop(root string, sleep time.Duration) {
65 1a048c00 2022-11-15 o for {
66 1a048c00 2022-11-15 o for url, since := range archives {
67 1a048c00 2022-11-15 o resp, err := getIfModified(url, since)
68 1a048c00 2022-11-15 o if err != nil {
69 1a048c00 2022-11-15 o log.Println("get archive:", err)
70 1a048c00 2022-11-15 o continue
71 1a048c00 2022-11-15 o }
72 1a048c00 2022-11-15 o if resp.StatusCode == http.StatusNotModified {
73 1a048c00 2022-11-15 o log.Printf("%s unmodified", url)
74 1a048c00 2022-11-15 o continue
75 1a048c00 2022-11-15 o }
76 1a048c00 2022-11-15 o if resp.Header.Get("Last-Modified") != "" {
77 1a048c00 2022-11-15 o modified, err := time.Parse(time.RFC1123, resp.Header.Get("Last-Modified"))
78 1a048c00 2022-11-15 o if err != nil {
79 1a048c00 2022-11-15 o log.Printf("parse last modified time for %s: %v", url, err)
80 1a048c00 2022-11-15 o continue
81 1a048c00 2022-11-15 o }
82 1a048c00 2022-11-15 o archives[url] = modified
83 1a048c00 2022-11-15 o }
84 1a048c00 2022-11-15 o rd := tar.NewReader(resp.Body)
85 1a048c00 2022-11-15 o if err := Extract(rd, root); err != nil {
86 1a048c00 2022-11-15 o log.Printf("extract %s: %v", url, err)
87 1a048c00 2022-11-15 o }
88 1a048c00 2022-11-15 o resp.Body.Close()
89 1a048c00 2022-11-15 o }
90 1a048c00 2022-11-15 o time.Sleep(sleep)
91 1a048c00 2022-11-15 o }
92 1a048c00 2022-11-15 o }
93 1a048c00 2022-11-15 o
94 1a048c00 2022-11-15 o func main() {
95 1a048c00 2022-11-15 o archives["http://127.0.0.1:8000/test.tar"] = time.Time{}
96 1a048c00 2022-11-15 o archives["http://127.0.0.1:8000/meerkat.tar"] = time.Time{}
97 1a048c00 2022-11-15 o cache, err := cacheDir()
98 1a048c00 2022-11-15 o if err != nil {
99 1a048c00 2022-11-15 o log.Fatal(err)
100 1a048c00 2022-11-15 o }
101 1a048c00 2022-11-15 o if err := os.MkdirAll(cache, 0755); err != nil {
102 1a048c00 2022-11-15 o log.Fatal(err)
103 1a048c00 2022-11-15 o }
104 1a048c00 2022-11-15 o log.Println("serving archives from", cache)
105 1a048c00 2022-11-15 o go fetchloop(cache, 20*time.Second)
106 1a048c00 2022-11-15 o log.Fatal(http.ListenAndServe(":6969", http.FileServer(http.FS(os.DirFS(cache)))))
107 1a048c00 2022-11-15 o }