about summary refs log tree commit diff stats
path: root/internal/importer/http.go
diff options
context:
space:
mode:
authorAlan Pearce2024-05-09 16:47:41 +0200
committerAlan Pearce2024-05-09 19:27:55 +0200
commite062ca72b222b890e345548bd8422d5df98e9fef (patch)
tree89f52ebfdb1fb8069e6323d9dde42f5491dad5d1 /internal/importer/http.go
parent967f6fdf5c1693d3aa27079b3ae28768fb7356c6 (diff)
downloadsearchix-e062ca72b222b890e345548bd8422d5df98e9fef.tar.lz
searchix-e062ca72b222b890e345548bd8422d5df98e9fef.tar.zst
searchix-e062ca72b222b890e345548bd8422d5df98e9fef.zip
feat: import sources from configuration in go code and index options
Diffstat (limited to 'internal/importer/http.go')
-rw-r--r--internal/importer/http.go63
1 files changed, 63 insertions, 0 deletions
diff --git a/internal/importer/http.go b/internal/importer/http.go
new file mode 100644
index 0000000..1bf2428
--- /dev/null
+++ b/internal/importer/http.go
@@ -0,0 +1,63 @@
+package importer
+
+import (
+	"context"
+	"fmt"
+	"log/slog"
+	"net/http"
+	"os"
+	"searchix/internal/file"
+	"strings"
+	"time"
+
+	"github.com/pkg/errors"
+)
+
+func fetchFileIfNeeded(ctx context.Context, path string, url string) (needed bool, err error) {
+	stat, err := file.StatIfExists(path)
+	if err != nil {
+		return false, errors.WithMessagef(err, "could not stat file %s", path)
+	}
+
+	var mtime string
+	if stat != nil {
+		mtime = strings.Replace(stat.ModTime().UTC().Format(time.RFC1123), "UTC", "GMT", 1)
+	}
+
+	req, err := http.NewRequestWithContext(ctx, "GET", url, http.NoBody)
+	if err != nil {
+		return false, errors.WithMessagef(err, "could not create HTTP request for %s", url)
+	}
+
+	if mtime != "" {
+		req.Header.Set("If-Modified-Since", mtime)
+	}
+	res, err := http.DefaultClient.Do(req)
+	if err != nil {
+		return false, errors.WithMessagef(err, "could not make HTTP request to %s", url)
+	}
+	defer res.Body.Close()
+
+	switch res.StatusCode {
+	case http.StatusNotModified:
+		needed = false
+	case http.StatusOK:
+		newMtime, err := time.Parse(time.RFC1123, res.Header.Get("Last-Modified"))
+		if err != nil {
+			slog.Warn("could not parse Last-Modified header from response", "value", res.Header.Get("Last-Modified"))
+		}
+		err = file.WriteToFile(path, res.Body)
+		if err != nil {
+			return false, errors.WithMessagef(err, "could not write response body to file %s", path)
+		}
+		err = os.Chtimes(path, time.Time{}, newMtime)
+		if err != nil {
+			slog.Warn("could not update mtime on file", "file", path)
+		}
+		needed = true
+	default:
+		return false, fmt.Errorf("got response code %d, don't know what to do", res.StatusCode)
+	}
+
+	return needed, nil
+}