@cryptotaxi247 / kubo / commits / b8fcece0e

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>