@cryptotaxi247 / kubo / commits / 029f971d9

gateway: use core api for serving GET/HEAD requests

License: MIT Signed-off-by: Lars Gierth <larsg@systemli.org>

Lars Gierth committed Sep 11, 2016 at 05:18 UTC 029f971d9cb7e89e523568758c01e2c9924e5af9
2 files changed +26 -44
core/corehttp/gateway.go
+3 -2
@@ -6,6 +6,7 @@ import (
6 "net/http"
7
8 core "github.com/ipfs/go-ipfs/core"
9 + coreapi "github.com/ipfs/go-ipfs/core/coreapi"
10 config "github.com/ipfs/go-ipfs/repo/config"
11 id "gx/ipfs/QmQfvKShQ2v7nkfCE4ygisxpcSBFvBYaorQ54SibY6PGXV/go-libp2p/p2p/protocol/identify"
12 )
@@ -27,7 +28,7 @@ func GatewayOption(writable bool, paths ...string) ServeOption {
28 Headers: cfg.Gateway.HTTPHeaders,
29 Writable: writable,
30 PathPrefixes: cfg.Gateway.PathPrefixes,
30 - })
31 + }, coreapi.NewUnixfsAPI(n))
32
33 for _, p := range paths {
34 mux.Handle(p+"/", gateway)
@@ -37,7 +38,7 @@ func GatewayOption(writable bool, paths ...string) ServeOption {
38 }
39
40 func VersionOption() ServeOption {
40 - return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) {
41 + return func(_ *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) {
42 mux.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) {
43 fmt.Fprintf(w, "Commit: %s\n", config.CurrentCommit)
44 fmt.Fprintf(w, "Client Version: %s\n", id.ClientVersion)
core/corehttp/gateway_handler.go
+23 -42
@@ -16,9 +16,10 @@ import (
16 chunk "github.com/ipfs/go-ipfs/importer/chunk"
17 dag "github.com/ipfs/go-ipfs/merkledag"
18 dagutils "github.com/ipfs/go-ipfs/merkledag/utils"
19 +
20 + coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
21 path "github.com/ipfs/go-ipfs/path"
22 ft "github.com/ipfs/go-ipfs/unixfs"
21 - uio "github.com/ipfs/go-ipfs/unixfs/io"
23
24 humanize "gx/ipfs/QmPSBJL4momYnE7DcUyk2DVhD6rH488ZmHBGLbxNdhU44K/go-humanize"
25 routing "gx/ipfs/QmQKEgGgYCDyk8VNY6A65FpuE4YwbspvjXHco1rdb75PVc/go-libp2p-routing"
@@ -36,12 +37,14 @@ const (
37 type gatewayHandler struct {
38 node *core.IpfsNode
39 config GatewayConfig
40 + api coreiface.UnixfsAPI
41 }
42
41 -func newGatewayHandler(node *core.IpfsNode, conf GatewayConfig) *gatewayHandler {
43 +func newGatewayHandler(n *core.IpfsNode, c GatewayConfig, api coreiface.UnixfsAPI) *gatewayHandler {
44 i := &gatewayHandler{
43 - node: node,
44 - config: conf,
45 + node: n,
46 + config: c,
47 + api: api,
48 }
49 return i
50 }
@@ -154,27 +157,19 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
157 ipnsHostname = true
158 }
159
157 - p, err := path.ParsePath(urlPath)
158 - if err != nil {
159 - webError(w, "Invalid Path Error", err, http.StatusBadRequest)
160 - return
161 - }
162 -
163 - nd, err := core.Resolve(ctx, i.node.Namesys, i.node.Resolver, p)
164 - // If node is in offline mode the error code and message should be different
165 - if err == core.ErrNoNamesys && !i.node.OnlineMode() {
160 + dr, err := i.api.Cat(ctx, urlPath)
161 + dir := false
162 + if err == coreiface.ErrIsDir {
163 + dir = true
164 + } else if err == coreiface.ErrOffline {
165 w.WriteHeader(http.StatusServiceUnavailable)
166 fmt.Fprint(w, "Could not resolve path. Node is in offline mode.")
167 return
168 } else if err != nil {
169 webError(w, "Path Resolve error", err, http.StatusBadRequest)
170 return
172 - }
173 -
174 - pbnd, ok := nd.(*dag.ProtoNode)
175 - if !ok {
176 - webError(w, "Cannot read non protobuf nodes through gateway", dag.ErrNotProtobuf, http.StatusBadRequest)
177 - return
171 + } else {
172 + defer dr.Close()
173 }
174
175 etag := gopath.Base(urlPath)
@@ -204,13 +199,6 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
199 w.Header().Set("Suborigin", pathRoot)
200 }
201
207 - dr, err := uio.NewDagReader(ctx, pbnd, i.node.DAG)
208 - if err != nil && err != uio.ErrIsDir {
209 - // not a directory and still an error
210 - internalWebError(w, err)
211 - return
212 - }
213 -
202 // set these headers _after_ the error, for we may just not have it
203 // and dont want the client to cache a 500 response...
204 // and only if it's /ipfs!
@@ -224,18 +212,23 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
212 modtime = time.Unix(1, 0)
213 }
214
227 - if err == nil {
228 - defer dr.Close()
215 + if !dir {
216 name := gopath.Base(urlPath)
217 http.ServeContent(w, r, name, modtime, dr)
218 return
219 }
220
221 + links, err := i.api.Ls(ctx, urlPath)
222 + if err != nil {
223 + internalWebError(w, err)
224 + return
225 + }
226 +
227 // storage for directory listing
228 var dirListing []directoryItem
229 // loop through files
230 foundIndex := false
238 - for _, link := range nd.Links() {
231 + for _, link := range links {
232 if link.Name == "index.html" {
233 log.Debugf("found index.html link for %s", urlPath)
234 foundIndex = true
@@ -254,19 +247,7 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
247 }
248
249 // return index page instead.
257 - nd, err := core.Resolve(ctx, i.node.Namesys, i.node.Resolver, p)
258 - if err != nil {
259 - internalWebError(w, err)
260 - return
261 - }
262 -
263 - pbnd, ok := nd.(*dag.ProtoNode)
264 - if !ok {
265 - internalWebError(w, dag.ErrNotProtobuf)
266 - return
267 - }
268 -
269 - dr, err := uio.NewDagReader(ctx, pbnd, i.node.DAG)
250 + dr, err := i.api.Cat(ctx, p.String())
251 if err != nil {
252 internalWebError(w, err)
253 return