mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 01:13:45 +00:00
swarm/api: Add contenttype contingent resolve manifest -> rsrc
This commit is contained in:
parent
a16d0af41d
commit
11c3b4cae1
4 changed files with 91 additions and 34 deletions
|
|
@ -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(key storage.Key, name string, period uint32, version uint32) (storage.Key, []byte, error) {
|
||||
func (self *Api) DbLookup(name string, period uint32, version uint32) (storage.Key, []byte, error) {
|
||||
var err error
|
||||
if version != 0 {
|
||||
if period == 0 {
|
||||
|
|
|
|||
|
|
@ -292,7 +292,8 @@ func (s *Server) HandleDelete(w http.ResponseWriter, r *Request) {
|
|||
}
|
||||
|
||||
func (s *Server) HandlePostDb(w http.ResponseWriter, r *Request) {
|
||||
if r.ContentLength == 0 {
|
||||
var outdata string
|
||||
if r.uri.Path != "" {
|
||||
frequency, err := strconv.ParseUint(r.uri.Path, 10, 64)
|
||||
if err != nil {
|
||||
s.BadRequest(w, r, fmt.Sprintf("Cannot parse frequency parameter: %v", err))
|
||||
|
|
@ -303,7 +304,33 @@ func (s *Server) HandlePostDb(w http.ResponseWriter, r *Request) {
|
|||
s.Error(w, r, fmt.Errorf("Resource creation failed: %v", err))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
manifestKey, err := s.api.NewManifest()
|
||||
if err != nil {
|
||||
s.Error(w, r, fmt.Errorf("create manifest err: %v", err))
|
||||
return
|
||||
}
|
||||
newKey, err := s.updateManifest(manifestKey, func(mw *api.ManifestWriter) error {
|
||||
key, err := mw.AddEntry(bytes.NewReader([]byte(r.uri.Addr)), &api.ManifestEntry{
|
||||
Path: r.uri.Addr,
|
||||
ContentType: api.ResourceContentType,
|
||||
Mode: 0644,
|
||||
Size: int64(len(r.uri.Addr)),
|
||||
ModTime: time.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.logDebug("resource manifest for for %s stored", key.Log())
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
s.Error(w, r, fmt.Errorf("update manifest err: %v", err))
|
||||
return
|
||||
}
|
||||
log.Debug("manifests", "new", newKey, "old", manifestKey)
|
||||
outdata = fmt.Sprintf("%s", newKey)
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
|
|
@ -311,12 +338,16 @@ func (s *Server) HandlePostDb(w http.ResponseWriter, r *Request) {
|
|||
}
|
||||
_, _, _, err = s.api.DbUpdate(r.uri.Addr, data)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Header().Add("Status", fmt.Sprintf("%d", http.StatusUnauthorized))
|
||||
http.ServeContent(w, &r.Request, "", time.Now(), bytes.NewReader([]byte(err.Error())))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
if outdata != "" {
|
||||
w.Header().Set("Content-type", "text/plain")
|
||||
fmt.Fprintf(w, outdata)
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve mutable resource updates:
|
||||
|
|
@ -325,13 +356,10 @@ func (s *Server) HandlePostDb(w http.ResponseWriter, r *Request) {
|
|||
// bzz-db[-[immutable|-raw]]://<id>/<n>/<m> - get update version m of period n
|
||||
// <id> = ens name or hash
|
||||
func (s *Server) HandleGetDb(w http.ResponseWriter, r *Request) {
|
||||
|
||||
rootKey, err := s.api.Resolve(r.uri)
|
||||
if err != nil {
|
||||
s.Error(w, r, fmt.Errorf("error resolving %s: %s", r.uri.Addr, err))
|
||||
return
|
||||
s.handleGetDb(w, r, r.uri.Addr)
|
||||
}
|
||||
|
||||
func (s *Server) handleGetDb(w http.ResponseWriter, r *Request, name string) {
|
||||
var params []string
|
||||
if len(r.uri.Path) > 0 {
|
||||
params = strings.Split(r.uri.Path, "/")
|
||||
|
|
@ -341,16 +369,18 @@ func (s *Server) HandleGetDb(w http.ResponseWriter, r *Request) {
|
|||
var version uint64
|
||||
var data []byte
|
||||
var dataLength int
|
||||
var err error
|
||||
now := time.Now()
|
||||
log.Debug("handlegetdb", "name", name)
|
||||
switch len(params) {
|
||||
case 0:
|
||||
updateKey, data, err = s.api.DbLookup(rootKey, r.uri.Addr, 0, 0)
|
||||
updateKey, data, err = s.api.DbLookup(name, 0, 0)
|
||||
case 2:
|
||||
version, err = strconv.ParseUint(params[1], 10, 32)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
updateKey, data, err = s.api.DbLookup(rootKey, r.uri.Addr, uint32(period), uint32(version))
|
||||
updateKey, data, err = s.api.DbLookup(name, uint32(period), uint32(version))
|
||||
case 1:
|
||||
version, err = strconv.ParseUint(params[1], 10, 32)
|
||||
if err != nil {
|
||||
|
|
@ -360,7 +390,7 @@ func (s *Server) HandleGetDb(w http.ResponseWriter, r *Request) {
|
|||
if err != nil {
|
||||
break
|
||||
}
|
||||
updateKey, data, err = s.api.DbLookup(rootKey, r.uri.Addr, uint32(period), uint32(version))
|
||||
updateKey, data, err = s.api.DbLookup(name, uint32(period), uint32(version))
|
||||
default:
|
||||
s.BadRequest(w, r, fmt.Sprintf("Invalid mutable resource request"))
|
||||
return
|
||||
|
|
@ -373,9 +403,9 @@ func (s *Server) HandleGetDb(w http.ResponseWriter, r *Request) {
|
|||
w.Header().Set("Content-Type", "application/octet-stream")
|
||||
} else {
|
||||
entry := api.ManifestEntry{
|
||||
Hash: rootKey.Hex(),
|
||||
Hash: name,
|
||||
Path: updateKey.Hex(),
|
||||
ContentType: api.DbManifestType,
|
||||
ContentType: api.ManifestType,
|
||||
Size: int64(dataLength),
|
||||
ModTime: now,
|
||||
Status: http.StatusOK,
|
||||
|
|
@ -395,7 +425,7 @@ func (s *Server) HandleGetDb(w http.ResponseWriter, r *Request) {
|
|||
s.Error(w, r, fmt.Errorf("Could not convert manifest to json: %v", err))
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", api.DbManifestType)
|
||||
w.Header().Set("Content-Type", api.ManifestType)
|
||||
data = []byte(manifestJson)
|
||||
}
|
||||
http.ServeContent(w, &r.Request, "", now, bytes.NewReader(data))
|
||||
|
|
@ -461,6 +491,17 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
|
|||
|
||||
switch {
|
||||
case r.uri.Raw():
|
||||
m := &api.Manifest{}
|
||||
sz, _ := reader.Size(nil)
|
||||
b := make([]byte, sz)
|
||||
reader.Read(b)
|
||||
err = json.Unmarshal(b, m)
|
||||
if len(m.Entries) > 0 {
|
||||
if m.Entries[0].ContentType == api.ResourceContentType {
|
||||
s.handleGetDb(w, r, m.Entries[0].Path)
|
||||
return
|
||||
}
|
||||
}
|
||||
// allow the request to overwrite the content type using a query
|
||||
// parameter
|
||||
contentType := "application/octet-stream"
|
||||
|
|
@ -468,7 +509,6 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
|
|||
contentType = typ
|
||||
}
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
|
||||
http.ServeContent(w, &r.Request, "", time.Now(), reader)
|
||||
case r.uri.Hash():
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
|
|
|
|||
|
|
@ -45,21 +45,27 @@ func TestBzzGetDb(t *testing.T) {
|
|||
defer srv.Close()
|
||||
|
||||
keybytes := make([]byte, common.HashLength) // nearest we get to source of info
|
||||
_, err := rand.Read(keybytes)
|
||||
copy(keybytes, []byte{42})
|
||||
|
||||
databytes := make([]byte, 42)
|
||||
_, err := rand.Read(databytes)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/bzz-db:/%s/42", srv.URL, fmt.Sprintf("%x", keybytes))
|
||||
resp, err := http.Post(url, "application/octet-stream", nil)
|
||||
url := fmt.Sprintf("%s/bzz-db:/%x/42", srv.URL, keybytes)
|
||||
resp, err := http.Post(url, "application/octet-stream", bytes.NewReader(databytes))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
manifesthash, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log.Debug("Create", "status", resp.Status, "body", b)
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("err %s", resp.Status)
|
||||
}
|
||||
log.Debug("Create", "status", resp.Status, "body", manifesthash)
|
||||
|
||||
url = fmt.Sprintf("%s/bzz-db:/%x", srv.URL, keybytes)
|
||||
data := []byte("foo")
|
||||
|
|
@ -67,13 +73,13 @@ func TestBzzGetDb(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b, err = ioutil.ReadAll(resp.Body)
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log.Debug("Update", "status", resp.Status, "body", b)
|
||||
log.Debug("Update", "status", resp.Status)
|
||||
|
||||
url = fmt.Sprintf("%s/bzz-db-raw:/%s", srv.URL, fmt.Sprintf("%x", keybytes))
|
||||
url = fmt.Sprintf("%s/bzz-raw:/%s", srv.URL, manifesthash)
|
||||
resp, err = http.Get(url)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -82,9 +88,9 @@ func TestBzzGetDb(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log.Debug("Get raw", "status", resp.Status, "body", b)
|
||||
log.Debug("Manifest", "status", resp.Status, "body", fmt.Sprintf("%s", b))
|
||||
|
||||
url = fmt.Sprintf("%s/bzz-db:/%s", srv.URL, fmt.Sprintf("%x", keybytes))
|
||||
url = fmt.Sprintf("%s/bzz-db-raw:/%x", srv.URL, keybytes)
|
||||
resp, err = http.Get(url)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -93,7 +99,18 @@ func TestBzzGetDb(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log.Debug("Get manifest", "status", resp.Status, "body", b)
|
||||
log.Debug("Get raw", "status", resp.Status)
|
||||
|
||||
url = fmt.Sprintf("%s/bzz-db:/%x", srv.URL, keybytes)
|
||||
resp, err = http.Get(url)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b, err = ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
log.Debug("Get manifest", "status", resp.Status)
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import (
|
|||
|
||||
const (
|
||||
ManifestType = "application/bzz-manifest+json"
|
||||
DbManifestType = "application/bzz-db-manifest+json"
|
||||
ResourceContentType = "application/bzz-resource"
|
||||
)
|
||||
|
||||
// Manifest represents a swarm manifest
|
||||
|
|
|
|||
Loading…
Reference in a new issue