Last active
May 17, 2017 21:47
-
-
Save nf/d9aed75ca58f1105c57c1f7275652227 to your computer and use it in GitHub Desktop.
skeleton upspin server
This file contains 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
package main | |
import ( | |
"fmt" | |
"net/http" | |
"upspin.io/access" | |
"upspin.io/cloud/https" | |
"upspin.io/config" | |
"upspin.io/errors" | |
"upspin.io/flags" | |
"upspin.io/log" | |
"upspin.io/pack" | |
"upspin.io/path" | |
"upspin.io/rpc/dirserver" | |
"upspin.io/rpc/storeserver" | |
"upspin.io/serverutil" | |
"upspin.io/upspin" | |
_ "upspin.io/key/transports" | |
_ "upspin.io/pack/eeintegrity" | |
) | |
func main() { | |
flags.Parse(flags.Server) | |
cfg, err := config.FromFile(flags.Config) | |
if err != nil { | |
log.Fatal(err) | |
} | |
addr := upspin.NetAddr(flags.NetAddr) | |
ep := upspin.Endpoint{ | |
Transport: upspin.Remote, | |
NetAddr: addr, | |
} | |
s, err := newServer(cfg, ep) | |
if err != nil { | |
log.Fatal(err) | |
} | |
http.Handle("/api/Store/", storeserver.New(cfg, s.StoreServer(), addr)) | |
http.Handle("/api/Dir/", dirserver.New(cfg, s.DirServer(), addr)) | |
https.ListenAndServeFromFlags(nil) | |
} | |
const accessRef = upspin.Reference(access.AccessFile) | |
var accessRefdata = upspin.Refdata{Reference: accessRef} | |
var errNotImplemented = errors.Str("not implemented") | |
type server struct { | |
cfg upspin.Config | |
ep upspin.Endpoint | |
accessEntry *upspin.DirEntry | |
accessBytes []byte | |
} | |
func newServer(cfg upspin.Config, ep upspin.Endpoint) (*server, error) { | |
s := &server{ | |
cfg: cfg, | |
ep: ep, | |
} | |
rootAccess := []byte(fmt.Sprintf("Read: %s\nList,Create: all\n", cfg.UserName())) | |
var err error | |
s.accessEntry, s.accessBytes, err = s.pack(access.AccessFile, rootAccess) | |
if err != nil { | |
return nil, err | |
} | |
return s, nil | |
} | |
const packing = upspin.EEIntegrityPack | |
func (s *server) pack(filePath string, data []byte) (*upspin.DirEntry, []byte, error) { | |
name := upspin.PathName(s.cfg.UserName()) + "/" + upspin.PathName(filePath) | |
de := &upspin.DirEntry{ | |
Writer: s.cfg.UserName(), | |
Name: name, | |
SignedName: name, | |
Packing: packing, | |
Time: upspin.Now(), | |
Sequence: 1, | |
} | |
bp, err := pack.Lookup(packing).Pack(s.cfg, de) | |
if err != nil { | |
return nil, nil, err | |
} | |
cipher, err := bp.Pack(data) | |
if err != nil { | |
return nil, nil, err | |
} | |
bp.SetLocation(upspin.Location{ | |
Endpoint: s.ep, | |
Reference: upspin.Reference(filePath), | |
}) | |
return de, cipher, bp.Close() | |
} | |
func (s *server) DirServer() upspin.DirServer { return dirServer{s} } | |
func (s *server) StoreServer() upspin.StoreServer { return storeServer{s} } | |
func (s *server) Endpoint() upspin.Endpoint { return s.ep } | |
func (s *server) Ping() bool { return true } | |
func (s *server) Close() {} | |
type dirServer struct { | |
*server | |
} | |
func (s dirServer) Dial(upspin.Config, upspin.Endpoint) (upspin.Service, error) { | |
return s, nil | |
} | |
func (s dirServer) Lookup(name upspin.PathName) (*upspin.DirEntry, error) { | |
p, err := path.Parse(name) | |
if err != nil { | |
return nil, err | |
} | |
if p.User() != s.cfg.UserName() { | |
return nil, errors.E(name, errors.NotExist) | |
} | |
fp := p.FilePath() | |
switch fp { | |
case "": // Root directory. | |
return &upspin.DirEntry{ | |
Name: p.Path(), | |
SignedName: p.Path(), | |
Attr: upspin.AttrDirectory, | |
Time: upspin.Now(), | |
}, nil | |
case access.AccessFile: | |
return s.accessEntry, nil | |
} | |
return nil, errors.E(name, errors.Private) | |
} | |
func (s dirServer) Glob(pattern string) ([]*upspin.DirEntry, error) { | |
return serverutil.Glob(pattern, s.Lookup, s.listDir) | |
} | |
func (s dirServer) listDir(name upspin.PathName) ([]*upspin.DirEntry, error) { | |
p, err := path.Parse(name) | |
if err != nil { | |
return nil, err | |
} | |
if p.User() != s.cfg.UserName() || p.FilePath() != "" { | |
return nil, errors.E(name, errors.NotExist) | |
} | |
return []*upspin.DirEntry{ | |
s.accessEntry, | |
}, nil | |
} | |
func (s dirServer) WhichAccess(name upspin.PathName) (*upspin.DirEntry, error) { | |
return s.accessEntry, nil | |
} | |
func (s dirServer) Put(entry *upspin.DirEntry) (*upspin.DirEntry, error) { | |
return nil, errNotImplemented | |
} | |
func (s dirServer) Delete(name upspin.PathName) (*upspin.DirEntry, error) { | |
return nil, errNotImplemented | |
} | |
func (s dirServer) Watch(name upspin.PathName, order int64, done <-chan struct{}) (<-chan upspin.Event, error) { | |
return nil, upspin.ErrNotSupported | |
} | |
type storeServer struct { | |
*server | |
} | |
func (s storeServer) Dial(upspin.Config, upspin.Endpoint) (upspin.Service, error) { | |
return s, nil | |
} | |
func (s storeServer) Get(ref upspin.Reference) ([]byte, *upspin.Refdata, []upspin.Location, error) { | |
if ref == accessRef { | |
return s.accessBytes, &accessRefdata, nil, nil | |
} | |
return nil, nil, nil, errors.E(errors.NotExist) | |
} | |
func (s storeServer) Put(data []byte) (*upspin.Refdata, error) { | |
return nil, errNotImplemented | |
} | |
func (s storeServer) Delete(ref upspin.Reference) error { | |
return errNotImplemented | |
} |
This file contains 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
users: | |
- name: user | |
- name: imageserver | |
dirserver: $imageserver | |
storeserver: $imageserver | |
servers: | |
- name: keyserver | |
- name: storeserver | |
- name: dirserver | |
- name: imageserver | |
importpath: upspin.io/exp/cmd/imageserver | |
domain: example.com |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment