Skip to content

Commit

Permalink
feat(gateway): redirect ipns b58mh to cid
Browse files Browse the repository at this point in the history
  • Loading branch information
hacdias committed Mar 30, 2023
1 parent 6f324be commit 01dcb8d
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
12 changes: 12 additions & 0 deletions gateway/gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -548,3 +548,15 @@ func TestGoGetSupport(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, http.StatusOK, res.StatusCode)
}

func TestIpnsBase58MultihashRedirect(t *testing.T) {
ts, _, _ := newTestServerAndNode(t, nil)
t.Logf("test server url: %s", ts.URL)

req, err := http.NewRequest(http.MethodGet, ts.URL+"/ipns/12D3KooWRBy97UB99e3J6hiPesre1MZeuNQvfan4gBziswrRJsNK?keep=query", nil)
assert.Nil(t, err)

res, err := doWithoutRedirect(req)
assert.Nil(t, err)
assert.Equal(t, "/ipns/bafzaajaiaejcbzdibmxyzdjbbehgvizh6g5tikvy47mshdy6gwbruvgwvd24seje?keep=query", res.Header.Get("Location"))
}
34 changes: 34 additions & 0 deletions gateway/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
ipath "github.com/ipfs/boxo/coreiface/path"
cid "github.com/ipfs/go-cid"
logging "github.com/ipfs/go-log"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/multiformats/go-multihash"
prometheus "github.com/prometheus/client_golang/prometheus"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
Expand Down Expand Up @@ -305,6 +307,34 @@ func (i *handler) optionsHandler(w http.ResponseWriter, r *http.Request) {
i.addUserHeaders(w) // return all custom headers (including CORS ones, if set)
}

// handleIpnsPeerIdToCidRedirection redirects from /ipns/b58mh to /ipns/cid in
// the most cost-effective way.
func handleIpnsPeerIdToCidRedirection(w http.ResponseWriter, r *http.Request) bool {
pathParts := strings.Split(r.URL.Path, "/")
if len(pathParts) < 3 {
return false
}

s := pathParts[2]

// Similarly to peer.Decode, check the prefix first as it is
// less computationally expensive.
if !strings.HasPrefix(s, "1") {
return false
}

// Decode the base58 encoded sha256 or identity multihash.
m, err := multihash.FromB58String(s)
if err != nil {
return false
}

pathParts[2] = peer.ToCid(peer.ID(m)).String()
r.URL.Path = strings.Join(pathParts, "/")
http.Redirect(w, r, r.URL.String(), http.StatusFound)
return true
}

func (i *handler) getOrHeadHandler(w http.ResponseWriter, r *http.Request) {
begin := time.Now()

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

if handleIpnsPeerIdToCidRedirection(w, r) {
return
}

contentPath := ipath.New(r.URL.Path)
ctx := context.WithValue(r.Context(), ContentPathKey, contentPath)
r = r.WithContext(ctx)
Expand Down

0 comments on commit 01dcb8d

Please sign in to comment.