feat(corehttp) add a Gateway blocklist

use pointer

use func

comment on decider to clarify whether it allows or denies

fix set conf

gstw
This commit is contained in:
Brian Tiger Chow 2015-02-03 15:48:10 -08:00
parent 4c920d0281
commit d50a7ff003
2 changed files with 71 additions and 9 deletions

View File

@ -2,13 +2,30 @@ package corehttp
import (
"net/http"
"sync"
core "github.com/jbenet/go-ipfs/core"
)
func GatewayOption(writable bool) ServeOption {
// Gateway should be instantiated using NewGateway
type Gateway struct {
Config GatewayConfig
}
type GatewayConfig struct {
BlockList *BlockList
Writable bool
}
func NewGateway(conf GatewayConfig) *Gateway {
return &Gateway{
Config: conf,
}
}
func (g *Gateway) ServeOption() ServeOption {
return func(n *core.IpfsNode, mux *http.ServeMux) error {
gateway, err := newGatewayHandler(n, writable)
gateway, err := newGatewayHandler(n, g.Config)
if err != nil {
return err
}
@ -17,3 +34,41 @@ func GatewayOption(writable bool) ServeOption {
return nil
}
}
func GatewayOption(writable bool) ServeOption {
g := NewGateway(GatewayConfig{
Writable: writable,
BlockList: &BlockList{},
})
return g.ServeOption()
}
// Decider decides whether to Allow string
type Decider func(string) bool
type BlockList struct {
mu sync.RWMutex
d Decider
}
func (b *BlockList) ShouldAllow(s string) bool {
b.mu.RLock()
d := b.d
b.mu.RUnlock()
if d == nil {
return true
}
return d(s)
}
// SetDecider atomically swaps the blocklist's decider
func (b *BlockList) SetDecider(d Decider) {
b.mu.Lock()
b.d = d
b.mu.Unlock()
}
func (b *BlockList) ShouldBlock(s string) bool {
return !b.ShouldAllow(s)
}

View File

@ -50,13 +50,13 @@ type directoryItem struct {
type gatewayHandler struct {
node *core.IpfsNode
dirList *template.Template
writable bool
config GatewayConfig
}
func newGatewayHandler(node *core.IpfsNode, writable bool) (*gatewayHandler, error) {
func newGatewayHandler(node *core.IpfsNode, conf GatewayConfig) (*gatewayHandler, error) {
i := &gatewayHandler{
node: node,
writable: writable,
config: conf,
}
err := i.loadTemplate()
if err != nil {
@ -125,18 +125,20 @@ func (i *gatewayHandler) NewDagReader(nd *dag.Node) (uio.ReadSeekCloser, error)
return uio.NewDagReader(i.node.Context(), nd, i.node.DAG)
}
// TODO(btc): break this apart into separate handlers using a more expressive
// muxer
func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if i.writable && r.Method == "POST" {
if i.config.Writable && r.Method == "POST" {
i.postHandler(w, r)
return
}
if i.writable && r.Method == "PUT" {
if i.config.Writable && r.Method == "PUT" {
i.putHandler(w, r)
return
}
if i.writable && r.Method == "DELETE" {
if i.config.Writable && r.Method == "DELETE" {
i.deleteHandler(w, r)
return
}
@ -147,7 +149,7 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
errmsg := "Method " + r.Method + " not allowed: "
if !i.writable {
if !i.config.Writable {
w.WriteHeader(http.StatusMethodNotAllowed)
errmsg = errmsg + "read only access"
} else {
@ -164,6 +166,11 @@ func (i *gatewayHandler) getHandler(w http.ResponseWriter, r *http.Request) {
urlPath := r.URL.Path
if i.config.BlockList != nil && i.config.BlockList.ShouldBlock(urlPath) {
w.WriteHeader(http.StatusNotFound)
return
}
nd, p, err := i.ResolvePath(ctx, urlPath)
if err != nil {
if err == routing.ErrNotFound {