diff options
| -rw-r--r-- | go.mod | 1 | ||||
| -rw-r--r-- | go.sum | 2 | ||||
| -rw-r--r-- | internal/headerparams.go | 22 | ||||
| -rw-r--r-- | internal/lume/zip.go | 52 |
4 files changed, 76 insertions, 1 deletions
@@ -21,6 +21,7 @@ require ( github.com/acomagu/bufpipe v1.0.4 // indirect github.com/akutz/memconn v0.1.0 // indirect github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 // indirect + github.com/andybalholm/brotli v1.0.6 // indirect github.com/aws/aws-sdk-go-v2 v1.18.0 // indirect github.com/aws/aws-sdk-go-v2/config v1.18.22 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.13.21 // indirect @@ -17,6 +17,8 @@ github.com/akutz/memconn v0.1.0 h1:NawI0TORU4hcOMsMr11g7vwlCdkYeLKXBcxWu2W/P8A= github.com/akutz/memconn v0.1.0/go.mod h1:Jo8rI7m0NieZyLI5e2CDlRdRqRRB4S7Xp77ukDjH+Fw= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= +github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= +github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= 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) +} |
