diff options
| author | Xe Iaso <me@xeiaso.net> | 2023-10-27 10:28:05 -0400 |
|---|---|---|
| committer | Xe Iaso <me@xeiaso.net> | 2023-10-27 10:28:12 -0400 |
| commit | 88ce81cc191cda29c1f7f0d9cf1f16a0873f6fe1 (patch) | |
| tree | 6aa94e0e20820ef7965a46396ba4c9e326130926 /internal | |
| parent | 930708194b6f1aff52c30f336f70db4b33d38f83 (diff) | |
| download | xesite-88ce81cc191cda29c1f7f0d9cf1f16a0873f6fe1.tar.xz xesite-88ce81cc191cda29c1f7f0d9cf1f16a0873f6fe1.zip | |
internal/lume: start work on dynamically replacing the zip filesystem for XeDN serving
Signed-off-by: Xe Iaso <me@xeiaso.net>
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/headerparams.go | 22 | ||||
| -rw-r--r-- | internal/lume/zip.go | 52 |
2 files changed, 73 insertions, 1 deletions
diff --git a/internal/headerparams.go b/internal/headerparams.go new file mode 100644 index 0000000..ff4e78b --- /dev/null +++ b/internal/headerparams.go @@ -0,0 +1,22 @@ +package internal + +import ( + "strings" +) + +func ParseValueAndParams(value string) map[string]string { + parts := strings.Split(value, ",") + vals := make(map[string]string) + + for _, part := range parts { + part = strings.TrimSpace(part) + if part == "" { + continue + } + + parts := strings.Split(part, ";") + vals[parts[0]] = strings.Join(parts[1:], ";") + } + + return vals +} diff --git a/internal/lume/zip.go b/internal/lume/zip.go index cecfb38..90513fc 100644 --- a/internal/lume/zip.go +++ b/internal/lume/zip.go @@ -10,9 +10,14 @@ import ( "os" "path/filepath" "strings" + "sync" + + "xeiaso.net/v4/internal" ) -const compressionGZIP = 0x69 +const ( + compressionGZIP = 0x69 +) func init() { zip.RegisterCompressor(compressionGZIP, func(w io.Writer) (io.WriteCloser, error) { @@ -163,3 +168,48 @@ func isCompressible(fname string) (bool, error) { // The file is compressible by both its header and name return true, nil } + +type ZipServer struct { + lock sync.RWMutex + zip *zip.ReadCloser +} + +func NewZipServer(zipPath string) (*ZipServer, error) { + file, err := zip.OpenReader(zipPath) + if err != nil { + return nil, err + } + + result := &ZipServer{ + zip: file, + } + + return result, nil +} + +func (zs *ZipServer) Update(fname string) error { + zs.lock.Lock() + defer zs.lock.Unlock() + + old := zs.zip + + file, err := zip.OpenReader(fname) + if err != nil { + return err + } + + zs.zip = file + + old.Close() + return nil +} + +func (zs *ZipServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { + zs.lock.RLock() + defer zs.lock.RUnlock() + + vals := internal.ParseValueAndParams(r.Header.Get("Accept-Encoding")) + slog.Info("accept-encoding", "vals", vals) + + http.FileServer(http.FS(zs.zip)).ServeHTTP(w, r) +} |
