core/corehttp: Handle IPNS paths in gateway
Matt Bell committed
Jan 26, 2015 at 22:37 UTC
b8fcece0e56f7f6287b7582ba62a47a8506cbc7d
2 files changed
+40
-16
core/corehttp/gateway.go
+1
@@ -12,5 +12,6 @@ func GatewayOption(n *core.IpfsNode, mux *http.ServeMux) error {
12
return err
13
}
14
mux.Handle("/ipfs/", gateway)
15
+ mux.Handle("/ipns/", gateway)
16
return nil
17
}
core/corehttp/gateway_handler.go
+39
-16
@@ -5,6 +5,7 @@ import (
5
"io"
6
"net/http"
7
"path"
8
+ "strings"
9
"time"
10
11
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
@@ -33,6 +34,7 @@ type webHandler map[string]interface{}
34
type directoryItem struct {
35
Size uint64
36
Name string
37
+ Path string
38
}
39
40
// gatewayHandler is a HTTP handler that serves IPFS objects (accessible by default at /ipfs/<path>)
@@ -63,8 +65,26 @@ func (i *gatewayHandler) loadTemplate() error {
65
return nil
66
}
67
66
-func (i *gatewayHandler) ResolvePath(p string) (*dag.Node, error) {
67
- return i.node.Resolver.ResolvePath(p)
68
+func (i *gatewayHandler) ResolvePath(ctx context.Context, p string) (*dag.Node, string, error) {
69
+ if strings.HasPrefix(p, "/ipns/") {
70
+ elements := strings.Split(path.Clean(p[6:]), "/")
71
+ k, err := i.node.Namesys.Resolve(ctx, elements[0])
72
+ if err != nil {
73
+ return nil, "", err
74
+ }
75
+
76
+ elements[0] = k.Pretty()
77
+ p = path.Join(elements...)
78
+ }
79
+ if !strings.HasPrefix(p, "/ipfs/") {
80
+ p = path.Join("/ipfs/", p)
81
+ }
82
+
83
+ node, err := i.node.Resolver.ResolvePath(p)
84
+ if err != nil {
85
+ return nil, "", err
86
+ }
87
+ return node, p, err
88
}
89
90
func (i *gatewayHandler) NewDagFromReader(r io.Reader) (*dag.Node, error) {
@@ -81,9 +101,12 @@ func (i *gatewayHandler) NewDagReader(nd *dag.Node) (io.ReadSeeker, error) {
101
}
102
103
func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
84
- urlPath := r.URL.Path[5:]
104
+ ctx, cancel := context.WithCancel(i.node.Context())
105
+ defer cancel()
106
86
- nd, err := i.ResolvePath(urlPath)
107
+ urlPath := r.URL.Path
108
+
109
+ nd, p, err := i.ResolvePath(ctx, urlPath)
110
if err != nil {
111
if err == routing.ErrNotFound {
112
w.WriteHeader(http.StatusNotFound)
@@ -98,6 +121,8 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
121
return
122
}
123
124
+ w.Header().Set("X-IPFS-Path", p)
125
+
126
dr, err := i.NewDagReader(nd)
127
if err == nil {
128
_, name := path.Split(urlPath)
@@ -113,13 +138,6 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
138
return
139
}
140
116
- log.Debug("listing directory")
117
- if urlPath[len(urlPath)-1:] != "/" {
118
- log.Debug("missing trailing slash, redirect")
119
- http.Redirect(w, r, "/ipfs/"+urlPath+"/", 307)
120
- return
121
- }
122
-
141
// storage for directory listing
142
var dirListing []directoryItem
143
// loop through files
@@ -129,7 +147,7 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
147
log.Debug("found index")
148
foundIndex = true
149
// return index page instead.
132
- nd, err := i.ResolvePath(urlPath + "/index.html")
150
+ nd, _, err := i.ResolvePath(ctx, urlPath+"/index.html")
151
if err != nil {
152
internalWebError(w, err)
153
return
@@ -144,12 +162,17 @@ func (i *gatewayHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
162
break
163
}
164
147
- dirListing = append(dirListing, directoryItem{link.Size, link.Name})
165
+ di := directoryItem{link.Size, link.Name, path.Join(p, link.Name)}
166
+ dirListing = append(dirListing, di)
167
}
168
169
if !foundIndex {
170
// template and return directory listing
152
- hndlr := webHandler{"listing": dirListing, "path": urlPath}
171
+ hndlr := webHandler{
172
+ "listing": dirListing,
173
+ "path": urlPath,
174
+ "actualPath": p,
175
+ }
176
if err := i.dirList.Execute(w, hndlr); err != nil {
177
internalWebError(w, err)
178
return
@@ -198,8 +221,8 @@ var listingTemplate = `
221
<h2>Index of {{ .path }}</h2>
222
<ul>
223
<li><a href="./..">..</a></li>
201
- {{ range $item := .listing }}
202
- <li><a href="./{{ $item.Name }}">{{ $item.Name }}</a> - {{ $item.Size }} bytes</li>
224
+ {{ range .listing }}
225
+ <li><a href="{{ .Path }}">{{ .Name }}</a> - {{ .Size }} bytes</li>
226
{{ end }}
227
</ul>
228
</body>