From 3f1cbe2f437c9aad8b972b40283d2dc69a2bd6b9 Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Fri, 31 Jul 2015 17:34:56 -0400 Subject: [PATCH] corehttp: add net.Listener to ServeOption ServeOptions take the node and muxer, they should get the listener too as sometimes they need to operate on the listener address. License: MIT Signed-off-by: Juan Batiz-Benet --- cmd/ipfs/daemon.go | 5 +++-- core/corehttp/commands.go | 3 ++- core/corehttp/corehttp.go | 8 ++++---- core/corehttp/gateway.go | 5 +++-- core/corehttp/gateway_test.go | 20 ++++++++++++++++---- core/corehttp/ipns_hostname.go | 3 ++- core/corehttp/logs.go | 3 ++- core/corehttp/prometheus.go | 3 ++- core/corehttp/redirect.go | 3 ++- 9 files changed, 36 insertions(+), 17 deletions(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index d14770ebf..0b23d079d 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -3,6 +3,7 @@ package main import ( _ "expvar" "fmt" + "net" "net/http" _ "net/http/pprof" "os" @@ -126,8 +127,8 @@ future version, along with this notice. Please move to setting the HTTP Headers. // mostly useful to hook up things that register in the default muxer, // and don't provide a convenient http.Handler entry point, such as // expvar and http/pprof. -func defaultMux(path string) func(node *core.IpfsNode, mux *http.ServeMux) (*http.ServeMux, error) { - return func(node *core.IpfsNode, mux *http.ServeMux) (*http.ServeMux, error) { +func defaultMux(path string) corehttp.ServeOption { + return func(node *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { mux.Handle(path, http.DefaultServeMux) return mux, nil } diff --git a/core/corehttp/commands.go b/core/corehttp/commands.go index 0a65fcc3a..1793c5539 100644 --- a/core/corehttp/commands.go +++ b/core/corehttp/commands.go @@ -1,6 +1,7 @@ package corehttp import ( + "net" "net/http" "os" "strings" @@ -58,7 +59,7 @@ func addHeadersFromConfig(c *cmdsHttp.ServerConfig, nc *config.Config) { } func CommandsOption(cctx commands.Context) ServeOption { - return func(n *core.IpfsNode, mux *http.ServeMux) (*http.ServeMux, error) { + return func(n *core.IpfsNode, l net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { cfg := &cmdsHttp.ServerConfig{ CORSOpts: &cors.Options{ diff --git a/core/corehttp/corehttp.go b/core/corehttp/corehttp.go index 042f056ad..dc221f3cd 100644 --- a/core/corehttp/corehttp.go +++ b/core/corehttp/corehttp.go @@ -23,16 +23,16 @@ var log = eventlog.Logger("core/server") // 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) +type ServeOption func(*core.IpfsNode, net.Listener, *http.ServeMux) (*http.ServeMux, error) // makeHandler turns a list of ServeOptions into a http.Handler that implements // all of the given options, in order. -func makeHandler(n *core.IpfsNode, options ...ServeOption) (http.Handler, error) { +func makeHandler(n *core.IpfsNode, l net.Listener, options ...ServeOption) (http.Handler, error) { topMux := http.NewServeMux() mux := topMux for _, option := range options { var err error - mux, err = option(n, mux) + mux, err = option(n, l, mux) if err != nil { return nil, err } @@ -65,7 +65,7 @@ func ListenAndServe(n *core.IpfsNode, listeningMultiAddr string, options ...Serv } func Serve(node *core.IpfsNode, lis net.Listener, options ...ServeOption) error { - handler, err := makeHandler(node, options...) + handler, err := makeHandler(node, lis, options...) if err != nil { return err } diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index f70a1d11f..584a89437 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -2,6 +2,7 @@ package corehttp import ( "fmt" + "net" "net/http" "sync" @@ -27,7 +28,7 @@ func NewGateway(conf GatewayConfig) *Gateway { } func (g *Gateway) ServeOption() ServeOption { - return func(n *core.IpfsNode, mux *http.ServeMux) (*http.ServeMux, error) { + return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { // pass user's HTTP headers g.Config.Headers = n.Repo.Config().Gateway.HTTPHeaders @@ -50,7 +51,7 @@ func GatewayOption(writable bool) ServeOption { } func VersionOption() ServeOption { - return func(n *core.IpfsNode, mux *http.ServeMux) (*http.ServeMux, error) { + return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { mux.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Client Version: %s\n", id.ClientVersion) fmt.Fprintf(w, "Protocol Version: %s\n", id.IpfsVersion) diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go index 01d4295b7..7ad3584da 100644 --- a/core/corehttp/gateway_test.go +++ b/core/corehttp/gateway_test.go @@ -55,6 +55,14 @@ func newNodeWithMockNamesys(t *testing.T, ns mockNamesys) *core.IpfsNode { return n } +type delegatedHandler struct { + http.Handler +} + +func (dh *delegatedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + dh.Handler.ServeHTTP(w, r) +} + func TestGatewayGet(t *testing.T) { t.Skip("not sure whats going on here") ns := mockNamesys{} @@ -65,7 +73,14 @@ func TestGatewayGet(t *testing.T) { } ns["example.com"] = path.FromString("/ipfs/" + k) - h, err := makeHandler(n, + // need this variable here since we need to construct handler with + // listener, and server with handler. yay cycles. + dh := &delegatedHandler{} + ts := httptest.NewServer(dh) + defer ts.Close() + + dh.Handler, err = makeHandler(n, + ts.Listener, IPNSHostnameOption(), GatewayOption(false), ) @@ -73,9 +88,6 @@ func TestGatewayGet(t *testing.T) { t.Fatal(err) } - ts := httptest.NewServer(h) - defer ts.Close() - t.Log(ts.URL) for _, test := range []struct { host string diff --git a/core/corehttp/ipns_hostname.go b/core/corehttp/ipns_hostname.go index 6f31e5268..10edb0ace 100644 --- a/core/corehttp/ipns_hostname.go +++ b/core/corehttp/ipns_hostname.go @@ -1,6 +1,7 @@ package corehttp import ( + "net" "net/http" "strings" @@ -13,7 +14,7 @@ import ( // an IPNS name. // The rewritten request points at the resolved name on the gateway handler. func IPNSHostnameOption() ServeOption { - return func(n *core.IpfsNode, mux *http.ServeMux) (*http.ServeMux, error) { + return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { childMux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithCancel(n.Context()) diff --git a/core/corehttp/logs.go b/core/corehttp/logs.go index 7624644cf..59b87b9bc 100644 --- a/core/corehttp/logs.go +++ b/core/corehttp/logs.go @@ -2,6 +2,7 @@ package corehttp import ( "io" + "net" "net/http" core "github.com/ipfs/go-ipfs/core" @@ -36,7 +37,7 @@ func (w *writeErrNotifier) Write(b []byte) (int, error) { } func LogOption() ServeOption { - return func(n *core.IpfsNode, mux *http.ServeMux) (*http.ServeMux, error) { + return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { mux.HandleFunc("/logs", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) wnf, errs := newWriteErrNotifier(w) diff --git a/core/corehttp/prometheus.go b/core/corehttp/prometheus.go index d6e8ef4d0..0642c04b5 100644 --- a/core/corehttp/prometheus.go +++ b/core/corehttp/prometheus.go @@ -1,6 +1,7 @@ package corehttp import ( + "net" "net/http" prom "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus" @@ -9,7 +10,7 @@ import ( ) func PrometheusOption(path string) ServeOption { - return func(n *core.IpfsNode, mux *http.ServeMux) (*http.ServeMux, error) { + return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { mux.Handle(path, prom.Handler()) return mux, nil } diff --git a/core/corehttp/redirect.go b/core/corehttp/redirect.go index 67d6c0773..ec70ffaf9 100644 --- a/core/corehttp/redirect.go +++ b/core/corehttp/redirect.go @@ -1,6 +1,7 @@ package corehttp import ( + "net" "net/http" core "github.com/ipfs/go-ipfs/core" @@ -8,7 +9,7 @@ import ( func RedirectOption(path string, redirect string) ServeOption { handler := &redirectHandler{redirect} - return func(n *core.IpfsNode, mux *http.ServeMux) (*http.ServeMux, error) { + return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) { mux.Handle("/"+path+"/", handler) return mux, nil }