From 084cdc3ed842c84da357bf0ea441c9207c08c3ca Mon Sep 17 00:00:00 2001 From: Kevin Wallace Date: Mon, 2 Feb 2015 22:55:23 -0800 Subject: [PATCH] gateway: attempt to resolve hostname to ipfs path This allows someone to host a static site by pointing a TXT record at their content in IPFS, and a CNAME record at an IPFS gateway. Note that such a setup technically violates RFC1912 (section 2.4; "A CNAME record is not allowed to coexist with any other data."), but tends to work in practice. We may want to consider changing the DNS->IPFS resolution scheme to allow this scenario to be RFC-compliant (e.g. store the mapping on a well-known subdomain to allow CNAME records on the domain itself). License: MIT Signed-off-by: Kevin Wallace --- cmd/ipfs/daemon.go | 5 ++++- core/corehttp/ipns_hostname.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 core/corehttp/ipns_hostname.go diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 2dcf48e4d..0ad20c9dc 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -178,7 +178,10 @@ func daemonFunc(req cmds.Request, res cmds.Response) { if gatewayMaddr != nil { go func() { - var opts = []corehttp.ServeOption{corehttp.GatewayOption(writable)} + var opts = []corehttp.ServeOption{ + corehttp.IPNSHostnameOption(), + corehttp.GatewayOption(writable), + } if rootRedirect != nil { opts = append(opts, rootRedirect) } diff --git a/core/corehttp/ipns_hostname.go b/core/corehttp/ipns_hostname.go new file mode 100644 index 000000000..27d683250 --- /dev/null +++ b/core/corehttp/ipns_hostname.go @@ -0,0 +1,29 @@ +package corehttp + +import ( + "net/http" + "strings" + + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context" + "github.com/jbenet/go-ipfs/core" +) + +// IPNSHostnameOption rewrites an incoming request if its Host: header contains +// 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) { + childMux := http.NewServeMux() + mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + ctx, cancel := context.WithCancel(n.Context()) + defer cancel() + + host := strings.SplitN(r.Host, ":", 2)[0] + if k, err := n.Namesys.Resolve(ctx, host); err == nil { + r.URL.Path = "/ipfs/" + k.Pretty() + r.URL.Path + } + childMux.ServeHTTP(w, r) + }) + return childMux, nil + } +}