提交 7d09da3c 作者: Mildred Ki'Lya

Make gateway read-only by default and add option to make it writable

上级 d221d55d
...@@ -17,6 +17,7 @@ import ( ...@@ -17,6 +17,7 @@ import (
) )
var ( var (
writable = flag.Bool("writable", false, "enable writing objects (with POST, PUT and DELETE)")
refreshAssetsInterval = flag.Duration("refresh-assets-interval", 30*time.Second, "refresh assets") refreshAssetsInterval = flag.Duration("refresh-assets-interval", 30*time.Second, "refresh assets")
garbageCollectInterval = flag.Duration("gc-interval", 24*time.Hour, "frequency of repo garbage collection") garbageCollectInterval = flag.Duration("gc-interval", 24*time.Hour, "frequency of repo garbage collection")
assetsPath = flag.String("assets-path", "", "if provided, periodically adds contents of path to IPFS") assetsPath = flag.String("assets-path", "", "if provided, periodically adds contents of path to IPFS")
...@@ -93,7 +94,7 @@ func run() error { ...@@ -93,7 +94,7 @@ func run() error {
} }
opts := []corehttp.ServeOption{ opts := []corehttp.ServeOption{
corehttp.GatewayOption, corehttp.GatewayOption(*writable),
} }
if err := corehttp.ListenAndServe(node, *host, opts...); err != nil { if err := corehttp.ListenAndServe(node, *host, opts...); err != nil {
return err return err
......
...@@ -2,6 +2,7 @@ package main ...@@ -2,6 +2,7 @@ package main
import ( import (
"bytes" "bytes"
"fmt"
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
cmds "github.com/jbenet/go-ipfs/commands" cmds "github.com/jbenet/go-ipfs/commands"
...@@ -15,6 +16,7 @@ import ( ...@@ -15,6 +16,7 @@ import (
const ( const (
initOptionKwd = "init" initOptionKwd = "init"
mountKwd = "mount" mountKwd = "mount"
writableKwd = "writable"
ipfsMountKwd = "mount-ipfs" ipfsMountKwd = "mount-ipfs"
ipnsMountKwd = "mount-ipns" ipnsMountKwd = "mount-ipns"
// apiAddrKwd = "address-api" // apiAddrKwd = "address-api"
...@@ -36,6 +38,7 @@ the daemon. ...@@ -36,6 +38,7 @@ the daemon.
Options: []cmds.Option{ Options: []cmds.Option{
cmds.BoolOption(initOptionKwd, "Initialize IPFS with default settings if not already initialized"), cmds.BoolOption(initOptionKwd, "Initialize IPFS with default settings if not already initialized"),
cmds.BoolOption(mountKwd, "Mounts IPFS to the filesystem"), cmds.BoolOption(mountKwd, "Mounts IPFS to the filesystem"),
cmds.BoolOption(writableKwd, "Enable writing objects (with POST, PUT and DELETE)"),
cmds.StringOption(ipfsMountKwd, "Path to the mountpoint for IPFS (if using --mount)"), cmds.StringOption(ipfsMountKwd, "Path to the mountpoint for IPFS (if using --mount)"),
cmds.StringOption(ipnsMountKwd, "Path to the mountpoint for IPNS (if using --mount)"), cmds.StringOption(ipnsMountKwd, "Path to the mountpoint for IPNS (if using --mount)"),
...@@ -161,9 +164,22 @@ func daemonFunc(req cmds.Request, res cmds.Response) { ...@@ -161,9 +164,22 @@ func daemonFunc(req cmds.Request, res cmds.Response) {
rootRedirect = corehttp.RedirectOption("", cfg.Gateway.RootRedirect) rootRedirect = corehttp.RedirectOption("", cfg.Gateway.RootRedirect)
} }
writable, writableOptionFound, err := req.Option(writableKwd).Bool()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
if !writableOptionFound {
writable = cfg.Gateway.Writable
}
if writable {
fmt.Printf("IPNS gateway mounted read-write\n")
}
if gatewayMaddr != nil { if gatewayMaddr != nil {
go func() { go func() {
var opts = []corehttp.ServeOption{corehttp.GatewayOption} var opts = []corehttp.ServeOption{corehttp.GatewayOption(writable)}
if rootRedirect != nil { if rootRedirect != nil {
opts = append(opts, rootRedirect) opts = append(opts, rootRedirect)
} }
...@@ -177,7 +193,7 @@ func daemonFunc(req cmds.Request, res cmds.Response) { ...@@ -177,7 +193,7 @@ func daemonFunc(req cmds.Request, res cmds.Response) {
var opts = []corehttp.ServeOption{ var opts = []corehttp.ServeOption{
corehttp.CommandsOption(*req.Context()), corehttp.CommandsOption(*req.Context()),
corehttp.WebUIOption, corehttp.WebUIOption,
corehttp.GatewayOption, corehttp.GatewayOption(true),
} }
if rootRedirect != nil { if rootRedirect != nil {
opts = append(opts, rootRedirect) opts = append(opts, rootRedirect)
......
...@@ -80,7 +80,7 @@ func run(ipfsPath, watchPath string) error { ...@@ -80,7 +80,7 @@ func run(ipfsPath, watchPath string) error {
if *http { if *http {
addr := "/ip4/127.0.0.1/tcp/5001" addr := "/ip4/127.0.0.1/tcp/5001"
var opts = []corehttp.ServeOption{ var opts = []corehttp.ServeOption{
corehttp.GatewayOption, corehttp.GatewayOption(true),
corehttp.WebUIOption, corehttp.WebUIOption,
corehttp.CommandsOption(cmdCtx(node, ipfsPath)), corehttp.CommandsOption(cmdCtx(node, ipfsPath)),
} }
......
...@@ -6,12 +6,14 @@ import ( ...@@ -6,12 +6,14 @@ import (
core "github.com/jbenet/go-ipfs/core" core "github.com/jbenet/go-ipfs/core"
) )
func GatewayOption(n *core.IpfsNode, mux *http.ServeMux) error { func GatewayOption(writable bool) ServeOption {
gateway, err := newGatewayHandler(n) return func(n *core.IpfsNode, mux *http.ServeMux) error {
if err != nil { gateway, err := newGatewayHandler(n, writable)
return err if err != nil {
} return err
mux.Handle("/ipfs/", gateway) }
mux.Handle("/ipfs/", gateway)
mux.Handle("/ipns/", gateway) mux.Handle("/ipns/", gateway)
return nil return nil
}
} }
...@@ -48,13 +48,15 @@ type directoryItem struct { ...@@ -48,13 +48,15 @@ type directoryItem struct {
// gatewayHandler is a HTTP handler that serves IPFS objects (accessible by default at /ipfs/<path>) // gatewayHandler is a HTTP handler that serves IPFS objects (accessible by default at /ipfs/<path>)
// (it serves requests like GET /ipfs/QmVRzPKPzNtSrEzBFm2UZfxmPAgnaLke4DMcerbsGGSaFe/link) // (it serves requests like GET /ipfs/QmVRzPKPzNtSrEzBFm2UZfxmPAgnaLke4DMcerbsGGSaFe/link)
type gatewayHandler struct { type gatewayHandler struct {
node *core.IpfsNode node *core.IpfsNode
dirList *template.Template dirList *template.Template
writable bool
} }
func newGatewayHandler(node *core.IpfsNode) (*gatewayHandler, error) { func newGatewayHandler(node *core.IpfsNode, writable bool) (*gatewayHandler, error) {
i := &gatewayHandler{ i := &gatewayHandler{
node: node, node: node,
writable: writable,
} }
err := i.loadTemplate() err := i.loadTemplate()
if err != nil { if err != nil {
...@@ -116,17 +118,17 @@ func (i *gatewayHandler) NewDagReader(nd *dag.Node) (uio.ReadSeekCloser, error) ...@@ -116,17 +118,17 @@ func (i *gatewayHandler) NewDagReader(nd *dag.Node) (uio.ReadSeekCloser, error)
} }
func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" { if i.writable && r.Method == "POST" {
i.postHandler(w, r) i.postHandler(w, r)
return return
} }
if r.Method == "PUT" { if i.writable && r.Method == "PUT" {
i.putHandler(w, r) i.putHandler(w, r)
return return
} }
if r.Method == "DELETE" { if i.writable && r.Method == "DELETE" {
i.deleteHandler(w, r) i.deleteHandler(w, r)
return return
} }
...@@ -136,8 +138,14 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { ...@@ -136,8 +138,14 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return return
} }
errmsg := "Method " + r.Method + " not allowed: " + "bad request for " + r.URL.Path errmsg := "Method " + r.Method + " not allowed: "
w.WriteHeader(http.StatusBadRequest) if !i.writable {
w.WriteHeader(http.StatusMethodNotAllowed)
errmsg = errmsg + "read only access"
} else {
w.WriteHeader(http.StatusBadRequest)
errmsg = errmsg + "bad request for " + r.URL.Path
}
w.Write([]byte(errmsg)) w.Write([]byte(errmsg))
log.Error(errmsg) log.Error(errmsg)
} }
......
...@@ -3,4 +3,5 @@ package config ...@@ -3,4 +3,5 @@ package config
// Gateway contains options for the HTTP gateway server. // Gateway contains options for the HTTP gateway server.
type Gateway struct { type Gateway struct {
RootRedirect string RootRedirect string
Writable bool
} }
...@@ -54,6 +54,7 @@ func Init(out io.Writer, nBitsForKeypair int) (*Config, error) { ...@@ -54,6 +54,7 @@ func Init(out io.Writer, nBitsForKeypair int) (*Config, error) {
Gateway: Gateway{ Gateway: Gateway{
RootRedirect: "", RootRedirect: "",
Writable: false,
}, },
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论