@cryptotaxi247 / kubo / commits / a90f4967e

gateway: re-use resolved path

Instead of resolving a node, we resolve a path. This resolved path is then re-used for Cat and Ls. This way, a resolve operation is only done once. The error messages for a failed resolve is changed from `ipfs cat …` to `ipfs resolve …` to better reflect the API calls. The test is updated accordingly. License: MIT Signed-off-by: Remco Bloemen <remco@2π.com>

Remco Bloemen committed Apr 18, 2017 at 17:22 UTC a90f4967e30fc5f16d362f1b9844196e1bd24101
2 files changed +17 -16
core/corehttp/gateway_handler.go
+16 -15
@@ -164,35 +164,36 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
164 return
165 }
166
167 - dr, err := i.api.Unixfs().Cat(ctx, parsedPath)
168 - dir := false
167 + // Resolve path to the final DAG node for the ETag
168 + resolvedPath, err := i.api.ResolvePath(ctx, parsedPath)
169 switch err {
170 case nil:
171 - // Cat() worked
172 - defer dr.Close()
173 - case coreiface.ErrIsDir:
174 - dir = true
171 case coreiface.ErrOffline:
172 if !i.node.OnlineMode() {
177 - webError(w, "ipfs cat "+urlPath, err, http.StatusServiceUnavailable)
173 + webError(w, "ipfs resolve -r "+urlPath, err, http.StatusServiceUnavailable)
174 return
175 }
176 fallthrough
177 default:
182 - webError(w, "ipfs cat "+urlPath, err, http.StatusNotFound)
178 + webError(w, "ipfs resolve -r "+urlPath, err, http.StatusNotFound)
179 return
180 }
181
186 - // Resolve path to the final DAG node for the ETag
187 - dagnode, err := i.api.ResolveNode(ctx, parsedPath)
188 - if err != nil {
189 - // Unixfs().Cat() also calls ResolveNode, so it should not fail here.
190 - webError(w, "could not resolve ipfs path", err, http.StatusBadRequest)
182 + dr, err := i.api.Unixfs().Cat(ctx, resolvedPath)
183 + dir := false
184 + switch err {
185 + case nil:
186 + // Cat() worked
187 + defer dr.Close()
188 + case coreiface.ErrIsDir:
189 + dir = true
190 + default:
191 + webError(w, "ipfs cat "+urlPath, err, http.StatusNotFound)
192 return
193 }
194
195 // Check etag send back to us
195 - etag := "\"" + dagnode.Cid().String() + "\""
196 + etag := "\"" + resolvedPath.Cid().String() + "\""
197 if r.Header.Get("If-None-Match") == etag {
198 w.WriteHeader(http.StatusNotModified)
199 return
@@ -225,7 +226,7 @@ func (i *gatewayHandler) getOrHeadHandler(ctx context.Context, w http.ResponseWr
226 return
227 }
228
228 - links, err := i.api.Unixfs().Ls(ctx, parsedPath)
229 + links, err := i.api.Unixfs().Ls(ctx, resolvedPath)
230 if err != nil {
231 internalWebError(w, err)
232 return
core/corehttp/gateway_test.go
+1 -1
@@ -136,7 +136,7 @@ func TestGatewayGet(t *testing.T) {
136 {"localhost:5001", "/", http.StatusNotFound, "404 page not found\n"},
137 {"localhost:5001", "/" + k, http.StatusNotFound, "404 page not found\n"},
138 {"localhost:5001", "/ipfs/" + k, http.StatusOK, "fnord"},
139 - {"localhost:5001", "/ipns/nxdomain.example.com", http.StatusNotFound, "ipfs cat /ipns/nxdomain.example.com: " + namesys.ErrResolveFailed.Error() + "\n"},
139 + {"localhost:5001", "/ipns/nxdomain.example.com", http.StatusNotFound, "ipfs resolve -r /ipns/nxdomain.example.com: " + namesys.ErrResolveFailed.Error() + "\n"},
140 {"localhost:5001", "/ipns/example.com", http.StatusOK, "fnord"},
141 {"example.com", "/", http.StatusOK, "fnord"},
142 } {