Commit 029f971d authored by Lars Gierth's avatar Lars Gierth

gateway: use core api for serving GET/HEAD requests

License: MIT
Signed-off-by: default avatarLars Gierth <larsg@systemli.org>
parent 46239e82
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
"net/http" "net/http"
core "github.com/ipfs/go-ipfs/core" core "github.com/ipfs/go-ipfs/core"
coreapi "github.com/ipfs/go-ipfs/core/coreapi"
config "github.com/ipfs/go-ipfs/repo/config" config "github.com/ipfs/go-ipfs/repo/config"
id "gx/ipfs/QmQfvKShQ2v7nkfCE4ygisxpcSBFvBYaorQ54SibY6PGXV/go-libp2p/p2p/protocol/identify" id "gx/ipfs/QmQfvKShQ2v7nkfCE4ygisxpcSBFvBYaorQ54SibY6PGXV/go-libp2p/p2p/protocol/identify"
) )
...@@ -27,7 +28,7 @@ func GatewayOption(writable bool, paths ...string) ServeOption { ...@@ -27,7 +28,7 @@ func GatewayOption(writable bool, paths ...string) ServeOption {
Headers: cfg.Gateway.HTTPHeaders, Headers: cfg.Gateway.HTTPHeaders,
Writable: writable, Writable: writable,
PathPrefixes: cfg.Gateway.PathPrefixes, PathPrefixes: cfg.Gateway.PathPrefixes,
}) }, coreapi.NewUnixfsAPI(n))
for _, p := range paths { for _, p := range paths {
mux.Handle(p+"/", gateway) mux.Handle(p+"/", gateway)
...@@ -37,7 +38,7 @@ func GatewayOption(writable bool, paths ...string) ServeOption { ...@@ -37,7 +38,7 @@ func GatewayOption(writable bool, paths ...string) ServeOption {
} }
func VersionOption() ServeOption { func VersionOption() ServeOption {
return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { return func(_ *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) {
mux.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) { mux.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Commit: %s\n", config.CurrentCommit) fmt.Fprintf(w, "Commit: %s\n", config.CurrentCommit)
fmt.Fprintf(w, "Client Version: %s\n", id.ClientVersion) fmt.Fprintf(w, "Client Version: %s\n", id.ClientVersion)
......
...@@ -16,9 +16,10 @@ import ( ...@@ -16,9 +16,10 @@ import (
chunk "github.com/ipfs/go-ipfs/importer/chunk" chunk "github.com/ipfs/go-ipfs/importer/chunk"
dag "github.com/ipfs/go-ipfs/merkledag" dag "github.com/ipfs/go-ipfs/merkledag"
dagutils "github.com/ipfs/go-ipfs/merkledag/utils" dagutils "github.com/ipfs/go-ipfs/merkledag/utils"
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
path "github.com/ipfs/go-ipfs/path" path "github.com/ipfs/go-ipfs/path"
ft "github.com/ipfs/go-ipfs/unixfs" ft "github.com/ipfs/go-ipfs/unixfs"
uio "github.com/ipfs/go-ipfs/unixfs/io"
humanize "gx/ipfs/QmPSBJL4momYnE7DcUyk2DVhD6rH488ZmHBGLbxNdhU44K/go-humanize" humanize "gx/ipfs/QmPSBJL4momYnE7DcUyk2DVhD6rH488ZmHBGLbxNdhU44K/go-humanize"
routing "gx/ipfs/QmQKEgGgYCDyk8VNY6A65FpuE4YwbspvjXHco1rdb75PVc/go-libp2p-routing" routing "gx/ipfs/QmQKEgGgYCDyk8VNY6A65FpuE4YwbspvjXHco1rdb75PVc/go-libp2p-routing"
...@@ -36,12 +37,14 @@ const ( ...@@ -36,12 +37,14 @@ const (
type gatewayHandler struct { type gatewayHandler struct {
node *core.IpfsNode node *core.IpfsNode
config GatewayConfig config GatewayConfig
api coreiface.UnixfsAPI
} }
func newGatewayHandler(node *core.IpfsNode, conf GatewayConfig) *gatewayHandler { func newGatewayHandler(n *core.IpfsNode, c GatewayConfig, api coreiface.UnixfsAPI) *gatewayHandler {
i := &gatewayHandler{ i := &gatewayHandler{
node: node, node: n,
config: conf, config: c,
api: api,
} }
return i return i
} }
...@@ -154,27 +157,19 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request ...@@ -154,27 +157,19 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
ipnsHostname = true ipnsHostname = true
} }
p, err := path.ParsePath(urlPath) dr, err := i.api.Cat(ctx, urlPath)
if err != nil { dir := false
webError(w, "Invalid Path Error", err, http.StatusBadRequest) if err == coreiface.ErrIsDir {
return dir = true
} } else if err == coreiface.ErrOffline {
nd, err := core.Resolve(ctx, i.node.Namesys, i.node.Resolver, p)
// If node is in offline mode the error code and message should be different
if err == core.ErrNoNamesys && !i.node.OnlineMode() {
w.WriteHeader(http.StatusServiceUnavailable) w.WriteHeader(http.StatusServiceUnavailable)
fmt.Fprint(w, "Could not resolve path. Node is in offline mode.") fmt.Fprint(w, "Could not resolve path. Node is in offline mode.")
return return
} else if err != nil { } else if err != nil {
webError(w, "Path Resolve error", err, http.StatusBadRequest) webError(w, "Path Resolve error", err, http.StatusBadRequest)
return return
} } else {
defer dr.Close()
pbnd, ok := nd.(*dag.ProtoNode)
if !ok {
webError(w, "Cannot read non protobuf nodes through gateway", dag.ErrNotProtobuf, http.StatusBadRequest)
return
} }
etag := gopath.Base(urlPath) etag := gopath.Base(urlPath)
...@@ -204,13 +199,6 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request ...@@ -204,13 +199,6 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
w.Header().Set("Suborigin", pathRoot) w.Header().Set("Suborigin", pathRoot)
} }
dr, err := uio.NewDagReader(ctx, pbnd, i.node.DAG)
if err != nil && err != uio.ErrIsDir {
// not a directory and still an error
internalWebError(w, err)
return
}
// set these headers _after_ the error, for we may just not have it // set these headers _after_ the error, for we may just not have it
// and dont want the client to cache a 500 response... // and dont want the client to cache a 500 response...
// and only if it's /ipfs! // and only if it's /ipfs!
...@@ -224,18 +212,23 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request ...@@ -224,18 +212,23 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
modtime = time.Unix(1, 0) modtime = time.Unix(1, 0)
} }
if err == nil { if !dir {
defer dr.Close()
name := gopath.Base(urlPath) name := gopath.Base(urlPath)
http.ServeContent(w, r, name, modtime, dr) http.ServeContent(w, r, name, modtime, dr)
return return
} }
links, err := i.api.Ls(ctx, urlPath)
if err != nil {
internalWebError(w, err)
return
}
// storage for directory listing // storage for directory listing
var dirListing []directoryItem var dirListing []directoryItem
// loop through files // loop through files
foundIndex := false foundIndex := false
for _, link := range nd.Links() { for _, link := range links {
if link.Name == "index.html" { if link.Name == "index.html" {
log.Debugf("found index.html link for %s", urlPath) log.Debugf("found index.html link for %s", urlPath)
foundIndex = true foundIndex = true
...@@ -254,19 +247,7 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request ...@@ -254,19 +247,7 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
} }
// return index page instead. // return index page instead.
nd, err := core.Resolve(ctx, i.node.Namesys, i.node.Resolver, p) dr, err := i.api.Cat(ctx, p.String())
if err != nil {
internalWebError(w, err)
return
}
pbnd, ok := nd.(*dag.ProtoNode)
if !ok {
internalWebError(w, dag.ErrNotProtobuf)
return
}
dr, err := uio.NewDagReader(ctx, pbnd, i.node.DAG)
if err != nil { if err != nil {
internalWebError(w, err) internalWebError(w, err)
return return
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment