1
1
package main
2
2
3
3
import (
4
+ "bufio"
4
5
"errors"
5
6
"flag"
6
7
"log"
@@ -17,13 +18,15 @@ import (
17
18
)
18
19
19
20
var (
20
- writable = flag .Bool ("writable" , false , "enable writing objects (with POST, PUT and DELETE)" )
21
- refreshAssetsInterval = flag .Duration ("refresh-assets-interval" , 30 * time .Second , "refresh assets" )
22
- garbageCollectInterval = flag .Duration ("gc-interval" , 24 * time .Hour , "frequency of repo garbage collection" )
23
- assetsPath = flag .String ("assets-path" , "" , "if provided, periodically adds contents of path to IPFS" )
24
- host = flag .String ("host" , "/ip4/0.0.0.0/tcp/8080" , "override the HTTP host listening address" )
25
- performGC = flag .Bool ("gc" , false , "perform garbage collection" )
26
- nBitsForKeypair = flag .Int ("b" , 1024 , "number of bits for keypair (if repo is uninitialized)" )
21
+ blocklistFilepath = flag .String ("blocklist" , "" , "keys that should not be served by the gateway" )
22
+ writable = flag .Bool ("writable" , false , "enable writing objects (with POST, PUT and DELETE)" )
23
+ refreshBlockListInterval = flag .Duration ("refresh-blocklist-interval" , 30 * time .Second , "refresh blocklist" )
24
+ refreshAssetsInterval = flag .Duration ("refresh-assets-interval" , 30 * time .Second , "refresh assets" )
25
+ garbageCollectInterval = flag .Duration ("gc-interval" , 24 * time .Hour , "frequency of repo garbage collection" )
26
+ assetsPath = flag .String ("assets-path" , "" , "if provided, periodically adds contents of path to IPFS" )
27
+ host = flag .String ("host" , "/ip4/0.0.0.0/tcp/8080" , "override the HTTP host listening address" )
28
+ performGC = flag .Bool ("gc" , false , "perform garbage collection" )
29
+ nBitsForKeypair = flag .Int ("b" , 1024 , "number of bits for keypair (if repo is uninitialized)" )
27
30
)
28
31
29
32
func main () {
@@ -77,8 +80,18 @@ func run() error {
77
80
}
78
81
}
79
82
83
+ blocklist := & corehttp.BlockList {}
84
+ gateway := corehttp .NewGateway (corehttp.GatewayConfig {
85
+ Writable : * writable ,
86
+ BlockList : blocklist ,
87
+ })
88
+
89
+ if err := runBlockListWorker (blocklist , * blocklistFilepath ); err != nil {
90
+ return err
91
+ }
92
+
80
93
opts := []corehttp.ServeOption {
81
- corehttp . GatewayOption ( * writable ),
94
+ gateway . ServeOption ( ),
82
95
}
83
96
return corehttp .ListenAndServe (node , * host , opts ... )
84
97
}
@@ -112,3 +125,41 @@ func runFileServerWorker(ctx context.Context, node *core.IpfsNode) error {
112
125
}()
113
126
return nil
114
127
}
128
+
129
+ func runBlockListWorker (blocklist * corehttp.BlockList , filepath string ) error {
130
+ if filepath == "" {
131
+ return nil
132
+ }
133
+ go func () {
134
+ for _ = range time .Tick (* refreshBlockListInterval ) {
135
+ log .Println ("updating the blocklist..." )
136
+ func () { // in a func to allow defer f.Close()
137
+ f , err := os .Open (filepath )
138
+ if err != nil {
139
+ log .Println (err )
140
+ }
141
+ defer f .Close ()
142
+ scanner := bufio .NewScanner (f )
143
+ blocked := make (map [string ]struct {}) // Implement using Bloom Filter hybrid if blocklist gets large
144
+ for scanner .Scan () {
145
+ t := scanner .Text ()
146
+ blocked [t ] = struct {}{}
147
+ }
148
+
149
+ // If an error occurred, do not change the existing decider. This
150
+ // is to avoid accidentally clearing the list if the deploy is
151
+ // botched.
152
+ if err := scanner .Err (); err != nil {
153
+ log .Println (err )
154
+ } else {
155
+ blocklist .SetDecider (func (s string ) bool {
156
+ _ , ok := blocked [s ]
157
+ return ! ok
158
+ })
159
+ log .Printf ("updated the blocklist (%d entries)" , len (blocked ))
160
+ }
161
+ }()
162
+ }
163
+ }()
164
+ return nil
165
+ }
0 commit comments