mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-23 19:37:46 +08:00
Each option now additionally returns the mux to be used by future options. If
every options returns the mux it was passed, the current behavior is unchanged.
However, if the option returns an a new mux, it can mediate requests to handlers
provided by future options:
return func(n *core.IpfsNode, mux *http.ServeMux) (*http.ServeMux, error) {
childMux := http.NewServeMux()
mux.Handle("/", handlerThatDelegatesToChildMux)
return childMux, nil
}
License: MIT
Signed-off-by: Kevin Wallace <kevin@pentabarf.net>
74 lines
2.2 KiB
Go
74 lines
2.2 KiB
Go
package corehttp
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
manners "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/braintree/manners"
|
|
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
|
manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr-net"
|
|
core "github.com/jbenet/go-ipfs/core"
|
|
eventlog "github.com/jbenet/go-ipfs/thirdparty/eventlog"
|
|
)
|
|
|
|
var log = eventlog.Logger("core/server")
|
|
|
|
// ServeOption registers any HTTP handlers it provides on the given mux.
|
|
// It returns the mux to expose to future options, which may be a new mux if it
|
|
// is interested in mediating requests to future options, or the same mux
|
|
// initially passed in if not.
|
|
type ServeOption func(*core.IpfsNode, *http.ServeMux) (*http.ServeMux, error)
|
|
|
|
// ListenAndServe runs an HTTP server listening at |listeningMultiAddr| with
|
|
// the given serve options. The address must be provided in multiaddr format.
|
|
//
|
|
// TODO intelligently parse address strings in other formats so long as they
|
|
// unambiguously map to a valid multiaddr. e.g. for convenience, ":8080" should
|
|
// map to "/ip4/0.0.0.0/tcp/8080".
|
|
func ListenAndServe(n *core.IpfsNode, listeningMultiAddr string, options ...ServeOption) error {
|
|
addr, err := ma.NewMultiaddr(listeningMultiAddr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
topMux := http.NewServeMux()
|
|
mux := topMux
|
|
for _, option := range options {
|
|
mux, err = option(n, mux)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return listenAndServe(n, addr, topMux)
|
|
}
|
|
|
|
func listenAndServe(node *core.IpfsNode, addr ma.Multiaddr, mux *http.ServeMux) error {
|
|
_, host, err := manet.DialArgs(addr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
server := manners.NewServer()
|
|
|
|
// if the server exits beforehand
|
|
var serverError error
|
|
serverExited := make(chan struct{})
|
|
|
|
go func() {
|
|
serverError = server.ListenAndServe(host, mux)
|
|
close(serverExited)
|
|
}()
|
|
|
|
// wait for server to exit.
|
|
select {
|
|
case <-serverExited:
|
|
|
|
// if node being closed before server exits, close server
|
|
case <-node.Closing():
|
|
log.Infof("server at %s terminating...", addr)
|
|
server.Shutdown <- true
|
|
<-serverExited // now, DO wait until server exit
|
|
}
|
|
|
|
log.Infof("server at %s terminated", addr)
|
|
return serverError
|
|
}
|