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
21 1a048c00 2022-11-15 o func Extract(r *tar.Reader, dir string) error {
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
27 1a048c00 2022-11-15 o if err != nil {
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)
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)
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)
51 1a048c00 2022-11-15 o var urls []string = []string{"http://127.0.0.1:8000/test.tar"}
53 1a048c00 2022-11-15 o var archives = make(map[string]time.Time)
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
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)
64 1a048c00 2022-11-15 o func fetchloop(root string, sleep time.Duration) {
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)
72 1a048c00 2022-11-15 o if resp.StatusCode == http.StatusNotModified {
73 1a048c00 2022-11-15 o log.Printf("%s unmodified", url)
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)
82 1a048c00 2022-11-15 o archives[url] = modified
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)
88 1a048c00 2022-11-15 o resp.Body.Close()
90 1a048c00 2022-11-15 o time.Sleep(sleep)
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 {
101 1a048c00 2022-11-15 o if err := os.MkdirAll(cache, 0755); err != nil {
102 1a048c00 2022-11-15 o log.Fatal(err)
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)))))