forked from ipfs/kubo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
commands.go
129 lines (107 loc) · 3.41 KB
/
commands.go
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package corehttp
import (
"net"
"net/http"
"os"
"strconv"
"strings"
commands "github.com/ipfs/go-ipfs/commands"
cmdsHttp "github.com/ipfs/go-ipfs/commands/http"
core "github.com/ipfs/go-ipfs/core"
corecommands "github.com/ipfs/go-ipfs/core/commands"
config "github.com/ipfs/go-ipfs/repo/config"
)
const originEnvKey = "API_ORIGIN"
const originEnvKeyDeprecate = `You are using the ` + originEnvKey + `ENV Variable.
This functionality is deprecated, and will be removed in future versions.
Instead, try either adding headers to the config, or passing them via
cli arguments:
ipfs config API.HTTPHeaders 'Access-Control-Allow-Origin' '*'
ipfs daemon
or
ipfs daemon --api-http-header 'Access-Control-Allow-Origin: *'
`
var defaultLocalhostOrigins = []string{
"http://127.0.0.1:<port>",
"https://127.0.0.1:<port>",
"http://localhost:<port>",
"https://localhost:<port>",
}
func addCORSFromEnv(c *cmdsHttp.ServerConfig) {
origin := os.Getenv(originEnvKey)
if origin != "" {
log.Warning(originEnvKeyDeprecate)
if len(c.AllowedOrigins()) == 0 {
c.SetAllowedOrigins([]string{origin}...)
}
c.AppendAllowedOrigins(origin)
}
}
func addHeadersFromConfig(c *cmdsHttp.ServerConfig, nc *config.Config) {
log.Info("Using API.HTTPHeaders:", nc.API.HTTPHeaders)
if acao := nc.API.HTTPHeaders[cmdsHttp.ACAOrigin]; acao != nil {
c.SetAllowedOrigins(acao...)
}
if acam := nc.API.HTTPHeaders[cmdsHttp.ACAMethods]; acam != nil {
c.SetAllowedMethods(acam...)
}
if acac := nc.API.HTTPHeaders[cmdsHttp.ACACredentials]; acac != nil {
for _, v := range acac {
c.SetAllowCredentials(strings.ToLower(v) == "true")
}
}
c.Headers = nc.API.HTTPHeaders
}
func addCORSDefaults(c *cmdsHttp.ServerConfig) {
// by default use localhost origins
if len(c.AllowedOrigins()) == 0 {
c.SetAllowedOrigins(defaultLocalhostOrigins...)
}
// by default, use GET, PUT, POST
if len(c.AllowedMethods()) == 0 {
c.SetAllowedMethods("GET", "POST", "PUT")
}
}
func patchCORSVars(c *cmdsHttp.ServerConfig, addr net.Addr) {
// we have to grab the port from an addr, which may be an ip6 addr.
// TODO: this should take multiaddrs and derive port from there.
port := ""
if tcpaddr, ok := addr.(*net.TCPAddr); ok {
port = strconv.Itoa(tcpaddr.Port)
} else if udpaddr, ok := addr.(*net.UDPAddr); ok {
port = strconv.Itoa(udpaddr.Port)
}
// we're listening on tcp/udp with ports. ("udp!?" you say? yeah... it happens...)
origins := c.AllowedOrigins()
for i, o := range origins {
// TODO: allow replacing <host>. tricky, ip4 and ip6 and hostnames...
if port != "" {
o = strings.Replace(o, "<port>", port, -1)
}
origins[i] = o
}
c.SetAllowedOrigins(origins...)
}
func commandsOption(cctx commands.Context, command *commands.Command) ServeOption {
return func(n *core.IpfsNode, l net.Listener, mux *http.ServeMux) (*http.ServeMux, error) {
cfg := cmdsHttp.NewServerConfig()
cfg.SetAllowedMethods("GET", "POST", "PUT")
rcfg, err := n.Repo.Config()
if err != nil {
return nil, err
}
addHeadersFromConfig(cfg, rcfg)
addCORSFromEnv(cfg)
addCORSDefaults(cfg)
patchCORSVars(cfg, l.Addr())
cmdHandler := cmdsHttp.NewHandler(cctx, command, cfg)
mux.Handle(cmdsHttp.ApiPath+"/", cmdHandler)
return mux, nil
}
}
func CommandsOption(cctx commands.Context) ServeOption {
return commandsOption(cctx, corecommands.Root)
}
func CommandsROOption(cctx commands.Context) ServeOption {
return commandsOption(cctx, corecommands.RootRO)
}