Skip to content

Commit

Permalink
http endpoints: dont print before listen
Browse files Browse the repository at this point in the history
  • Loading branch information
cryptix committed May 30, 2015
1 parent 5d43ebb commit d8c11a5
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 80 deletions.
171 changes: 98 additions & 73 deletions cmd/ipfs/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ package main
import (
_ "expvar"
"fmt"
_ "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/codahale/metrics/runtime"
"net/http"
_ "net/http/pprof"
"os"
"strings"

_ "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/codahale/metrics/runtime"
ma "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"

cmds "github.com/ipfs/go-ipfs/commands"
"github.com/ipfs/go-ipfs/core"
commands "github.com/ipfs/go-ipfs/core/commands"
Expand Down Expand Up @@ -192,13 +194,64 @@ func daemonFunc(req cmds.Request, res cmds.Response) {
return node, nil
}

// verify api address is valid multiaddr
// construct api endpoint
apiMaddr, err := ma.NewMultiaddr(cfg.Addresses.API)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}

apiLis, err := manet.Listen(apiMaddr)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
// we might have listened to /tcp/0 - lets see what we are listing on
apiMaddr = apiLis.Multiaddr()
fmt.Printf("API server listening on %s\n", apiMaddr)

apiGw := corehttp.NewGateway(corehttp.GatewayConfig{
Writable: true,
BlockList: &corehttp.BlockList{
Decider: func(s string) bool {
unrestricted, _, _ := req.Option(unrestrictedApiAccess).Bool()
if unrestricted {
return true
}
// for now, only allow paths in the WebUI path
for _, webuipath := range corehttp.WebUIPaths {
if strings.HasPrefix(s, webuipath) {
return true
}
}
return false
},
},
})
var opts = []corehttp.ServeOption{
corehttp.CommandsOption(*req.Context()),
corehttp.WebUIOption,
apiGw.ServeOption(),
corehttp.VersionOption(),
defaultMux("/debug/vars"),
defaultMux("/debug/pprof/"),
}

var rootRedirect corehttp.ServeOption
if len(cfg.Gateway.RootRedirect) > 0 {
rootRedirect = corehttp.RedirectOption("", cfg.Gateway.RootRedirect)
}

if rootRedirect != nil {
opts = append(opts, rootRedirect)
}

errc := make(chan error)
go func() {
errc <- corehttp.Serve(node, apiLis.NetListener(), opts...)
}()

// construct http gateway
var gatewayMaddr ma.Multiaddr
if len(cfg.Addresses.Gateway) > 0 {
// ignore error for gateway address
Expand All @@ -209,7 +262,44 @@ func daemonFunc(req cmds.Request, res cmds.Response) {
}
}

// mount if the user provided the --mount flag
writable, writableOptionFound, err := req.Option(writableKwd).Bool()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
if !writableOptionFound {
writable = cfg.Gateway.Writable
}

if gatewayMaddr != nil {

gwLis, err := manet.Listen(gatewayMaddr)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
// we might have listened to /tcp/0 - lets see what we are listing on
gatewayMaddr = gwLis.Multiaddr()

if writable {
fmt.Printf("Gateway (writable) server listening on %s\n", gatewayMaddr)
} else {
fmt.Printf("Gateway (readonly) server listening on %s\n", gatewayMaddr)
}
var opts = []corehttp.ServeOption{
corehttp.VersionOption(),
corehttp.IPNSHostnameOption(),
corehttp.GatewayOption(writable),
}
if rootRedirect != nil {
opts = append(opts, rootRedirect)
}
go func() {
errc <- corehttp.Serve(node, gwLis.NetListener(), opts...)
}()
}

