Skip to content

Commit 01dcb8d

Browse files
committed
feat(gateway): redirect ipns b58mh to cid
1 parent 6f324be commit 01dcb8d

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

gateway/gateway_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,3 +548,15 @@ func TestGoGetSupport(t *testing.T) {
548548
assert.Nil(t, err)
549549
assert.Equal(t, http.StatusOK, res.StatusCode)
550550
}
551+
552+
func TestIpnsBase58MultihashRedirect(t *testing.T) {
553+
ts, _, _ := newTestServerAndNode(t, nil)
554+
t.Logf("test server url: %s", ts.URL)
555+
556+
req, err := http.NewRequest(http.MethodGet, ts.URL+"/ipns/12D3KooWRBy97UB99e3J6hiPesre1MZeuNQvfan4gBziswrRJsNK?keep=query", nil)
557+
assert.Nil(t, err)
558+
559+
res, err := doWithoutRedirect(req)
560+
assert.Nil(t, err)
561+
assert.Equal(t, "/ipns/bafzaajaiaejcbzdibmxyzdjbbehgvizh6g5tikvy47mshdy6gwbruvgwvd24seje?keep=query", res.Header.Get("Location"))
562+
}

gateway/handler.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import (
1919
ipath "github.com/ipfs/boxo/coreiface/path"
2020
cid "github.com/ipfs/go-cid"
2121
logging "github.com/ipfs/go-log"
22+
"github.com/libp2p/go-libp2p/core/peer"
23+
"github.com/multiformats/go-multihash"
2224
prometheus "github.com/prometheus/client_golang/prometheus"
2325
"go.opentelemetry.io/otel"
2426
"go.opentelemetry.io/otel/attribute"
@@ -305,6 +307,34 @@ func (i *handler) optionsHandler(w http.ResponseWriter, r *http.Request) {
305307
i.addUserHeaders(w) // return all custom headers (including CORS ones, if set)
306308
}
307309

310+
// handleIpnsPeerIdToCidRedirection redirects from /ipns/b58mh to /ipns/cid in
311+
// the most cost-effective way.
312+
func handleIpnsPeerIdToCidRedirection(w http.ResponseWriter, r *http.Request) bool {
313+
pathParts := strings.Split(r.URL.Path, "/")
314+
if len(pathParts) < 3 {
315+
return false
316+
}
317+
318+
s := pathParts[2]
319+
320+
// Similarly to peer.Decode, check the prefix first as it is
321+
// less computationally expensive.
322+
if !strings.HasPrefix(s, "1") {
323+
return false
324+
}
325+
326+
// Decode the base58 encoded sha256 or identity multihash.
327+
m, err := multihash.FromB58String(s)
328+
if err != nil {
329+
return false
330+
}
331+
332+
pathParts[2] = peer.ToCid(peer.ID(m)).String()
333+
r.URL.Path = strings.Join(pathParts, "/")
334+
http.Redirect(w, r, r.URL.String(), http.StatusFound)
335+
return true
336+
}
337+
308338
func (i *handler) getOrHeadHandler(w http.ResponseWriter, r *http.Request) {
309339
begin := time.Now()
310340

@@ -325,6 +355,10 @@ func (i *handler) getOrHeadHandler(w http.ResponseWriter, r *http.Request) {
325355
return
326356
}
327357

358+
if handleIpnsPeerIdToCidRedirection(w, r) {
359+
return
360+
}
361+
328362
contentPath := ipath.New(r.URL.Path)
329363
ctx := context.WithValue(r.Context(), ContentPathKey, contentPath)
330364
r = r.WithContext(ctx)

0 commit comments

Comments
 (0)