1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-05-22 01:17:11 +08:00
Files
kubo/core/corehttp/commands.go
Juan Batiz-Benet 3ee83a7c5e fix cors: defaults should take the port of the listener
need to do it this way to avoid VERY confusing situations where
the user would change the API port (to another port, or maybe even
to :0). this way things dont break on the user, and by default,
users only need to change the API address and things should still
"just work"

License: MIT
Signed-off-by: Juan Batiz-Benet <juan@benet.ai>
2015-08-02 08:16:51 +02:00

121 lines
3.3 KiB
Go

package corehttp
import (
"net"
"net/http"
"os"
"strconv"
"strings"
cors "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/rs/cors"
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 c.CORSOpts == nil {
c.CORSOpts.AllowedOrigins = []string{origin}
}
c.CORSOpts.AllowedOrigins = append(c.CORSOpts.AllowedOrigins, 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.CORSOpts.AllowedOrigins = acao
}
if acam := nc.API.HTTPHeaders[cmdsHttp.ACAMethods]; acam != nil {
c.CORSOpts.AllowedMethods = acam
}
if acac := nc.API.HTTPHeaders[cmdsHttp.ACACredentials]; acac != nil {
for _, v := range acac {
c.CORSOpts.AllowCredentials = (strings.ToLower(v) == "true")
}
}
c.Headers = nc.API.HTTPHeaders
}
func addCORSDefaults(c *cmdsHttp.ServerConfig) {
// by default use localhost origins
if len(c.CORSOpts.AllowedOrigins) == 0 {
c.CORSOpts.AllowedOrigins = defaultLocalhostOrigins
}
// by default, use GET, PUT, POST
if len(c.CORSOpts.AllowedMethods) == 0 {
c.CORSOpts.AllowedMethods = []string{"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...)
for i, o := range c.CORSOpts.AllowedOrigins {
// TODO: allow replacing <host>. tricky, ip4 and ip6 and hostnames...
if port != "" {
o = strings.Replace(o, "<port>", port, -1)
}
c.CORSOpts.AllowedOrigins[i] = o
}
}
func CommandsOption(cctx commands.Context) ServeOption {
return func(n *core.IpfsNode, l net.Listener, mux *http.ServeMux) (*http.ServeMux, error) {
cfg := &cmdsHttp.ServerConfig{
CORSOpts: &cors.Options{
AllowedMethods: []string{"GET", "POST", "PUT"},
},
}
addHeadersFromConfig(cfg, n.Repo.Config())
addCORSFromEnv(cfg)
addCORSDefaults(cfg)
patchCORSVars(cfg, l.Addr())
cmdHandler := cmdsHttp.NewHandler(cctx, corecommands.Root, cfg)
mux.Handle(cmdsHttp.ApiPath+"/", cmdHandler)
return mux, nil
}
}