// mount fuse if the user provided the --mount flag
mount, _, err := req.Option(mountKwd).Bool()
if err != nil {
res.SetError(err, cmds.ErrNormal)
Expand Down Expand Up @@ -243,75 +333,10 @@ func daemonFunc(req cmds.Request, res cmds.Response) {
fmt.Printf("IPNS mounted at: %s\n", nsdir)
}

var rootRedirect corehttp.ServeOption
if len(cfg.Gateway.RootRedirect) > 0 {
rootRedirect = corehttp.RedirectOption("", cfg.Gateway.RootRedirect)
}

writable, writableOptionFound, err := req.Option(writableKwd).Bool()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
if !writableOptionFound {
writable = cfg.Gateway.Writable
}

if gatewayMaddr != nil {
go func() {
var opts = []corehttp.ServeOption{
corehttp.VersionOption(),
corehttp.IPNSHostnameOption(),
corehttp.GatewayOption(writable),
}
if rootRedirect != nil {
opts = append(opts, rootRedirect)
}
if writable {
fmt.Printf("Gateway (writable) server listening on %s\n", gatewayMaddr)
} else {
fmt.Printf("Gateway (readonly) server listening on %s\n", gatewayMaddr)
}
err := corehttp.ListenAndServe(node, gatewayMaddr.String(), opts...)
if err != nil {
log.Error(err)
}
}()
}

gateway := corehttp.NewGateway(corehttp.GatewayConfig{
Writable: true,
BlockList: &corehttp.BlockList{
Decider: func(s string) bool {
unrestricted, _, _ := req.Option(unrestrictedApiAccess).Bool()
if unrestricted {
return true
}
// for now, only allow paths in the WebUI path
for _, webuipath := range corehttp.WebUIPaths {
if strings.HasPrefix(s, webuipath) {
return true
}
}
return false
},
},
})
var opts = []corehttp.ServeOption{
corehttp.CommandsOption(*req.Context()),
corehttp.WebUIOption,
gateway.ServeOption(),
corehttp.VersionOption(),
defaultMux("/debug/vars"),
defaultMux("/debug/pprof/"),
}

if rootRedirect != nil {
opts = append(opts, rootRedirect)
}
fmt.Printf("API server listening on %s\n", apiMaddr)
if err := corehttp.ListenAndServe(node, apiMaddr.String(), opts...); err != nil {
res.SetError(err, cmds.ErrNormal)
return
for err := range errc {
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
}
}
21 changes: 14 additions & 7 deletions core/corehttp/corehttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ high-level HTTP interfaces to IPFS.
package corehttp

import (
"fmt"
"net"
"net/http"
"time"
Expand Down Expand Up @@ -49,20 +50,26 @@ func ListenAndServe(n *core.IpfsNode, listeningMultiAddr string, options ...Serv
if err != nil {
return err
}
handler, err := makeHandler(n, options...)

list, err := manet.Listen(addr)
if err != nil {
return err
}
return listenAndServe(n, addr, handler)

// we might have listened to /tcp/0 - lets see what we are listing on
addr = list.Multiaddr()
fmt.Printf("API server listening on %s\n", addr)

return Serve(n, list.NetListener(), options...)
}

func listenAndServe(node *core.IpfsNode, addr ma.Multiaddr, handler http.Handler) error {
netarg, host, err := manet.DialArgs(addr)
func Serve(node *core.IpfsNode, lis net.Listener, options ...ServeOption) error {
handler, err := makeHandler(node, options...)
if err != nil {
return err
}

list, err := net.Listen(netarg, host)
addr, err := manet.FromNetAddr(lis.Addr())
if err != nil {
return err
}
Expand All @@ -75,7 +82,7 @@ func listenAndServe(node *core.IpfsNode, addr ma.Multiaddr, handler http.Handler
defer node.Children().Done()

go func() {
serverError = http.Serve(list, handler)
serverError = http.Serve(lis, handler)
close(serverExited)
}()

Expand All @@ -87,7 +94,7 @@ func listenAndServe(node *core.IpfsNode, addr ma.Multiaddr, handler http.Handler
case <-node.Closing():
log.Infof("server at %s terminating...", addr)

list.Close()
lis.Close()

outer:
for {
Expand Down

0 comments on commit d8c11a5

Please sign in to comment.