parent
b49f21ec82
commit
d038393156
@ -0,0 +1,23 @@ |
|||||||
|
Copyright (c) 2014, Elazar Leibovich |
||||||
|
All rights reserved. |
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without |
||||||
|
modification, are permitted provided that the following conditions are met: |
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this |
||||||
|
list of conditions and the following disclaimer. |
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, |
||||||
|
this list of conditions and the following disclaimer in the documentation |
||||||
|
and/or other materials provided with the distribution. |
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
@ -0,0 +1,46 @@ |
|||||||
|
# go-bindata-assetfs |
||||||
|
|
||||||
|
Serve embedded files from [jteeuwen/go-bindata](https://github.com/jteeuwen/go-bindata) with `net/http`. |
||||||
|
|
||||||
|
[GoDoc](http://godoc.org/github.com/elazarl/go-bindata-assetfs) |
||||||
|
|
||||||
|
### Installation |
||||||
|
|
||||||
|
Install with |
||||||
|
|
||||||
|
$ go get github.com/jteeuwen/go-bindata/... |
||||||
|
$ go get github.com/elazarl/go-bindata-assetfs/... |
||||||
|
|
||||||
|
### Creating embedded data |
||||||
|
|
||||||
|
Usage is identical to [jteeuwen/go-bindata](https://github.com/jteeuwen/go-bindata) usage, |
||||||
|
instead of running `go-bindata` run `go-bindata-assetfs`. |
||||||
|
|
||||||
|
The tool will create a `bindata_assetfs.go` file, which contains the embedded data. |
||||||
|
|
||||||
|
A typical use case is |
||||||
|
|
||||||
|
$ go-bindata-assetfs data/... |
||||||
|
|
||||||
|
### Using assetFS in your code |
||||||
|
|
||||||
|
The generated file provides an `assetFS()` function that returns a `http.Filesystem` |
||||||
|
wrapping the embedded files. What you usually want to do is: |
||||||
|
|
||||||
|
http.Handle("/", http.FileServer(assetFS())) |
||||||
|
|
||||||
|
This would run an HTTP server serving the embedded files. |
||||||
|
|
||||||
|
## Without running binary tool |
||||||
|
|
||||||
|
You can always just run the `go-bindata` tool, and then |
||||||
|
|
||||||
|
use |
||||||
|
|
||||||
|
import "github.com/elazarl/go-bindata-assetfs" |
||||||
|
... |
||||||
|
http.Handle("/", |
||||||
|
http.FileServer( |
||||||
|
&assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, Prefix: "data"})) |
||||||
|
|
||||||
|
to serve files embedded from the `data` directory. |
@ -0,0 +1,147 @@ |
|||||||
|
package assetfs |
||||||
|
|
||||||
|
import ( |
||||||
|
"bytes" |
||||||
|
"errors" |
||||||
|
"io" |
||||||
|
"io/ioutil" |
||||||
|
"net/http" |
||||||
|
"os" |
||||||
|
"path" |
||||||
|
"path/filepath" |
||||||
|
"time" |
||||||
|
) |
||||||
|
|
||||||
|
var ( |
||||||
|
fileTimestamp = time.Now() |
||||||
|
) |
||||||
|
|
||||||
|
// FakeFile implements os.FileInfo interface for a given path and size
|
||||||
|
type FakeFile struct { |
||||||
|
// Path is the path of this file
|
||||||
|
Path string |
||||||
|
// Dir marks of the path is a directory
|
||||||
|
Dir bool |
||||||
|
// Len is the length of the fake file, zero if it is a directory
|
||||||
|
Len int64 |
||||||
|
} |
||||||
|
|
||||||
|
func (f *FakeFile) Name() string { |
||||||
|
_, name := filepath.Split(f.Path) |
||||||
|
return name |
||||||
|
} |
||||||
|
|
||||||
|
func (f *FakeFile) Mode() os.FileMode { |
||||||
|
mode := os.FileMode(0644) |
||||||
|
if f.Dir { |
||||||
|
return mode | os.ModeDir |
||||||
|
} |
||||||
|
return mode |
||||||
|
} |
||||||
|
|
||||||
|
func (f *FakeFile) ModTime() time.Time { |
||||||
|
return fileTimestamp |
||||||
|
} |
||||||
|
|
||||||
|
func (f *FakeFile) Size() int64 { |
||||||
|
return f.Len |
||||||
|
} |
||||||
|
|
||||||
|
func (f *FakeFile) IsDir() bool { |
||||||
|
return f.Mode().IsDir() |
||||||
|
} |
||||||
|
|
||||||
|
func (f *FakeFile) Sys() interface{} { |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// AssetFile implements http.File interface for a no-directory file with content
|
||||||
|
type AssetFile struct { |
||||||
|
*bytes.Reader |
||||||
|
io.Closer |
||||||
|
FakeFile |
||||||
|
} |
||||||
|
|
||||||
|
func NewAssetFile(name string, content []byte) *AssetFile { |
||||||
|
return &AssetFile{ |
||||||
|
bytes.NewReader(content), |
||||||
|
ioutil.NopCloser(nil), |
||||||
|
FakeFile{name, false, int64(len(content))}} |
||||||
|
} |
||||||
|
|
||||||
|
func (f *AssetFile) Readdir(count int) ([]os.FileInfo, error) { |
||||||
|
return nil, errors.New("not a directory") |
||||||
|
} |
||||||
|
|
||||||
|
func (f *AssetFile) Size() int64 { |
||||||
|
return f.FakeFile.Size() |
||||||
|
} |
||||||
|
|
||||||
|
func (f *AssetFile) Stat() (os.FileInfo, error) { |
||||||
|
return f, nil |
||||||
|
} |
||||||
|
|
||||||
|
// AssetDirectory implements http.File interface for a directory
|
||||||
|
type AssetDirectory struct { |
||||||
|
AssetFile |
||||||
|
ChildrenRead int |
||||||
|
Children []os.FileInfo |
||||||
|
} |
||||||
|
|
||||||
|
func NewAssetDirectory(name string, children []string, fs *AssetFS) *AssetDirectory { |
||||||
|
fileinfos := make([]os.FileInfo, 0, len(children)) |
||||||
|
for _, child := range children { |
||||||
|
_, err := fs.AssetDir(filepath.Join(name, child)) |
||||||
|
fileinfos = append(fileinfos, &FakeFile{child, err == nil, 0}) |
||||||
|
} |
||||||
|
return &AssetDirectory{ |
||||||
|
AssetFile{ |
||||||
|
bytes.NewReader(nil), |
||||||
|
ioutil.NopCloser(nil), |
||||||
|
FakeFile{name, true, 0}, |
||||||
|
}, |
||||||
|
0, |
||||||
|
fileinfos} |
||||||
|
} |
||||||
|
|
||||||
|
func (f *AssetDirectory) Readdir(count int) ([]os.FileInfo, error) { |
||||||
|
if count <= 0 { |
||||||
|
return f.Children, nil |
||||||
|
} |
||||||
|
if f.ChildrenRead+count > len(f.Children) { |
||||||
|
count = len(f.Children) - f.ChildrenRead |
||||||
|
} |
||||||
|
rv := f.Children[f.ChildrenRead : f.ChildrenRead+count] |
||||||
|
f.ChildrenRead += count |
||||||
|
return rv, nil |
||||||
|
} |
||||||
|
|
||||||
|
func (f *AssetDirectory) Stat() (os.FileInfo, error) { |
||||||
|
return f, nil |
||||||
|
} |
||||||
|
|
||||||
|
// AssetFS implements http.FileSystem, allowing
|
||||||
|
// embedded files to be served from net/http package.
|
||||||
|
type AssetFS struct { |
||||||
|
// Asset should return content of file in path if exists
|
||||||
|
Asset func(path string) ([]byte, error) |
||||||
|
// AssetDir should return list of files in the path
|
||||||
|
AssetDir func(path string) ([]string, error) |
||||||
|
// Prefix would be prepended to http requests
|
||||||
|
Prefix string |
||||||
|
} |
||||||
|
|
||||||
|
func (fs *AssetFS) Open(name string) (http.File, error) { |
||||||
|
name = path.Join(fs.Prefix, name) |
||||||
|
if len(name) > 0 && name[0] == '/' { |
||||||
|
name = name[1:] |
||||||
|
} |
||||||
|
if b, err := fs.Asset(name); err == nil { |
||||||
|
return NewAssetFile(name, b), nil |
||||||
|
} |
||||||
|
if children, err := fs.AssetDir(name); err == nil { |
||||||
|
return NewAssetDirectory(name, children, fs), nil |
||||||
|
} else { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
// assetfs allows packages to serve static content embedded
|
||||||
|
// with the go-bindata tool with the standard net/http package.
|
||||||
|
//
|
||||||
|
// See https://github.com/jteeuwen/go-bindata for more information
|
||||||
|
// about embedding binary data with go-bindata.
|
||||||
|
//
|
||||||
|
// Usage example, after running
|
||||||
|
// $ go-bindata data/...
|
||||||
|
// use:
|
||||||
|
// http.Handle("/",
|
||||||
|
// http.FileServer(
|
||||||
|
// &assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, Prefix: "data"}))
|
||||||
|
package assetfs |
Loading…
Reference in new issue