diff options
Diffstat (limited to 'common/docserver/docserver.go')
-rw-r--r-- | common/docserver/docserver.go | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/common/docserver/docserver.go b/common/docserver/docserver.go new file mode 100644 index 000000000..5d37ac97c --- /dev/null +++ b/common/docserver/docserver.go @@ -0,0 +1,93 @@ +package docserver + +import ( + "fmt" + "io/ioutil" + "net/http" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" +) + +// http://golang.org/pkg/net/http/#RoundTripper +var ( + schemes = map[string]func(*DocServer) http.RoundTripper{ + // Simple File server from local disk file:///etc/passwd :) + "file": fileServerOnDocRoot, + + // Swarm RoundTripper for bzz scheme bzz://mydomain/contact/twitter.json + // "bzz": &bzz.FileServer{}, + + // swarm remote file system call bzzfs:///etc/passwd + // "bzzfs": &bzzfs.FileServer{}, + + // restful peer protocol RoundTripper for enode scheme: + // POST suggestPeer DELETE removePeer PUT switch protocols + // RPC - standard protocol provides arc API for self enode (very safe remote server only connects to registered enode) + // POST enode://ae234dfgc56b..@128.56.68.5:3456/eth/getBlock/356eac67890fe + // and remote peer protocol + // POST enode://ae234dfgc56b..@128.56.68.5:3456/eth/getBlock/356eac67890fe + // proxy protoocol + + } +) + +func fileServerOnDocRoot(ds *DocServer) http.RoundTripper { + return http.NewFileTransport(http.Dir(ds.DocRoot)) +} + +type DocServer struct { + *http.Transport + DocRoot string +} + +func New(docRoot string) (self *DocServer, err error) { + self = &DocServer{ + Transport: &http.Transport{}, + DocRoot: docRoot, + } + err = self.RegisterProtocols(schemes) + return +} + +// Clients should be reused instead of created as needed. Clients are safe for concurrent use by multiple goroutines. + +// A Client is higher-level than a RoundTripper (such as Transport) and additionally handles HTTP details such as cookies and redirects. + +func (self *DocServer) Client() *http.Client { + return &http.Client{ + Transport: self, + } +} + +func (self *DocServer) RegisterProtocols(schemes map[string]func(*DocServer) http.RoundTripper) (err error) { + for scheme, rtf := range schemes { + self.RegisterProtocol(scheme, rtf(self)) + } + return +} + +func (self *DocServer) GetAuthContent(uri string, hash common.Hash) (content []byte, err error) { + // retrieve content + resp, err := self.Client().Get(uri) + defer resp.Body.Close() + if err != nil { + return + } + content, err = ioutil.ReadAll(resp.Body) + if err != nil { + return + } + + // check hash to authenticate content + hashbytes := crypto.Sha3(content) + var chash common.Hash + copy(chash[:], hashbytes) + if chash != hash { + content = nil + err = fmt.Errorf("content hash mismatch") + } + + return + +} |