diff options
author | Javier Peletier <jm@epiclabs.io> | 2018-09-30 15:43:10 +0800 |
---|---|---|
committer | Javier Peletier <jm@epiclabs.io> | 2018-10-03 15:12:06 +0800 |
commit | 83705ef6aa3645a6305a400fa175e44904a929f7 (patch) | |
tree | 013c6594b7d275ab5eaa90b3969e77719787483f /swarm/api/http | |
parent | b35622cf3c758d96874f287d137725946fc6341d (diff) | |
download | dexon-83705ef6aa3645a6305a400fa175e44904a929f7.tar dexon-83705ef6aa3645a6305a400fa175e44904a929f7.tar.gz dexon-83705ef6aa3645a6305a400fa175e44904a929f7.tar.bz2 dexon-83705ef6aa3645a6305a400fa175e44904a929f7.tar.lz dexon-83705ef6aa3645a6305a400fa175e44904a929f7.tar.xz dexon-83705ef6aa3645a6305a400fa175e44904a929f7.tar.zst dexon-83705ef6aa3645a6305a400fa175e44904a929f7.zip |
swarm/storage/mru: Renamed rest of MRU references
Diffstat (limited to 'swarm/api/http')
-rw-r--r-- | swarm/api/http/server.go | 124 | ||||
-rw-r--r-- | swarm/api/http/server_test.go | 101 |
2 files changed, 80 insertions, 145 deletions
diff --git a/swarm/api/http/server.go b/swarm/api/http/server.go index 4c19dd6df..c5b3b564c 100644 --- a/swarm/api/http/server.go +++ b/swarm/api/http/server.go @@ -31,7 +31,6 @@ import ( "net/http" "os" "path" - "regexp" "strconv" "strings" "time" @@ -145,13 +144,13 @@ func NewServer(api *api.API, corsString string) *Server { defaultMiddlewares..., ), }) - mux.Handle("/bzz-resource:/", methodHandler{ + mux.Handle("/bzz-feed:/", methodHandler{ "GET": Adapt( - http.HandlerFunc(server.HandleGetResource), + http.HandlerFunc(server.HandleGetFeed), defaultMiddlewares..., ), "POST": Adapt( - http.HandlerFunc(server.HandlePostResource), + http.HandlerFunc(server.HandlePostFeed), defaultMiddlewares..., ), }) @@ -458,44 +457,13 @@ func (s *Server) HandleDelete(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, newKey) } -// Parses a resource update post url to corresponding action -// possible combinations: -// / add multihash update to existing hash -// /raw add raw update to existing hash -// /# create new resource with first update as mulitihash -// /raw/# create new resource with first update raw -func resourcePostMode(path string) (isRaw bool, frequency uint64, err error) { - re, err := regexp.Compile("^(raw)?/?([0-9]+)?$") - if err != nil { - return isRaw, frequency, err - } - m := re.FindAllStringSubmatch(path, 2) - var freqstr = "0" - if len(m) > 0 { - if m[0][1] != "" { - isRaw = true - } - if m[0][2] != "" { - freqstr = m[0][2] - } - } else if len(path) > 0 { - return isRaw, frequency, fmt.Errorf("invalid path") - } - frequency, err = strconv.ParseUint(freqstr, 10, 64) - return isRaw, frequency, err -} - -// Handles creation of new mutable resources and adding updates to existing mutable resources -// There are two types of updates available, "raw" and "multihash." -// If the latter is used, a subsequent bzz:// GET call to the manifest of the resource will return -// the page that the multihash is pointing to, as if it held a normal swarm content manifest -// -// The POST request admits a JSON structure as defined in the mru package: `mru.updateRequestJSON` -// The requests can be to a) create a resource, b) update a resource or c) both a+b: create a resource and set the initial content -func (s *Server) HandlePostResource(w http.ResponseWriter, r *http.Request) { +// Handles feed manifest creation and feed updates +// The POST request admits a JSON structure as defined in the feeds package: `feeds.updateRequestJSON` +// The requests can be to a) create a feed manifest, b) update a feed or c) both a+b: create a feed manifest and publish a first update +func (s *Server) HandlePostFeed(w http.ResponseWriter, r *http.Request) { ruid := GetRUID(r.Context()) uri := GetURI(r.Context()) - log.Debug("handle.post.resource", "ruid", ruid) + log.Debug("handle.post.feed", "ruid", ruid) var err error // Creation and update must send mru.updateRequestJSON JSON structure @@ -505,19 +473,19 @@ func (s *Server) HandlePostResource(w http.ResponseWriter, r *http.Request) { return } - view, err := s.api.ResolveResourceView(r.Context(), uri, r.URL.Query()) + feed, err := s.api.ResolveFeed(r.Context(), uri, r.URL.Query()) if err != nil { // couldn't parse query string or retrieve manifest getFail.Inc(1) httpStatus := http.StatusBadRequest - if err == api.ErrCannotLoadResourceManifest || err == api.ErrCannotResolveResourceURI { + if err == api.ErrCannotLoadFeedManifest || err == api.ErrCannotResolveFeedURI { httpStatus = http.StatusNotFound } - RespondError(w, r, fmt.Sprintf("cannot retrieve resource view: %s", err), httpStatus) + RespondError(w, r, fmt.Sprintf("cannot retrieve feed from manifest: %s", err), httpStatus) return } var updateRequest mru.Request - updateRequest.Feed = *view + updateRequest.Feed = *feed query := r.URL.Query() if err := updateRequest.FromValues(query, body); err != nil { // decodes request from query parameters @@ -527,13 +495,13 @@ func (s *Server) HandlePostResource(w http.ResponseWriter, r *http.Request) { if updateRequest.IsUpdate() { // Verify that the signature is intact and that the signer is authorized - // to update this resource - // Check this early, to avoid creating a resource and then not being able to set its first update. + // to update this feed + // Check this early, to avoid creating a feed and then not being able to set its first update. if err = updateRequest.Verify(); err != nil { RespondError(w, r, err.Error(), http.StatusForbidden) return } - _, err = s.api.ResourceUpdate(r.Context(), &updateRequest) + _, err = s.api.FeedsUpdate(r.Context(), &updateRequest) if err != nil { RespondError(w, r, err.Error(), http.StatusInternalServerError) return @@ -541,16 +509,16 @@ func (s *Server) HandlePostResource(w http.ResponseWriter, r *http.Request) { } if query.Get("manifest") == "1" { - // we create a manifest so we can retrieve the resource with bzz:// later - // this manifest has a special "resource type" manifest, and saves the - // resource view ID used to retrieve the resource later - m, err := s.api.NewResourceManifest(r.Context(), &updateRequest.Feed) + // we create a manifest so we can retrieve feed updates with bzz:// later + // this manifest has a special "feed type" manifest, and saves the + // feed identification used to retrieve feed updates later + m, err := s.api.NewFeedManifest(r.Context(), &updateRequest.Feed) if err != nil { - RespondError(w, r, fmt.Sprintf("failed to create resource manifest: %v", err), http.StatusInternalServerError) + RespondError(w, r, fmt.Sprintf("failed to create feed manifest: %v", err), http.StatusInternalServerError) return } // the key to the manifest will be passed back to the client - // the client can access the view directly through its resourceView member + // the client can access the Feed directly through its Feed member // the manifest key can be set as content in the resolver of the ENS name outdata, err := json.Marshal(m) if err != nil { @@ -563,41 +531,49 @@ func (s *Server) HandlePostResource(w http.ResponseWriter, r *http.Request) { } } -// Retrieve Swarm Feeds: -// bzz-resource://<id> - get latest update -// bzz-resource://<id>/?period=n - get latest update on period n -// bzz-resource://<id>/?period=n&version=m - get update version m of period n -// bzz-resource://<id>/meta - get metadata and next version information -// <id> = ens name or hash -// TODO: Enable pass maxPeriod parameter -func (s *Server) HandleGetResource(w http.ResponseWriter, r *http.Request) { +// HandleGetFeed retrieves Swarm Feeds updates: +// bzz-feed://<manifest address or ENS name> - get latest feed update, given a manifest address +// - or - +// specify user + topic (optional), subtopic name (optional) directly, without manifest: +// bzz-feed://?user=0x...&topic=0x...&name=subtopic name +// topic defaults to 0x000... if not specified. +// name defaults to empty string if not specified. +// thus, empty name and topic refers to the user's default feed. +// +// Optional parameters: +// time=xx - get the latest update before time (in epoch seconds) +// hint.time=xx - hint the lookup algorithm looking for updates at around that time +// hint.level=xx - hint the lookup algorithm looking for updates at around this frequency level +// meta=1 - get feed metadata and status information instead of performing a feed query +// NOTE: meta=1 will be deprecated in the near future +func (s *Server) HandleGetFeed(w http.ResponseWriter, r *http.Request) { ruid := GetRUID(r.Context()) uri := GetURI(r.Context()) - log.Debug("handle.get.resource", "ruid", ruid) + log.Debug("handle.get.feed", "ruid", ruid) var err error - view, err := s.api.ResolveResourceView(r.Context(), uri, r.URL.Query()) + feed, err := s.api.ResolveFeed(r.Context(), uri, r.URL.Query()) if err != nil { // couldn't parse query string or retrieve manifest getFail.Inc(1) httpStatus := http.StatusBadRequest - if err == api.ErrCannotLoadResourceManifest || err == api.ErrCannotResolveResourceURI { + if err == api.ErrCannotLoadFeedManifest || err == api.ErrCannotResolveFeedURI { httpStatus = http.StatusNotFound } - RespondError(w, r, fmt.Sprintf("cannot retrieve resource view: %s", err), httpStatus) + RespondError(w, r, fmt.Sprintf("cannot retrieve feed information from manifest: %s", err), httpStatus) return } // determine if the query specifies period and version or it is a metadata query if r.URL.Query().Get("meta") == "1" { - unsignedUpdateRequest, err := s.api.ResourceNewRequest(r.Context(), view) + unsignedUpdateRequest, err := s.api.FeedsNewRequest(r.Context(), feed) if err != nil { getFail.Inc(1) - RespondError(w, r, fmt.Sprintf("cannot retrieve resource metadata for view=%s: %s", view.Hex(), err), http.StatusNotFound) + RespondError(w, r, fmt.Sprintf("cannot retrieve feed metadata for feed=%s: %s", feed.Hex(), err), http.StatusNotFound) return } rawResponse, err := unsignedUpdateRequest.MarshalJSON() if err != nil { - RespondError(w, r, fmt.Sprintf("cannot encode unsigned UpdateRequest: %v", err), http.StatusInternalServerError) + RespondError(w, r, fmt.Sprintf("cannot encode unsigned feed update request: %v", err), http.StatusInternalServerError) return } w.Header().Add("Content-type", "application/json") @@ -606,28 +582,28 @@ func (s *Server) HandleGetResource(w http.ResponseWriter, r *http.Request) { return } - lookupParams := &mru.Query{Feed: *view} + lookupParams := &mru.Query{Feed: *feed} if err = lookupParams.FromValues(r.URL.Query()); err != nil { // parse period, version - RespondError(w, r, fmt.Sprintf("invalid mutable resource request:%s", err), http.StatusBadRequest) + RespondError(w, r, fmt.Sprintf("invalid feed update request:%s", err), http.StatusBadRequest) return } - data, err := s.api.ResourceLookup(r.Context(), lookupParams) + data, err := s.api.FeedsLookup(r.Context(), lookupParams) // any error from the switch statement will end up here if err != nil { - code, err2 := s.translateResourceError(w, r, "mutable resource lookup fail", err) + code, err2 := s.translateFeedError(w, r, "feed lookup fail", err) RespondError(w, r, err2.Error(), code) return } // All ok, serve the retrieved update - log.Debug("Found update", "view", view.Hex(), "ruid", ruid) + log.Debug("Found update", "feed", feed.Hex(), "ruid", ruid) w.Header().Set("Content-Type", api.MimeOctetStream) http.ServeContent(w, r, "", time.Now(), bytes.NewReader(data)) } -func (s *Server) translateResourceError(w http.ResponseWriter, r *http.Request, supErr string, err error) (int, error) { +func (s *Server) translateFeedError(w http.ResponseWriter, r *http.Request, supErr string, err error) (int, error) { code := 0 defaultErr := fmt.Errorf("%s: %v", supErr, err) rsrcErr, ok := err.(*mru.Error) diff --git a/swarm/api/http/server_test.go b/swarm/api/http/server_test.go index 0855d30a2..a7c7e3003 100644 --- a/swarm/api/http/server_test.go +++ b/swarm/api/http/server_test.go @@ -58,47 +58,6 @@ func init() { log.Root().SetHandler(log.CallerFileHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(os.Stderr, log.TerminalFormat(true))))) } -func TestResourcePostMode(t *testing.T) { - path := "" - errstr := "resourcePostMode for '%s' should be raw %v frequency %d, was raw %v, frequency %d" - r, f, err := resourcePostMode(path) - if err != nil { - t.Fatal(err) - } else if r || f != 0 { - t.Fatalf(errstr, path, false, 0, r, f) - } - - path = "raw" - r, f, err = resourcePostMode(path) - if err != nil { - t.Fatal(err) - } else if !r || f != 0 { - t.Fatalf(errstr, path, true, 0, r, f) - } - - path = "13" - r, f, err = resourcePostMode(path) - if err != nil { - t.Fatal(err) - } else if r || f == 0 { - t.Fatalf(errstr, path, false, 13, r, f) - } - - path = "raw/13" - r, f, err = resourcePostMode(path) - if err != nil { - t.Fatal(err) - } else if !r || f == 0 { - t.Fatalf(errstr, path, true, 13, r, f) - } - - path = "foo/13" - r, f, err = resourcePostMode(path) - if err == nil { - t.Fatal("resourcePostMode for 'foo/13' should fail, returned error nil") - } -} - func serverFunc(api *api.API) testutil.TestServer { return NewServer(api, "") } @@ -111,12 +70,12 @@ func newTestSigner() (*mru.GenericSigner, error) { return mru.NewGenericSigner(privKey), nil } -// test the transparent resolving of multihash resource types with bzz:// scheme +// test the transparent resolving of multihash-containing feed updates with bzz:// scheme // -// first upload data, and store the multihash to the resulting manifest in a resource update +// first upload data, and store the multihash to the resulting manifest in a feed update // retrieving the update with the multihash should return the manifest pointing directly to the data // and raw retrieve of that hash should return the data -func TestBzzResourceMultihash(t *testing.T) { +func TestBzzFeedMultihash(t *testing.T) { signer, _ := newTestSigner() @@ -154,7 +113,7 @@ func TestBzzResourceMultihash(t *testing.T) { } log.Info("added data", "manifest", string(b), "data", common.ToHex(mh)) - testUrl, err := url.Parse(fmt.Sprintf("%s/bzz-resource:/", srv.URL)) + testUrl, err := url.Parse(fmt.Sprintf("%s/bzz-feed:/", srv.URL)) if err != nil { t.Fatal(err) } @@ -182,12 +141,12 @@ func TestBzzResourceMultihash(t *testing.T) { t.Fatalf("data %s could not be unmarshaled: %v", b, err) } - correctManifestAddrHex := "6ef40ba1492cf2a029dc9a8b5896c822cf689d3cd010842f4f1744e6db8824bd" + correctManifestAddrHex := "bb056a5264c295c2b0f613c8409b9c87ce9d71576ace02458160df4cc894210b" if rsrcResp.Hex() != correctManifestAddrHex { - t.Fatalf("Response resource key mismatch, expected '%s', got '%s'", correctManifestAddrHex, rsrcResp.Hex()) + t.Fatalf("Response feed manifest address mismatch, expected '%s', got '%s'", correctManifestAddrHex, rsrcResp.Hex()) } - // get bzz manifest transparent resource resolve + // get bzz manifest transparent feed update resolve testBzzUrl = fmt.Sprintf("%s/bzz:/%s", srv.URL, rsrcResp) resp, err = http.Get(testBzzUrl) if err != nil { @@ -207,7 +166,7 @@ func TestBzzResourceMultihash(t *testing.T) { } // Test Swarm Feeds using the raw update methods -func TestBzzResource(t *testing.T) { +func TestBzzFeed(t *testing.T) { srv := testutil.NewTestSwarmServer(t, serverFunc, nil) signer, _ := newTestSigner() @@ -234,8 +193,8 @@ func TestBzzResource(t *testing.T) { t.Fatal(err) } - // creates resource and sets update 1 - testUrl, err := url.Parse(fmt.Sprintf("%s/bzz-resource:/", srv.URL)) + // creates feed and sets update 1 + testUrl, err := url.Parse(fmt.Sprintf("%s/bzz-feed:/", srv.URL)) if err != nil { t.Fatal(err) } @@ -262,9 +221,9 @@ func TestBzzResource(t *testing.T) { t.Fatalf("data %s could not be unmarshaled: %v", b, err) } - correctManifestAddrHex := "6ef40ba1492cf2a029dc9a8b5896c822cf689d3cd010842f4f1744e6db8824bd" + correctManifestAddrHex := "bb056a5264c295c2b0f613c8409b9c87ce9d71576ace02458160df4cc894210b" if rsrcResp.Hex() != correctManifestAddrHex { - t.Fatalf("Response resource manifest mismatch, expected '%s', got '%s'", correctManifestAddrHex, rsrcResp.Hex()) + t.Fatalf("Response feed manifest mismatch, expected '%s', got '%s'", correctManifestAddrHex, rsrcResp.Hex()) } // get the manifest @@ -289,12 +248,12 @@ func TestBzzResource(t *testing.T) { if len(manifest.Entries) != 1 { t.Fatalf("Manifest has %d entries", len(manifest.Entries)) } - correctViewHex := "0x666f6f2e65746800000000000000000000000000000000000000000000000000c96aaa54e2d44c299564da76e1cd3184a2386b8d" - if manifest.Entries[0].ResourceView.Hex() != correctViewHex { - t.Fatalf("Expected manifest Resource View '%s', got '%s'", correctViewHex, manifest.Entries[0].ResourceView.Hex()) + correctFeedHex := "0x666f6f2e65746800000000000000000000000000000000000000000000000000c96aaa54e2d44c299564da76e1cd3184a2386b8d" + if manifest.Entries[0].Feed.Hex() != correctFeedHex { + t.Fatalf("Expected manifest Feed '%s', got '%s'", correctFeedHex, manifest.Entries[0].Feed.Hex()) } - // get bzz manifest transparent resource resolve + // get bzz manifest transparent feed update resolve testBzzUrl := fmt.Sprintf("%s/bzz:/%s", srv.URL, rsrcResp) resp, err = http.Get(testBzzUrl) if err != nil { @@ -302,7 +261,7 @@ func TestBzzResource(t *testing.T) { } defer resp.Body.Close() if resp.StatusCode == http.StatusOK { - t.Fatal("Expected error status since resource is not multihash. Received 200 OK") + t.Fatal("Expected error status since feed update does not contain multihash. Received 200 OK") } b, err = ioutil.ReadAll(resp.Body) if err != nil { @@ -310,21 +269,21 @@ func TestBzzResource(t *testing.T) { } // get non-existent name, should fail - testBzzResUrl := fmt.Sprintf("%s/bzz-resource:/bar", srv.URL) + testBzzResUrl := fmt.Sprintf("%s/bzz-feed:/bar", srv.URL) resp, err = http.Get(testBzzResUrl) if err != nil { t.Fatal(err) } if resp.StatusCode != http.StatusNotFound { - t.Fatalf("Expected get non-existent resource to fail with StatusNotFound (404), got %d", resp.StatusCode) + t.Fatalf("Expected get non-existent feed manifest to fail with StatusNotFound (404), got %d", resp.StatusCode) } resp.Body.Close() - // get latest update (1.1) through resource directly + // get latest update through bzz-feed directly log.Info("get update latest = 1.1", "addr", correctManifestAddrHex) - testBzzResUrl = fmt.Sprintf("%s/bzz-resource:/%s", srv.URL, correctManifestAddrHex) + testBzzResUrl = fmt.Sprintf("%s/bzz-feed:/%s", srv.URL, correctManifestAddrHex) resp, err = http.Get(testBzzResUrl) if err != nil { t.Fatal(err) @@ -346,15 +305,15 @@ func TestBzzResource(t *testing.T) { srv.CurrentTime++ log.Info("update 2") - // 1.- get metadata about this resource - testBzzResUrl = fmt.Sprintf("%s/bzz-resource:/%s/", srv.URL, correctManifestAddrHex) + // 1.- get metadata about this Feed + testBzzResUrl = fmt.Sprintf("%s/bzz-feed:/%s/", srv.URL, correctManifestAddrHex) resp, err = http.Get(testBzzResUrl + "?meta=1") if err != nil { t.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - t.Fatalf("Get resource metadata returned %s", resp.Status) + t.Fatalf("Get feed metadata returned %s", resp.Status) } b, err = ioutil.ReadAll(resp.Body) if err != nil { @@ -362,13 +321,13 @@ func TestBzzResource(t *testing.T) { } updateRequest = &mru.Request{} if err = updateRequest.UnmarshalJSON(b); err != nil { - t.Fatalf("Error decoding resource metadata: %s", err) + t.Fatalf("Error decoding feed metadata: %s", err) } updateRequest.SetData(update2Data) if err = updateRequest.Sign(signer); err != nil { t.Fatal(err) } - testUrl, err = url.Parse(fmt.Sprintf("%s/bzz-resource:/", srv.URL)) + testUrl, err = url.Parse(fmt.Sprintf("%s/bzz-feed:/", srv.URL)) if err != nil { t.Fatal(err) } @@ -385,9 +344,9 @@ func TestBzzResource(t *testing.T) { t.Fatalf("Update returned %s", resp.Status) } - // get latest update (1.2) through resource directly + // get latest update through bzz-feed directly log.Info("get update 1.2") - testBzzResUrl = fmt.Sprintf("%s/bzz-resource:/%s", srv.URL, correctManifestAddrHex) + testBzzResUrl = fmt.Sprintf("%s/bzz-feed:/%s", srv.URL, correctManifestAddrHex) resp, err = http.Get(testBzzResUrl) if err != nil { t.Fatal(err) @@ -408,13 +367,13 @@ func TestBzzResource(t *testing.T) { log.Info("get first update in update1Timestamp via direct query") query := mru.NewQuery(&updateRequest.Feed, update1Timestamp, lookup.NoClue) - urlq, err := url.Parse(fmt.Sprintf("%s/bzz-resource:/", srv.URL)) + urlq, err := url.Parse(fmt.Sprintf("%s/bzz-feed:/", srv.URL)) if err != nil { t.Fatal(err) } values := urlq.Query() - query.AppendValues(values) // this adds view query parameters + query.AppendValues(values) // this adds feed query parameters urlq.RawQuery = values.Encode() resp, err = http.Get(urlq.String()) if err != nil { |