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

This commit is contained in:
Mildred Ki'Lya 2015-01-28 12:57:09 +01:00
parent d221d55d85
commit 7d09da3c8b
7 changed files with 49 additions and 20 deletions

View File

@ -17,6 +17,7 @@ import (
)
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")
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")
@ -93,7 +94,7 @@ func run() error {
}
opts := []corehttp.ServeOption{
corehttp.GatewayOption,
corehttp.GatewayOption(*writable),
}
if err := corehttp.ListenAndServe(node, *host, opts...); err != nil {
return err

View File

@ -2,6 +2,7 @@ package main
import (
"bytes"
"fmt"
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
cmds "github.com/jbenet/go-ipfs/commands"
@ -15,6 +16,7 @@ import (
const (
initOptionKwd = "init"
mountKwd = "mount"
writableKwd = "writable"
ipfsMountKwd = "mount-ipfs"
ipnsMountKwd = "mount-ipns"
// apiAddrKwd = "address-api"
@ -36,6 +38,7 @@ the daemon.
Options: []cmds.Option{
cmds.BoolOption(initOptionKwd, "Initialize IPFS with default settings if not already initialized"),
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(ipnsMountKwd, "Path to the mountpoint for IPNS (if using --mount)"),
@ -161,9 +164,22 @@ func daemonFunc(req cmds.Request, res cmds.Response) {
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 {
go func() {
var opts = []corehttp.ServeOption{corehttp.GatewayOption}
var opts = []corehttp.ServeOption{corehttp.GatewayOption(writable)}
if rootRedirect != nil {
opts = append(opts, rootRedirect)
}
@ -177,7 +193,7 @@ func daemonFunc(req cmds.Request, res cmds.Response) {
var opts = []corehttp.ServeOption{
corehttp.CommandsOption(*req.Context()),
corehttp.WebUIOption,
corehttp.GatewayOption,
corehttp.GatewayOption(true),
}
if rootRedirect != nil {
opts = append(opts, rootRedirect)

View File

@ -80,7 +80,7 @@ func run(ipfsPath, watchPath string) error {
if *http {
addr := "/ip4/127.0.0.1/tcp/5001"
var opts = []corehttp.ServeOption{
corehttp.GatewayOption,
corehttp.GatewayOption(true),
corehttp.WebUIOption,
corehttp.CommandsOption(cmdCtx(node, ipfsPath)),
}

View File

@ -6,12 +6,14 @@ import (
core "github.com/jbenet/go-ipfs/core"
)
func GatewayOption(n *core.IpfsNode, mux *http.ServeMux) error {
gateway, err := newGatewayHandler(n)
if err != nil {
return err
}
mux.Handle("/ipfs/", gateway)
func GatewayOption(writable bool) ServeOption {
return func(n *core.IpfsNode, mux *http.ServeMux) error {
gateway, err := newGatewayHandler(n, writable)
if err != nil {
return err
}
mux.Handle("/ipfs/", gateway)
mux.Handle("/ipns/", gateway)
return nil
return nil
}
}

View File

@ -48,13 +48,15 @@ type directoryItem struct {
// gatewayHandler is a HTTP handler that serves IPFS objects (accessible by default at /ipfs/<path>)
// (it serves requests like GET /ipfs/QmVRzPKPzNtSrEzBFm2UZfxmPAgnaLke4DMcerbsGGSaFe/link)
type gatewayHandler struct {
node *core.IpfsNode
dirList *template.Template
node *core.IpfsNode
dirList *template.Template
writable bool
}
func newGatewayHandler(node *core.IpfsNode) (*gatewayHandler, error) {
func newGatewayHandler(node *core.IpfsNode, writable bool) (*gatewayHandler, error) {
i := &gatewayHandler{
node: node,
node: node,
writable: writable,
}
err := i.loadTemplate()
if err != nil {
@ -116,17 +118,17 @@ func (i *gatewayHandler) NewDagReader(nd *dag.Node) (uio.ReadSeekCloser, error)
}
func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
if i.writable && r.Method == "POST" {
i.postHandler(w, r)
return
}
if r.Method == "PUT" {
if i.writable && r.Method == "PUT" {
i.putHandler(w, r)
return
}
if r.Method == "DELETE" {
if i.writable && r.Method == "DELETE" {
i.deleteHandler(w, r)
return
}
@ -136,8 +138,14 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
errmsg := "Method " + r.Method + " not allowed: " + "bad request for " + r.URL.Path
w.WriteHeader(http.StatusBadRequest)
errmsg := "Method " + r.Method + " not allowed: "
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))
log.Error(errmsg)
}

View File

@ -3,4 +3,5 @@ package config
// Gateway contains options for the HTTP gateway server.
type Gateway struct {
RootRedirect string
Writable bool
}

View File

@ -54,6 +54,7 @@ func Init(out io.Writer, nBitsForKeypair int) (*Config, error) {
Gateway: Gateway{
RootRedirect: "",
Writable: false,
},
}