Skip to content

Instantly share code, notes, and snippets.

@a10y
Created September 24, 2016 21:37
Show Gist options
  • Select an option

  • Save a10y/a2b56d58b5858a050243da8ea4f5c6b5 to your computer and use it in GitHub Desktop.

Select an option

Save a10y/a2b56d58b5858a050243da8ea4f5c6b5 to your computer and use it in GitHub Desktop.
// httpfs Performs GET requests when reading a file.
// Compile with `go build httpfs.go` and then run with `./httpfs /http`,
// then try doing `cat /http/aduffy.org`
package main
import (
"flag"
"io/ioutil"
"log"
"net/http"
"os"
"bazil.org/fuse"
"bazil.org/fuse/fs"
"golang.org/x/net/context"
)
func main() {
flag.Parse()
if flag.NArg() != 1 {
flag.Usage()
os.Exit(2)
}
mountpoint := flag.Arg(0)
c, err := fuse.Mount(
mountpoint,
fuse.FSName("http"),
fuse.Subtype("httpfs"),
fuse.LocalVolume(),
fuse.VolumeName("httpfs"),
)
if err != nil {
log.Fatal(err)
}
defer c.Close()
err = fs.Serve(c, FS{})
if err != nil {
log.Fatal(err)
}
// check if the mount process has an error to report
<-c.Ready
if err := c.MountError; err != nil {
log.Fatal(err)
}
}
// FS implements the hello world file system.
type FS struct{}
func (FS) Root() (fs.Node, error) {
return Dir{}, nil
}
// Dir implements both Node and Handle for the root directory.
type Dir struct{}
func (Dir) Attr(ctx context.Context, a *fuse.Attr) error {
a.Inode = 1
a.Mode = os.ModeDir | 0555
return nil
}
func (Dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
return File{"http://" + name}, nil
}
var dirDirs = []fuse.Dirent{
// {Inode: 2, Name: "hello", Type: fuse.DT_File},
}
func (Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
return dirDirs, nil
}
// File implements both Node and Handle for the hello file.
type File struct {
Url string // The URL we are looking up
}
func (f File) Attr(ctx context.Context, a *fuse.Attr) error {
a.Inode = 2 // Every file is ephemeral anyway
a.Mode = 0444 // Read only
bytes, err := getRequest(f.Url)
if err != nil {
a.Size = 0
} else {
a.Size = uint64(len(bytes))
}
return nil
}
func (f File) ReadAll(ctx context.Context) ([]byte, error) {
if body, err := getRequest(f.Url); err != nil {
return nil, err
} else {
return body, nil
}
}
func getRequest(url string) ([]byte, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
if body, err := ioutil.ReadAll(resp.Body); err != nil {
return nil, err
} else {
return body, nil
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment