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