-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathproxy.go
More file actions
77 lines (69 loc) · 2.29 KB
/
proxy.go
File metadata and controls
77 lines (69 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package blockchain
import (
"bytes"
"context"
"io"
"net"
"net/http"
"path"
)
const (
// ProxyListenAddr is the TCP address where go-fula listens for
// kubo-forwarded blockchain commands.
// Binds to all interfaces so that kubo containers in Docker bridge
// networking can reach the proxy via the Docker gateway IP.
ProxyListenAddr = "0.0.0.0:4020"
)
// StartProxy starts a TCP HTTP server on ProxyListenAddr that accepts
// blockchain commands forwarded by kubo's libp2p stream mounting.
// Requests are authenticated via signed headers (see auth_signed.go).
func (bl *FxBlockchain) StartProxy(ctx context.Context) error {
listener, err := net.Listen("tcp", ProxyListenAddr)
if err != nil {
return err
}
bl.proxyServer = &http.Server{Handler: http.HandlerFunc(bl.serveProxy)}
if bl.wg != nil {
log.Debug("called wg.Add in blockchain StartProxy")
bl.wg.Add(1)
}
go func() {
if bl.wg != nil {
log.Debug("called wg.Done in StartProxy blockchain")
defer bl.wg.Done()
}
defer log.Debug("StartProxy blockchain go routine is ending")
if err := bl.proxyServer.Serve(listener); err != http.ErrServerClosed {
log.Errorw("Proxy server stopped erroneously", "err", err)
}
}()
log.Infow("Blockchain proxy server started", "addr", ProxyListenAddr)
return nil
}
// serveProxy handles incoming requests on the TCP proxy server.
// It verifies signed headers, checks authorization, and dispatches the action.
func (bl *FxBlockchain) serveProxy(w http.ResponseWriter, r *http.Request) {
from, bodyBytes, err := verifySignedRequest(r)
if err != nil {
log.Errorw("proxy: signed request verification failed", "err", err)
http.Error(w, "", http.StatusUnauthorized)
return
}
action := path.Base(r.URL.Path)
if !bl.authorized(from, action) {
log.Errorw("proxy: rejected unauthorized request", "from", from, "action", action)
http.Error(w, "", http.StatusUnauthorized)
return
}
log.Debugw("proxy: action permitted", "action", action, "from", from)
// Restore the body so dispatch handlers can read it
r.Body = io.NopCloser(bytes.NewReader(bodyBytes))
bl.dispatch(from, action, w, r)
}
// ShutdownProxy gracefully shuts down the proxy server.
func (bl *FxBlockchain) ShutdownProxy(ctx context.Context) error {
if bl.proxyServer != nil {
return bl.proxyServer.Shutdown(ctx)
}
return nil
}