Created
September 24, 2016 21:37
-
-
Save a10y/a2b56d58b5858a050243da8ea4f5c6b5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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