]> ruderich.org/simon Gitweb - nsscash/nsscash.git/blobdiff - fetch.go
.github: update upstream actions to latest version
[nsscash/nsscash.git] / fetch.go
index 9834f3ead8d5beddc74134e722bd60797869f394..2c785a264f51685533a78e0f02544bc8794beed9 100644 (file)
--- a/fetch.go
+++ b/fetch.go
@@ -1,6 +1,6 @@
 // Download files via HTTP with support for If-Modified-Since
 
-// Copyright (C) 2019  Simon Ruderich
+// Copyright (C) 2019-2021  Simon Ruderich
 //
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU Affero General Public License as published by
 package main
 
 import (
+       "crypto/tls"
+       "crypto/x509"
+       "fmt"
        "io/ioutil"
        "net/http"
        "time"
+
+       "github.com/pkg/errors"
 )
 
 // Global variable to permit reuse of connections (keep-alive)
-var client *http.Client
+var clients map[string]*http.Client
 
 func init() {
-       client = &http.Client{}
+       clients = make(map[string]*http.Client)
+       clients[""] = &http.Client{}
 }
 
-func fetchIfModified(url string, lastModified *time.Time) (int, []byte, error) {
+func fetchIfModified(url, user, pass, ca string, lastModified *time.Time) (int, []byte, error) {
        req, err := http.NewRequest("GET", url, nil)
        if err != nil {
                return 0, nil, err
        }
+       if user != "" || pass != "" {
+               req.SetBasicAuth(user, pass)
+       }
        if !lastModified.IsZero() {
                req.Header.Add("If-Modified-Since",
-                       lastModified.Format(http.TimeFormat))
+                       lastModified.UTC().Format(http.TimeFormat))
+       }
+
+       client, ok := clients[ca]
+       if !ok {
+               pem, err := ioutil.ReadFile(ca)
+               if err != nil {
+                       return 0, nil, errors.Wrapf(err, "file.ca %q", ca)
+               }
+               pool := x509.NewCertPool()
+               ok := pool.AppendCertsFromPEM(pem)
+               if !ok {
+                       return 0, nil, fmt.Errorf(
+                               "file.ca %q: no PEM cert found", ca)
+               }
+
+               client = &http.Client{
+                       Transport: &http.Transport{
+                               TLSClientConfig: &tls.Config{
+                                       RootCAs: pool,
+                               },
+                       },
+               }
+               clients[ca] = client
        }
 
        resp, err := client.Do(req)