From ca31f22a6ac896f9c77f8b32b98ed973af526c68 Mon Sep 17 00:00:00 2001 From: justelad Date: Thu, 28 Jun 2018 12:11:31 +0200 Subject: [PATCH] wip --- swarm/api/http/controllers/bzz-hash.go | 16 ++++ swarm/api/http/controllers/bzz-immutable.go | 16 ++++ swarm/api/http/controllers/bzz-list.go | 84 +++++++++++++++++++ swarm/api/http/controllers/bzz-raw.go | 16 ++++ swarm/api/http/controllers/bzz-resource.go | 16 ++++ swarm/api/http/controllers/bzz.go | 16 ++++ swarm/api/http/controllers/controller.go | 15 ++++ swarm/api/http/messages/request.go | 30 +++++++ swarm/api/http/messages/response.go | 16 ++++ swarm/api/http/server.go | 89 ++++----------------- swarm/api/http/views/error.tmpl | 0 11 files changed, 241 insertions(+), 73 deletions(-) create mode 100644 swarm/api/http/controllers/bzz-hash.go create mode 100644 swarm/api/http/controllers/bzz-immutable.go create mode 100644 swarm/api/http/controllers/bzz-list.go create mode 100644 swarm/api/http/controllers/bzz-raw.go create mode 100644 swarm/api/http/controllers/bzz-resource.go create mode 100644 swarm/api/http/controllers/bzz.go create mode 100644 swarm/api/http/controllers/controller.go create mode 100644 swarm/api/http/messages/request.go create mode 100644 swarm/api/http/messages/response.go create mode 100644 swarm/api/http/views/error.tmpl diff --git a/swarm/api/http/controllers/bzz-hash.go b/swarm/api/http/controllers/bzz-hash.go new file mode 100644 index 0000000000..0cc3cc4673 --- /dev/null +++ b/swarm/api/http/controllers/bzz-hash.go @@ -0,0 +1,16 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package controllers diff --git a/swarm/api/http/controllers/bzz-immutable.go b/swarm/api/http/controllers/bzz-immutable.go new file mode 100644 index 0000000000..0cc3cc4673 --- /dev/null +++ b/swarm/api/http/controllers/bzz-immutable.go @@ -0,0 +1,16 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package controllers diff --git a/swarm/api/http/controllers/bzz-list.go b/swarm/api/http/controllers/bzz-list.go new file mode 100644 index 0000000000..99f4ce14b4 --- /dev/null +++ b/swarm/api/http/controllers/bzz-list.go @@ -0,0 +1,84 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package controllers + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + + "github.com/ethereum/go-ethereum/swarm/api" + "github.com/ethereum/go-ethereum/swarm/api/http" + "github.com/ethereum/go-ethereum/swarm/log" +) + +type BzzListController struct { + *Controller +} + +//var BzzListController BzzListController + +// HandleGetList handles a GET request to bzz-list:// and returns +// a list of all files contained in under grouped into +// common prefixes using "/" as a delimiter +func (controller *BzzListController) Get(w http.ResponseWriter, r *Request) { + log.Debug("handle.get.list", "ruid", r.ruid, "uri", r.uri) + getListCount.Inc(1) + // ensure the root path has a trailing slash so that relative URLs work + if r.uri.Path == "" && !strings.HasSuffix(r.URL.Path, "/") { + http.Redirect(w, &r.Request, r.URL.Path+"/", http.StatusMovedPermanently) + return + } + + addr, err := s.api.Resolve(r.uri) + if err != nil { + getListFail.Inc(1) + Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusNotFound) + return + } + log.Debug("handle.get.list: resolved", "ruid", r.ruid, "key", addr) + + list, err := s.getManifestList(addr, r.uri.Path) + + if err != nil { + getListFail.Inc(1) + Respond(w, r, err.Error(), http.StatusInternalServerError) + return + } + + // if the client wants HTML (e.g. a browser) then render the list as a + // HTML index with relative URLs + if strings.Contains(r.Header.Get("Accept"), "text/html") { + w.Header().Set("Content-Type", "text/html") + err := htmlListTemplate.Execute(w, &htmlListData{ + URI: &api.URI{ + Scheme: "bzz", + Addr: r.uri.Addr, + Path: r.uri.Path, + }, + List: &list, + }) + if err != nil { + getListFail.Inc(1) + log.Error(fmt.Sprintf("error rendering list HTML: %s", err)) + } + return + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(&list) +} diff --git a/swarm/api/http/controllers/bzz-raw.go b/swarm/api/http/controllers/bzz-raw.go new file mode 100644 index 0000000000..0cc3cc4673 --- /dev/null +++ b/swarm/api/http/controllers/bzz-raw.go @@ -0,0 +1,16 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package controllers diff --git a/swarm/api/http/controllers/bzz-resource.go b/swarm/api/http/controllers/bzz-resource.go new file mode 100644 index 0000000000..0cc3cc4673 --- /dev/null +++ b/swarm/api/http/controllers/bzz-resource.go @@ -0,0 +1,16 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package controllers diff --git a/swarm/api/http/controllers/bzz.go b/swarm/api/http/controllers/bzz.go new file mode 100644 index 0000000000..0cc3cc4673 --- /dev/null +++ b/swarm/api/http/controllers/bzz.go @@ -0,0 +1,16 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package controllers diff --git a/swarm/api/http/controllers/controller.go b/swarm/api/http/controllers/controller.go new file mode 100644 index 0000000000..937b9dd81a --- /dev/null +++ b/swarm/api/http/controllers/controller.go @@ -0,0 +1,15 @@ +package controllers + +import ( + "net/http" + + "github.com/ethereum/go-ethereum/swarm/api/http/request" +) + +type Controller struct { + ControllerHandler +} + +type ControllerHandler interface { + Get(w http.ResponseWriter, r *request.Request) +} diff --git a/swarm/api/http/messages/request.go b/swarm/api/http/messages/request.go new file mode 100644 index 0000000000..0769147961 --- /dev/null +++ b/swarm/api/http/messages/request.go @@ -0,0 +1,30 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package messages + +import ( + "net/http" + + "github.com/ethereum/go-ethereum/swarm/api" +) + +// Request wraps http.Request and also includes the parsed bzz URI +type Request struct { + http.Request + + uri *api.URI + ruid string // request unique id +} diff --git a/swarm/api/http/messages/response.go b/swarm/api/http/messages/response.go new file mode 100644 index 0000000000..435903426e --- /dev/null +++ b/swarm/api/http/messages/response.go @@ -0,0 +1,16 @@ +// Copyright 2018 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . +package messages diff --git a/swarm/api/http/server.go b/swarm/api/http/server.go index ba8b2b7ba9..d0f460ee3f 100644 --- a/swarm/api/http/server.go +++ b/swarm/api/http/server.go @@ -42,6 +42,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/swarm/api" + "github.com/ethereum/go-ethereum/swarm/api/http/request" "github.com/ethereum/go-ethereum/swarm/log" "github.com/ethereum/go-ethereum/swarm/storage" "github.com/ethereum/go-ethereum/swarm/storage/mru" @@ -110,17 +111,9 @@ type Server struct { api *api.API } -// Request wraps http.Request and also includes the parsed bzz URI -type Request struct { - http.Request - - uri *api.URI - ruid string // request unique id -} - // HandlePostRaw handles a POST request to a raw bzz-raw:/ URI, stores the request // body in swarm and returns the resulting storage address as a text/plain response -func (s *Server) HandlePostRaw(w http.ResponseWriter, r *Request) { +func (s *Server) HandlePostRaw(w http.ResponseWriter, r *request.Request) { log.Debug("handle.post.raw", "ruid", r.ruid) postRawCount.Inc(1) @@ -166,7 +159,7 @@ func (s *Server) HandlePostRaw(w http.ResponseWriter, r *Request) { // (either a tar archive or multipart form), adds those files either to an // existing manifest or to a new manifest under and returns the // resulting manifest hash as a text/plain response -func (s *Server) HandlePostFiles(w http.ResponseWriter, r *Request) { +func (s *Server) HandlePostFiles(w http.ResponseWriter, r *request.Request) { log.Debug("handle.post.files", "ruid", r.ruid) postFilesCount.Inc(1) @@ -227,7 +220,7 @@ func (s *Server) HandlePostFiles(w http.ResponseWriter, r *Request) { fmt.Fprint(w, newAddr) } -func (s *Server) handleTarUpload(req *Request, mw *api.ManifestWriter) error { +func (s *Server) handleTarUpload(req *request.Request, mw *api.ManifestWriter) error { log.Debug("handle.tar.upload", "ruid", req.ruid) tr := tar.NewReader(req.Body) for { @@ -261,7 +254,7 @@ func (s *Server) handleTarUpload(req *Request, mw *api.ManifestWriter) error { } } -func (s *Server) handleMultipartUpload(req *Request, boundary string, mw *api.ManifestWriter) error { +func (s *Server) handleMultipartUpload(req *request.Request, boundary string, mw *api.ManifestWriter) error { log.Debug("handle.multipart.upload", "ruid", req.ruid) mr := multipart.NewReader(req.Body, boundary) for { @@ -319,7 +312,7 @@ func (s *Server) handleMultipartUpload(req *Request, boundary string, mw *api.Ma } } -func (s *Server) handleDirectUpload(req *Request, mw *api.ManifestWriter) error { +func (s *Server) handleDirectUpload(req *request.Request, mw *api.ManifestWriter) error { log.Debug("handle.direct.upload", "ruid", req.ruid) key, err := mw.AddEntry(req.Body, &api.ManifestEntry{ Path: req.uri.Path, @@ -338,7 +331,7 @@ func (s *Server) handleDirectUpload(req *Request, mw *api.ManifestWriter) error // HandleDelete handles a DELETE request to bzz://, removes // from and returns the resulting manifest hash as a // text/plain response -func (s *Server) HandleDelete(w http.ResponseWriter, r *Request) { +func (s *Server) HandleDelete(w http.ResponseWriter, r *request.Request) { log.Debug("handle.delete", "ruid", r.ruid) deleteCount.Inc(1) @@ -399,7 +392,7 @@ func resourcePostMode(path string) (isRaw bool, frequency uint64, err error) { // The resource name will be verbatim what is passed as the address part of the url. // For example, if a POST is made to /bzz-resource:/foo.eth/raw/13 a new resource with frequency 13 // and name "foo.eth" will be created -func (s *Server) HandlePostResource(w http.ResponseWriter, r *Request) { +func (s *Server) HandlePostResource(w http.ResponseWriter, r *request.Request) { log.Debug("handle.post.resource", "ruid", r.ruid) var err error var addr storage.Address @@ -518,12 +511,12 @@ func (s *Server) HandlePostResource(w http.ResponseWriter, r *Request) { // bzz-resource:/// - get latest update on period n // bzz-resource://// - get update version m of period n // = ens name or hash -func (s *Server) HandleGetResource(w http.ResponseWriter, r *Request) { +func (s *Server) HandleGetResource(w http.ResponseWriter, r *request.Request) { s.handleGetResource(w, r) } // TODO: Enable pass maxPeriod parameter -func (s *Server) handleGetResource(w http.ResponseWriter, r *Request) { +func (s *Server) handleGetResource(w http.ResponseWriter, r *request.Request) { log.Debug("handle.get.resource", "ruid", r.ruid) var err error @@ -597,7 +590,7 @@ func (s *Server) handleGetResource(w http.ResponseWriter, r *Request) { http.ServeContent(w, &r.Request, "", now, bytes.NewReader(data)) } -func (s *Server) translateResourceError(w http.ResponseWriter, r *Request, supErr string, err error) (int, error) { +func (s *Server) translateResourceError(w http.ResponseWriter, r *request.Request, supErr string, err error) (int, error) { code := 0 defaultErr := fmt.Errorf("%s: %v", supErr, err) rsrcErr, ok := err.(*mru.Error) @@ -623,7 +616,7 @@ func (s *Server) translateResourceError(w http.ResponseWriter, r *Request, supEr // given storage key // - bzz-hash:// and responds with the hash of the content stored // at the given storage key as a text/plain response -func (s *Server) HandleGet(w http.ResponseWriter, r *Request) { +func (s *Server) HandleGet(w http.ResponseWriter, r *request.Request) { log.Debug("handle.get", "ruid", r.ruid, "uri", r.uri) getCount.Inc(1) var err error @@ -721,7 +714,7 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *Request) { // HandleGetFiles handles a GET request to bzz:/ with an Accept // header of "application/x-tar" and returns a tar stream of all files // contained in the manifest -func (s *Server) HandleGetFiles(w http.ResponseWriter, r *Request) { +func (s *Server) HandleGetFiles(w http.ResponseWriter, r *request.Request) { log.Debug("handle.get.files", "ruid", r.ruid, "uri", r.uri) getFilesCount.Inc(1) if r.uri.Path != "" { @@ -794,57 +787,6 @@ func (s *Server) HandleGetFiles(w http.ResponseWriter, r *Request) { } } -// HandleGetList handles a GET request to bzz-list:// and returns -// a list of all files contained in under grouped into -// common prefixes using "/" as a delimiter -func (s *Server) HandleGetList(w http.ResponseWriter, r *Request) { - log.Debug("handle.get.list", "ruid", r.ruid, "uri", r.uri) - getListCount.Inc(1) - // ensure the root path has a trailing slash so that relative URLs work - if r.uri.Path == "" && !strings.HasSuffix(r.URL.Path, "/") { - http.Redirect(w, &r.Request, r.URL.Path+"/", http.StatusMovedPermanently) - return - } - - addr, err := s.api.Resolve(r.uri) - if err != nil { - getListFail.Inc(1) - Respond(w, r, fmt.Sprintf("cannot resolve %s: %s", r.uri.Addr, err), http.StatusNotFound) - return - } - log.Debug("handle.get.list: resolved", "ruid", r.ruid, "key", addr) - - list, err := s.getManifestList(addr, r.uri.Path) - - if err != nil { - getListFail.Inc(1) - Respond(w, r, err.Error(), http.StatusInternalServerError) - return - } - - // if the client wants HTML (e.g. a browser) then render the list as a - // HTML index with relative URLs - if strings.Contains(r.Header.Get("Accept"), "text/html") { - w.Header().Set("Content-Type", "text/html") - err := htmlListTemplate.Execute(w, &htmlListData{ - URI: &api.URI{ - Scheme: "bzz", - Addr: r.uri.Addr, - Path: r.uri.Path, - }, - List: &list, - }) - if err != nil { - getListFail.Inc(1) - log.Error(fmt.Sprintf("error rendering list HTML: %s", err)) - } - return - } - - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(&list) -} - func (s *Server) getManifestList(addr storage.Address, prefix string) (list api.ManifestList, err error) { walker, err := s.api.NewManifestWalker(addr, nil) if err != nil { @@ -903,7 +845,7 @@ func (s *Server) getManifestList(addr storage.Address, prefix string) (list api. // HandleGetFile handles a GET request to bzz:/// and responds // with the content of the file at from the given -func (s *Server) HandleGetFile(w http.ResponseWriter, r *Request) { +func (s *Server) HandleGetFile(w http.ResponseWriter, r *request.Request) { log.Debug("handle.get.file", "ruid", r.ruid) getFileCount.Inc(1) // ensure the root path has a trailing slash so that relative URLs work @@ -1091,7 +1033,8 @@ func (s *Server) ServeHTTP(rw http.ResponseWriter, r *http.Request) { } if uri.List() { - s.HandleGetList(w, req) + + //ctrl.(w, req) return } diff --git a/swarm/api/http/views/error.tmpl b/swarm/api/http/views/error.tmpl new file mode 100644 index 0000000000..e69de29bb2