zipfs

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 23, 2020 License: BSD-3-Clause Imports: 8 Imported by: 1

README

zipfs

Package zipfs is an implementation of a Go http.FileSystem. Instead of serving files from a local filesystem directory, it serves the contents of a provided zip file. This might be useful to you if you have a Golang HTTP server (perhaps an API server) and would like to serve static content (perhaps a single-page application).

Hosting static content from a zip archive has several nice properties:

  • Data is stored in compressed form (of course), which makes it relatively efficient for large static asset bundles.
  • File metadata (particularly modification time) is preserved, which allows for caching.
  • Because zip archive data can be prefixed with any amount of arbitrary data, you can actually embed it into your server's binary executable file by concatenating it. This is extremely convenient and is perhaps the most compelling use case. An example of this is below.

Usage

Embedded zip data

As described above, it is possible to embed zip data directly into your server's binary executable file. Here's some example code for this:

package main

import (
	"log"
	"net/http"

	"gerace.dev/zipfs"
)

func main() {
	fs, err := zipfs.NewEmbeddedZipFileSystem()
	if err != nil {
		log.Fatalf("Error setting up zipfs: %v", err)
	}

	log.Fatal(http.ListenAndServe("127.0.0.1:8080", http.FileServer(fs)))
}

After you build your executable, append your zip file to it like so:

cat webassets.zip >>myserverbinary
zip -A myserverbinary

That's it!

Loading a normal zip file

For the more general case of supplying a zip file normally, you can pass any *zip.Reader and create a ZipFileSystem instance from that.

package main

import (
	"archive/zip"
	"log"
	"net/http"
	"os"

	"gerace.dev/zipfs"
)

func main() {
	f, err := os.Open("webassets.zip")
	if err != nil {
		log.Fatalf("Error opening webassets.zip: %v", err)
	}

	fi, err := f.Stat()
	if err != nil {
		log.Fatalf("Error getting file information about webassets.zip: %v", err)
	}

	zr, err := zip.NewReader(f, fi.Size())
	if err != nil {
		log.Fatalf("Error reading zip data from webassets.zip: %v", err)
	}

	fs, err := zipfs.NewZipFileSystem(zr)
	if err != nil {
		log.Fatalf("Error creating zip filesystem: %v", err)
	}

	log.Fatal(http.ListenAndServe("127.0.0.1:8080", http.FileServer(fs)))
}
Specifying Options

Options can be specified during instantiation, like so:

package main

import (
	"log"
	"net/http"

	"gerace.dev/zipfs"
)

func main() {
	fs, err := zipfs.NewEmbeddedZipFileSystem(zipfs.ServeIndexForMissing())
	if err != nil {
		log.Fatalf("Error setting up zipfs: %v", err)
	}

	log.Fatal(http.ListenAndServe("127.0.0.1:8080", http.FileServer(fs)))
}

Options

ServeIndexForMissing

This option is useful for hosting single-page applications that mutate the browser history state locally. When specified, requests for files that aren't in the zip archive will receive the content of index.html at the root of the zip archive, if it exists.

Documentation

Overview

Package zipfs provides an implementation of an http.FileSystem backed by the contents of a Zip file.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Option

type Option func(*ZipFileSystem)

Option represents a single option for a ZipFileSystem

func ServeIndexForMissing

func ServeIndexForMissing() Option

ServeIndexForMissing configures the filesystem to always serve the content of index.html (at the root of the zip archive) when a nonexistent path is requested. This is useful for single-page applications.

type ZipFileSystem

type ZipFileSystem struct {
	// contains filtered or unexported fields
}

ZipFileSystem is an implementation of http.FileSystem based on the contents of a zip file.

func NewEmbeddedZipFileSystem

func NewEmbeddedZipFileSystem(setters ...Option) (*ZipFileSystem, error)

NewEmbeddedZipFileSystem creates a new ZipFileSystem, while loading the zip content from the currently-running binary file itself.

func NewZipFileSystem

func NewZipFileSystem(zr *zip.Reader, setters ...Option) (*ZipFileSystem, error)

NewZipFileSystem creates a new ZipFileSystem with the provided zip.Reader and options.

func (*ZipFileSystem) Open

func (z *ZipFileSystem) Open(name string) (http.File, error)

Open finds and opens a given file by its name. It normalizes the file path by stripping the leading slash.

Jump to

Keyboard shortcuts

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