From dd99a70a7dda920a0f7dad5ad14e980202fae3ce Mon Sep 17 00:00:00 2001
From: rht <rhtbot@gmail.com>
Date: Sat, 15 Aug 2015 11:10:07 +0700
Subject: [PATCH] Add readonly api to gateway

Based on https://github.com/ipfs/go-ipfs/pull/1389

License: MIT
Signed-off-by: rht <rhtbot@gmail.com>
---
 cmd/ipfs/daemon.go             |  1 +
 core/commands/root.go          | 30 ++++++++++++++++++++++++++++++
 core/corehttp/commands.go      | 12 ++++++++++--
 test/sharness/t0110-gateway.sh | 13 +++++++++++++
 4 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go
index 0b23d079d..1b4917f14 100644
--- a/cmd/ipfs/daemon.go
+++ b/cmd/ipfs/daemon.go
@@ -401,6 +401,7 @@ func serveHTTPGateway(req cmds.Request) (error, <-chan error) {
 	}
 
 	var opts = []corehttp.ServeOption{
+		corehttp.CommandsROOption(*req.InvocContext()),
 		corehttp.VersionOption(),
 		corehttp.IPNSHostnameOption(),
 		corehttp.GatewayOption(writable),
diff --git a/core/commands/root.go b/core/commands/root.go
index 13d459162..1b842a486 100644
--- a/core/commands/root.go
+++ b/core/commands/root.go
@@ -109,9 +109,39 @@ var rootSubcommands = map[string]*cmds.Command{
 	"version":   VersionCmd,
 	"bitswap":   BitswapCmd,
 }
+var rootROSubcommands = map[string]*cmds.Command{
+	"block": &cmds.Command{
+		Subcommands: map[string]*cmds.Command{
+			"stat": blockStatCmd,
+			"get":  blockGetCmd,
+		},
+	},
+	"cat":      CatCmd,
+	"commands": CommandsDaemonCmd,
+	"ls":       LsCmd,
+	"name": &cmds.Command{
+		Subcommands: map[string]*cmds.Command{
+			"resolve": IpnsCmd,
+		},
+	},
+	"object": &cmds.Command{
+		Subcommands: map[string]*cmds.Command{
+			"data":  objectDataCmd,
+			"links": objectLinksCmd,
+			"get":   objectGetCmd,
+			"stat":  objectStatCmd,
+		},
+	},
+	"refs": RefsCmd,
+	//"resolve": ResolveCmd,
+}
+
+var RootRO = &cmds.Command{}
 
 func init() {
+	*RootRO = *Root
 	Root.Subcommands = rootSubcommands
+	RootRO.Subcommands = rootROSubcommands
 }
 
 type MessageOutput struct {
diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go
index d96818e2a..e3a64f0f8 100644
--- a/core/corehttp/commands.go
+++ b/core/corehttp/commands.go
@@ -99,7 +99,7 @@ func patchCORSVars(c *cmdsHttp.ServerConfig, addr net.Addr) {
 	}
 }
 
-func CommandsOption(cctx commands.Context) ServeOption {
+func commandsOption(cctx commands.Context, command *commands.Command) ServeOption {
 	return func(n *core.IpfsNode, l net.Listener, mux *http.ServeMux) (*http.ServeMux, error) {
 
 		cfg := &cmdsHttp.ServerConfig{
@@ -113,8 +113,16 @@ func CommandsOption(cctx commands.Context) ServeOption {
 		addCORSDefaults(cfg)
 		patchCORSVars(cfg, l.Addr())
 
-		cmdHandler := cmdsHttp.NewHandler(cctx, corecommands.Root, cfg)
+		cmdHandler := cmdsHttp.NewHandler(cctx, command, cfg)
 		mux.Handle(cmdsHttp.ApiPath+"/", cmdHandler)
 		return mux, nil
 	}
 }
+
+func CommandsOption(cctx commands.Context) ServeOption {
+	return commandsOption(cctx, corecommands.Root)
+}
+
+func CommandsROOption(cctx commands.Context) ServeOption {
+	return commandsOption(cctx, corecommands.RootRO)
+}
diff --git a/test/sharness/t0110-gateway.sh b/test/sharness/t0110-gateway.sh
index efef1f9cb..8bfcfbf0d 100755
--- a/test/sharness/t0110-gateway.sh
+++ b/test/sharness/t0110-gateway.sh
@@ -91,6 +91,19 @@ test_expect_success "log output looks good" '
 	grep "log API client connected" log_out
 '
 
+# test ipfs readonly api
+test_expect_success "get IPFS directory file through readonly API succeeds" '
+  curl -sfo actual "http://127.0.0.1:$port/api/v0/cat?arg=$HASH2/test"
+'
+
+test_expect_success "get IPFS directory file through readonly API output looks good" '
+  test_cmp dir/test actual
+'
+
+test_expect_success "refs IPFS directory file through readonly API succeeds" '
+  curl -sfo actual "http://127.0.0.1:$port/api/v0/refs?arg=$HASH2/test"
+'
+
 test_kill_ipfs_daemon
 
 test_done