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 <kevin@pentabarf.net>
Kevin Wallace committed
Feb 2, 2015 at 22:55 UTC
084cdc3ed842c84da357bf0ea441c9207c08c3ca
2 files changed
+33
-1
cmd/ipfs/daemon.go
+4
-1
@@ -178,7 +178,10 @@ func daemonFunc(req cmds.Request, res cmds.Response) {
178
179
if gatewayMaddr != nil {
180
go func() {
181
- var opts = []corehttp.ServeOption{corehttp.GatewayOption(writable)}
181
+ var opts = []corehttp.ServeOption{
182
+ corehttp.IPNSHostnameOption(),
183
+ corehttp.GatewayOption(writable),
184
+ }
185
if rootRedirect != nil {
186
opts = append(opts, rootRedirect)
187
}
core/corehttp/ipns_hostname.go
new
+29
@@ -0,0 +1,29 @@
1
+package corehttp
2
+
3
+import (
4
+ "net/http"
5
+ "strings"
6
+
7
+ "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
8
+ "github.com/jbenet/go-ipfs/core"
9
+)
10
+
11
+// IPNSHostnameOption rewrites an incoming request if its Host: header contains
12
+// an IPNS name.
13
+// The rewritten request points at the resolved name on the gateway handler.
14
+func IPNSHostnameOption() ServeOption {
15
+ return func(n *core.IpfsNode, mux *http.ServeMux) (*http.ServeMux, error) {
16
+ childMux := http.NewServeMux()
17
+ mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
18
+ ctx, cancel := context.WithCancel(n.Context())
19
+ defer cancel()
20
+
21
+ host := strings.SplitN(r.Host, ":", 2)[0]
22
+ if k, err := n.Namesys.Resolve(ctx, host); err == nil {
23
+ r.URL.Path = "/ipfs/" + k.Pretty() + r.URL.Path
24
+ }
25
+ childMux.ServeHTTP(w, r)
26
+ })
27
+ return childMux, nil
28
+ }
29
+}