]> ruderich.org/simon Gitweb - nsscash/nsscash.git/blob - fetch.go
nsscash: main_test: add special tests
[nsscash/nsscash.git] / fetch.go
1 // Download files via HTTP with support for If-Modified-Since
2
3 // Copyright (C) 2019  Simon Ruderich
4 //
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Affero General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU Affero General Public License for more details.
14 //
15 // You should have received a copy of the GNU Affero General Public License
16 // along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
18 package main
19
20 import (
21         "io/ioutil"
22         "net/http"
23         "time"
24 )
25
26 // Global variable to permit reuse of connections (keep-alive)
27 var client *http.Client
28
29 func init() {
30         client = &http.Client{}
31 }
32
33 func fetchIfModified(url string, lastModified *time.Time) (int, []byte, error) {
34         req, err := http.NewRequest("GET", url, nil)
35         if err != nil {
36                 return 0, nil, err
37         }
38         if !lastModified.IsZero() {
39                 req.Header.Add("If-Modified-Since",
40                         lastModified.Format(http.TimeFormat))
41         }
42
43         resp, err := client.Do(req)
44         if err != nil {
45                 return 0, nil, err
46         }
47         defer resp.Body.Close()
48
49         body, err := ioutil.ReadAll(resp.Body)
50         if err != nil {
51                 return 0, nil, err
52         }
53
54         modified, err := http.ParseTime(resp.Header.Get("Last-Modified"))
55         if err == nil {
56                 *lastModified = modified
57         }
58
59         return resp.StatusCode, body, nil
60 }