mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 09:23:48 +00:00
swarm/api: Add raw form to api+server WIP
This commit is contained in:
parent
81ec1f9694
commit
1bf4f4a37f
6 changed files with 105 additions and 50 deletions
|
|
@ -46,9 +46,9 @@ on top of the dpa
|
|||
it is the public interface of the dpa which is included in the ethereum stack
|
||||
*/
|
||||
type Api struct {
|
||||
resource *storage.ResourceHandler
|
||||
dpa *storage.DPA
|
||||
dns Resolver
|
||||
resource *storage.ResourceHandler
|
||||
}
|
||||
|
||||
//the api constructor initialises
|
||||
|
|
@ -365,7 +365,7 @@ func (self *Api) BuildDirectoryTree(mhash string, nameresolver bool) (key storag
|
|||
}
|
||||
|
||||
// Look up mutable resource updates at specific periods and versions
|
||||
func (self *Api) DbLookup(name string, period uint32, version uint32) (io.ReadSeeker, error) {
|
||||
func (self *Api) DbLookup(key storage.Key, name string, period uint32, version uint32) (io.ReadSeeker, error) {
|
||||
var err error
|
||||
if version != 0 {
|
||||
if period == 0 {
|
||||
|
|
@ -375,16 +375,20 @@ func (self *Api) DbLookup(name string, period uint32, version uint32) (io.ReadSe
|
|||
}
|
||||
period = self.resource.BlockToPeriod(name, currentblocknumber)
|
||||
}
|
||||
_, err = self.resource.LookupVersion(name, period, version, true)
|
||||
_, err = self.resource.LookupVersionByName(name, period, version, true)
|
||||
} else if period != 0 {
|
||||
_, err = self.resource.LookupHistorical(name, period, true)
|
||||
_, err = self.resource.LookupHistoricalByName(name, period, true)
|
||||
} else {
|
||||
_, err = self.resource.LookupLatest(name, true)
|
||||
_, err = self.resource.LookupLatestByName(name, true)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bytes.NewReader(self.resource.GetData(name)), nil
|
||||
data, err := self.resource.GetData(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bytes.NewReader(data), nil
|
||||
}
|
||||
|
||||
func (self *Api) DbCreate(name string, frequency uint64) (err error) {
|
||||
|
|
@ -394,5 +398,11 @@ func (self *Api) DbCreate(name string, frequency uint64) (err error) {
|
|||
|
||||
func (self *Api) DbUpdate(name string, data []byte) (storage.Key, uint32, uint32, error) {
|
||||
key, err := self.resource.Update(name, data)
|
||||
return key, self.resource.GetLastPeriod(name), self.resource.GetVersion(name), err
|
||||
period, _ := self.resource.GetLastPeriod(name)
|
||||
version, _ := self.resource.GetVersion(name)
|
||||
return key, period, version, err
|
||||
}
|
||||
|
||||
func (self *Api) DbHashSize() int {
|
||||
return self.resource.HashSize()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -332,36 +332,42 @@ func (s *Server) HandleGetDb(w http.ResponseWriter, r *Request) {
|
|||
s.Error(w, r, fmt.Errorf("error resolving %s: %s", r.uri.Addr, err))
|
||||
return
|
||||
}
|
||||
_ = key
|
||||
|
||||
var params []string
|
||||
if len(r.uri.Path) > 0 {
|
||||
params = strings.Split(r.uri.Path, "/")
|
||||
}
|
||||
var period uint64
|
||||
var version uint64
|
||||
var data io.ReadSeeker
|
||||
switch len(params) {
|
||||
case 0:
|
||||
data, err := s.api.DbLookup(r.uri.Addr)
|
||||
data, err = s.api.DbLookup(key, r.uri.Addr, 0, 0)
|
||||
break
|
||||
case 2:
|
||||
strconv.ParseUint(params[1], 10, 32)
|
||||
version, err = strconv.ParseUint(params[1], 10, 32)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
case 1:
|
||||
strconv.ParseUint(params[0], 10, 32)
|
||||
period, err = strconv.ParseUint(params[0], 10, 32)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
data, err = s.api.DbLookup(key, r.uri.Addr, uint32(period), uint32(version))
|
||||
break
|
||||
default:
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
err = "params 0-2"
|
||||
err = fmt.Errorf("params 0-2")
|
||||
}
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
wrappedData := wrapDbContent(data, s.uri.Scheme)
|
||||
if !r.uri.DbRaw() {
|
||||
|
||||
}
|
||||
http.ServeContent(w, &r.Request, "", time.Now(), data)
|
||||
|
||||
}
|
||||
|
||||
func wrapDbContent(data io.Reader, scheme *string) io.Reader {
|
||||
|
||||
}
|
||||
|
||||
// HandleGet handles a GET request to
|
||||
|
|
@ -705,6 +711,12 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
s.HandleDelete(w, req)
|
||||
|
||||
case "GET":
|
||||
|
||||
if uri.Db() || uri.DbRaw() {
|
||||
s.HandleGetDb(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
if uri.Raw() || uri.Hash() || uri.DeprecatedRaw() {
|
||||
s.HandleGet(w, req)
|
||||
return
|
||||
|
|
@ -720,11 +732,6 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if uri.Db() {
|
||||
s.HandleGetDb(w, req)
|
||||
return
|
||||
}
|
||||
|
||||
s.HandleGetFile(w, req)
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package http_test
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
|
@ -43,7 +44,14 @@ func TestBzzGetDb(t *testing.T) {
|
|||
srv := testutil.NewTestSwarmServer(t)
|
||||
defer srv.Close()
|
||||
|
||||
url := srv.URL + "/bzz-db:/foo/42"
|
||||
keybytes := make([]byte, common.HashLength) // nearest we get to source of info
|
||||
_, err := rand.Read(keybytes)
|
||||
if err != nil {
|
||||
fmt.Printf("err: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/bzz-db:/%s/42", srv.URL, fmt.Sprintf("%x", keybytes))
|
||||
resp, err := http.Post(url, "application/octet-stream", nil)
|
||||
if err != nil {
|
||||
fmt.Printf("err: %v\n", err)
|
||||
|
|
@ -52,7 +60,7 @@ func TestBzzGetDb(t *testing.T) {
|
|||
b, err := ioutil.ReadAll(resp.Body)
|
||||
fmt.Printf("Create: %s : %s\n", resp.Status, b)
|
||||
|
||||
url = srv.URL + "/bzz-db:/foo"
|
||||
url = fmt.Sprintf("%s/bzz-db:/%s", srv.URL, fmt.Sprintf("%x", keybytes))
|
||||
data := []byte("foo")
|
||||
resp, err = http.Post(url, "application/octet-stream", bytes.NewReader(data))
|
||||
if err != nil {
|
||||
|
|
@ -62,7 +70,7 @@ func TestBzzGetDb(t *testing.T) {
|
|||
b, err = ioutil.ReadAll(resp.Body)
|
||||
fmt.Printf("Update: %s : %s\n", resp.Status, b)
|
||||
|
||||
url = srv.URL + "/bzz-db:/foo"
|
||||
url = fmt.Sprintf("%s/bzz-db-raw:/%s", srv.URL, fmt.Sprintf("%x", keybytes))
|
||||
resp, err = http.Get(url)
|
||||
if err != nil {
|
||||
fmt.Printf("err: %v\n", err)
|
||||
|
|
@ -70,7 +78,6 @@ func TestBzzGetDb(t *testing.T) {
|
|||
}
|
||||
b, err = ioutil.ReadAll(resp.Body)
|
||||
fmt.Printf("Get: %s : %s\n", resp.Status, b)
|
||||
|
||||
}
|
||||
|
||||
func TestBzzGetPath(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ func (self *resource) isSynced() bool {
|
|||
// Implement to activate validation of resource updates
|
||||
// Specifically signing data and verification of signatures
|
||||
type ResourceValidator interface {
|
||||
hashSize() int
|
||||
checkAccess(string, common.Address) (bool, error)
|
||||
nameHash(string) common.Hash // nameHashFunc
|
||||
sign(common.Hash) (Signature, error) // SignFunc
|
||||
|
|
@ -166,28 +167,34 @@ func NewResourceHandler(datadir string, cloudStore CloudStore, rpcClient *rpc.Cl
|
|||
return rh, nil
|
||||
}
|
||||
|
||||
func (self *ResourceHandler) GetData(name string) []byte {
|
||||
rsrc := self.getResource(name)
|
||||
if rsrc == nil {
|
||||
return nil
|
||||
}
|
||||
return rsrc.data
|
||||
func (self *ResourceHandler) HashSize() int {
|
||||
return self.validator.hashSize()
|
||||
}
|
||||
|
||||
func (self *ResourceHandler) GetLastPeriod(name string) uint32 {
|
||||
// get data from current resource
|
||||
func (self *ResourceHandler) GetData(name string) ([]byte, error) {
|
||||
rsrc := self.getResource(name)
|
||||
if rsrc == nil {
|
||||
return 0
|
||||
if rsrc == nil || !rsrc.isSynced() {
|
||||
return nil, fmt.Errorf("Resource does not exist or is not synced")
|
||||
}
|
||||
return rsrc.lastPeriod
|
||||
return rsrc.data, nil
|
||||
}
|
||||
|
||||
func (self *ResourceHandler) GetVersion(name string) uint32 {
|
||||
func (self *ResourceHandler) GetLastPeriod(name string) (uint32, error) {
|
||||
rsrc := self.getResource(name)
|
||||
if rsrc == nil {
|
||||
return 0
|
||||
|
||||
if rsrc == nil || !rsrc.isSynced() {
|
||||
return 0, fmt.Errorf("Resource does not exist or is not synced")
|
||||
}
|
||||
return rsrc.version
|
||||
return rsrc.lastPeriod, nil
|
||||
}
|
||||
|
||||
func (self *ResourceHandler) GetVersion(name string) (uint32, error) {
|
||||
rsrc := self.getResource(name)
|
||||
if rsrc == nil || !rsrc.isSynced() {
|
||||
return 0, fmt.Errorf("Resource does not exist or is not synced")
|
||||
}
|
||||
return rsrc.version, nil
|
||||
}
|
||||
|
||||
// \TODO should be hashsize * branches from the chosen chunker, implement with dpa
|
||||
|
|
@ -269,8 +276,14 @@ func (self *ResourceHandler) NewResource(name string, frequency uint64) (*resour
|
|||
// root chunk.
|
||||
// It is the callers responsibility to make sure that this chunk exists (if the resource
|
||||
// update root data was retrieved externally, it typically doesn't)
|
||||
func (self *ResourceHandler) LookupVersion(name string, period uint32, version uint32, refresh bool) (*resource, error) {
|
||||
rsrc, err := self.loadResource(name, refresh)
|
||||
//
|
||||
//
|
||||
func (self *ResourceHandler) LookupVersionByName(name string, period uint32, version uint32, refresh bool) (*resource, error) {
|
||||
return self.LookupVersion(self.nameHash(name), name, period, version, refresh)
|
||||
}
|
||||
|
||||
func (self *ResourceHandler) LookupVersion(nameHash common.Hash, name string, period uint32, version uint32, refresh bool) (*resource, error) {
|
||||
rsrc, err := self.loadResource(nameHash, name, refresh)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -285,8 +298,12 @@ func (self *ResourceHandler) LookupVersion(name string, period uint32, version u
|
|||
// and returned.
|
||||
//
|
||||
// See also (*ResourceHandler).LookupVersion
|
||||
func (self *ResourceHandler) LookupHistorical(name string, period uint32, refresh bool) (*resource, error) {
|
||||
rsrc, err := self.loadResource(name, refresh)
|
||||
func (self *ResourceHandler) LookupHistoricalByName(name string, period uint32, refresh bool) (*resource, error) {
|
||||
return self.LookupHistorical(self.nameHash(name), name, period, refresh)
|
||||
}
|
||||
|
||||
func (self *ResourceHandler) LookupHistorical(nameHash common.Hash, name string, period uint32, refresh bool) (*resource, error) {
|
||||
rsrc, err := self.loadResource(nameHash, name, refresh)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -303,10 +320,14 @@ func (self *ResourceHandler) LookupHistorical(name string, period uint32, refres
|
|||
// Version iteration is done as in (*ResourceHandler).LookupHistorical
|
||||
//
|
||||
// See also (*ResourceHandler).LookupHistorical
|
||||
func (self *ResourceHandler) LookupLatest(name string, refresh bool) (*resource, error) {
|
||||
func (self *ResourceHandler) LookupLatestByName(name string, refresh bool) (*resource, error) {
|
||||
return self.LookupLatest(self.nameHash(name), name, refresh)
|
||||
}
|
||||
|
||||
func (self *ResourceHandler) LookupLatest(nameHash common.Hash, name string, refresh bool) (*resource, error) {
|
||||
|
||||
// get our blockheight at this time and the next block of the update period
|
||||
rsrc, err := self.loadResource(name, refresh)
|
||||
rsrc, err := self.loadResource(nameHash, name, refresh)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -362,7 +383,11 @@ func (self *ResourceHandler) lookup(rsrc *resource, period uint32, version uint3
|
|||
}
|
||||
|
||||
// load existing mutable resource into resource struct
|
||||
func (self *ResourceHandler) loadResource(name string, refresh bool) (*resource, error) {
|
||||
func (self *ResourceHandler) loadResource(nameHash common.Hash, name string, refresh bool) (*resource, error) {
|
||||
|
||||
if name == "" {
|
||||
name = nameHash.Hex()
|
||||
}
|
||||
|
||||
// if the resource is not known to this session we must load it
|
||||
// if refresh is set, we force load
|
||||
|
|
@ -374,7 +399,7 @@ func (self *ResourceHandler) loadResource(name string, refresh bool) (*resource,
|
|||
return nil, fmt.Errorf("Invalid name '%s'", name)
|
||||
}
|
||||
rsrc.name = &name
|
||||
rsrc.nameHash = self.nameHash(name)
|
||||
rsrc.nameHash = nameHash
|
||||
|
||||
// get the root info chunk and update the cached value
|
||||
chunk, err := self.Get(Key(rsrc.nameHash[:]))
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
type baseValidator struct {
|
||||
signFunc SignFunc
|
||||
hashsize int
|
||||
}
|
||||
|
||||
func (b *baseValidator) sign(datahash common.Hash) (signature Signature, err error) {
|
||||
|
|
@ -19,6 +20,10 @@ func (b *baseValidator) sign(datahash common.Hash) (signature Signature, err err
|
|||
return b.signFunc(datahash)
|
||||
}
|
||||
|
||||
func (b *baseValidator) hashSize() int {
|
||||
return b.hashsize
|
||||
}
|
||||
|
||||
// ENS validation of mutable resource owners
|
||||
type ENSValidator struct {
|
||||
*baseValidator
|
||||
|
|
@ -30,6 +35,7 @@ func NewENSValidator(contractaddress common.Address, backend bind.ContractBacken
|
|||
validator := &ENSValidator{
|
||||
baseValidator: &baseValidator{
|
||||
signFunc: signFunc,
|
||||
hashsize: common.HashLength,
|
||||
},
|
||||
}
|
||||
validator.api, err = ens.NewENS(transactOpts, contractaddress, backend)
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ func NewTestSwarmServer(t *testing.T) *TestSwarmServer {
|
|||
Server: srv,
|
||||
Dpa: dpa,
|
||||
dir: dir,
|
||||
hasher: storage.MakeHashFunc("SHA3")(),
|
||||
hasher: storage.MakeHashFunc(storage.SHA3Hash)(),
|
||||
cleanup: func() {
|
||||
rh.Close()
|
||||
rpcClean()
|
||||
|
|
|
|||
Loading…
Reference in a new issue