@cryptotaxi247 / kubo / commits / d50a7ff00

feat(corehttp) add a Gateway blocklist

use pointer use func comment on decider to clarify whether it allows or denies fix set conf gstw

Brian Tiger Chow committed Feb 3, 2015 at 15:48 UTC d50a7ff0037b2fb6d787cf6fb1c3d14a429b1ea0
2 files changed +71 -9
core/corehttp/gateway.go
+57 -2
@@ -2,13 +2,30 @@ package corehttp
2
3 import (
4 "net/http"
5 + "sync"
6
7 core "github.com/jbenet/go-ipfs/core"
8 )
9
9 -func GatewayOption(writable bool) ServeOption {
10 +// Gateway should be instantiated using NewGateway
11 +type Gateway struct {
12 + Config GatewayConfig
13 +}
14 +
15 +type GatewayConfig struct {
16 + BlockList *BlockList
17 + Writable bool
18 +}
19 +
20 +func NewGateway(conf GatewayConfig) *Gateway {
21 + return &Gateway{
22 + Config: conf,
23 + }
24 +}
25 +
26 +func (g *Gateway) ServeOption() ServeOption {
27 return func(n *core.IpfsNode, mux *http.ServeMux) error {
11 - gateway, err := newGatewayHandler(n, writable)
28 + gateway, err := newGatewayHandler(n, g.Config)
29 if err != nil {
30 return err
31 }
@@ -17,3 +34,41 @@ func GatewayOption(writable bool) ServeOption {
34 return nil
35 }
36 }
37 +
38 +func GatewayOption(writable bool) ServeOption {
39 + g := NewGateway(GatewayConfig{
40 + Writable: writable,
41 + BlockList: &BlockList{},
42 + })
43 + return g.ServeOption()
44 +}
45 +
46 +// Decider decides whether to Allow string
47 +type Decider func(string) bool
48 +
49 +type BlockList struct {
50 +
51 + mu sync.RWMutex
52 + d Decider
53 +}
54 +
55 +func (b *BlockList) ShouldAllow(s string) bool {
56 + b.mu.RLock()
57 + d := b.d
58 + b.mu.RUnlock()
59 + if d == nil {
60 + return true
61 + }
62 + return d(s)
63 +}
64 +
65 +// SetDecider atomically swaps the blocklist's decider
66 +func (b *BlockList) SetDecider(d Decider) {
67 + b.mu.Lock()
68 + b.d = d
69 + b.mu.Unlock()
70 +}
71 +
72 +func (b *BlockList) ShouldBlock(s string) bool {
73 + return !b.ShouldAllow(s)
74 +}
core/corehttp/gateway_handler.go
+14 -7
@@ -50,13 +50,13 @@ type directoryItem struct {
50 type gatewayHandler struct {
51 node *core.IpfsNode
52 dirList *template.Template
53 - writable bool
53 + config GatewayConfig
54 }
55
56 -func newGatewayHandler(node *core.IpfsNode, writable bool) (*gatewayHandler, error) {
56 +func newGatewayHandler(node *core.IpfsNode, conf GatewayConfig) (*gatewayHandler, error) {
57 i := &gatewayHandler{
58 node: node,
59 - writable: writable,
59 + config: conf,
60 }
61 err := i.loadTemplate()
62 if err != nil {
@@ -125,18 +125,20 @@ func (i *gatewayHandler) NewDagReader(nd *dag.Node) (uio.ReadSeekCloser, error)
125 return uio.NewDagReader(i.node.Context(), nd, i.node.DAG)
126 }
127
128 +// TODO(btc): break this apart into separate handlers using a more expressive
129 +// muxer
130 func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
129 - if i.writable && r.Method == "POST" {
131 + if i.config.Writable && r.Method == "POST" {
132 i.postHandler(w, r)
133 return
134 }
135
134 - if i.writable && r.Method == "PUT" {
136 + if i.config.Writable && r.Method == "PUT" {
137 i.putHandler(w, r)
138 return
139 }
140
139 - if i.writable && r.Method == "DELETE" {
141 + if i.config.Writable && r.Method == "DELETE" {
142 i.deleteHandler(w, r)
143 return
144 }
@@ -147,7 +149,7 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
149 }
150
151 errmsg := "Method " + r.Method + " not allowed: "
150 - if !i.writable {
152 + if !i.config.Writable {
153 w.WriteHeader(http.StatusMethodNotAllowed)
154 errmsg = errmsg + "read only access"
155 } else {
@@ -164,6 +166,11 @@ func (i *gatewayHandler) getHandler(w http.ResponseWriter, r *http.Request) {
166
167 urlPath := r.URL.Path
168
169 + if i.config.BlockList != nil && i.config.BlockList.ShouldBlock(urlPath) {
170 + w.WriteHeader(http.StatusNotFound)
171 + return
172 + }
173 +
174 nd, p, err := i.ResolvePath(ctx, urlPath)
175 if err != nil {
176 if err == routing.ErrNotFound {