wrapfs

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 29, 2024 License: MIT Imports: 4 Imported by: 1

README

WrapFS

wrapfs is a Go module which provides wrappers around fs.FS.

ModTimeFS

This wrapper makes sure calls to fs.FileInfo.Stat and fs.DirEntry.Info always return non-zero ModTime(). In case the wrapped file or entry return non-zero modification time it stays unchanged. In case they return a zero modification time then a static mod time will be used instead.

Usage:

var someFs fs.FS = getFS()
modTimeFS := wrapfs.WithModTime(someFS, time.Now())
http.FileServer(http.FS(modTimeFS))

This is especially helpful for embed.FS file systems when used in conjecture with http.FileServer. When wrapfs.WithModTime is used in this case the HTTP server will be able to handle caches which utilize the "Last-Modified" HTTP headers.

Known Limitations

If new interfaces are added in fs they will not be exposed as implemented by the wrappers until the library has been patched.

Documentation

Overview

Package wrapfs provides wrappers of the fs.FS with additional functionality.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func WithModTime

func WithModTime(root fs.FS, modTime time.Time) fs.FS

WithModTime returns a wrapper around `root` which makes sure calls to fs.File.FileInfo and fs.DirEntry.Info always return non-zero ModTime(). In case the wrapped file or entry return non-zero modification time it stays unchanged. In case they return a zero modification time then `modTime` is used instead.

Example

ExampleWithModTime makes sure that an embed.FS will still support If-Modified-Since HTTP headers when used with http.FileServer.

package main

import (
	"embed"
	"fmt"
	"net/http"
	"net/http/httptest"
	"time"

	"github.com/ironsmile/wrapfs"
)

//go:embed modtimefs.go
var testFS embed.FS

func main() {
	modTime := time.Unix(1727600261, 0)

	modTimeFS := wrapfs.WithModTime(testFS, modTime)

	handler := http.FileServer(http.FS(modTimeFS))
	req := httptest.NewRequest(http.MethodGet, "/modtimefs.go", nil)
	resp := httptest.NewRecorder()

	handler.ServeHTTP(resp, req)
	defer resp.Result().Body.Close()

	fmt.Printf("Last-Modified header: %s\n", resp.Result().Header.Get("Last-Modified"))
}
Output:
Last-Modified header: Sun, 29 Sep 2024 08:57:41 GMT
Example (Second)

ExampleWithModTime_second makes sure that when If-Modified-Since is used then the file server returns 304.

package main

import (
	"embed"
	"fmt"
	"net/http"
	"net/http/httptest"
	"time"

	"github.com/ironsmile/wrapfs"
)

//go:embed modtimefs.go
var testFS embed.FS

func main() {
	modTime := time.Unix(1727600261, 0)
	modSince := modTime.Add(1 * time.Hour)

	modTimeFS := wrapfs.WithModTime(testFS, modTime)

	handler := http.FileServer(http.FS(modTimeFS))
	req := httptest.NewRequest(http.MethodGet, "/modtimefs.go", nil)
	req.Header.Set("If-Modified-Since", modSince.UTC().Format(http.TimeFormat))
	resp := httptest.NewRecorder()

	handler.ServeHTTP(resp, req)
	defer resp.Result().Body.Close()

	fmt.Printf("HTTP Status Code: %d\n", resp.Result().StatusCode)
}
Output:
HTTP Status Code: 304

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL