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