mirror of
https://github.com/ipfs/kubo.git
synced 2026-03-06 00:38:08 +08:00
feat: support requests from registerProtocolHandler
This commit adds support for requests produced by navigator.registerProtocolHandler on gateways. Now one can register `dweb.link` as an URI handler for `ipfs://`:
```
navigator.registerProtocolHandler('ipfs', 'https://dweb.link/ipfs/?uri=%s', 'ipfs resolver')
```
Then opening `ipfs://QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR` will produce an HTTP GET call to:
```
https://dweb.link/ipfs?uri=ipfs%3A%2F%2FQmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR
```
The query parameter `uri` will now be parsed and the given content identifier resolved via:
`https://dweb.link/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR`
This commit is contained in:
parent
4ccb526b94
commit
36368ee4dd
@ -181,6 +181,23 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
|
||||
}
|
||||
originalUrlPath := prefix + requestURI.Path
|
||||
|
||||
// Query parameter handling to support requests produced by navigator.registerProtocolHandler.
|
||||
// E.g. This code will redirect calls to /ipfs/?uri=ipfs%3A%2F%2Fcontent-identifier
|
||||
// to /ipfs/content-identifier.
|
||||
if uri := r.URL.Query().Get("uri"); uri != "" {
|
||||
u, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
webError(w, "failed to parse uri query parameter", err, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if u.Scheme != "ipfs" && u.Scheme != "ipns" {
|
||||
webError(w, "uri query parameter scheme must be ipfs or ipns", err, http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, gopath.Join("/", prefix, u.Scheme, u.Host), http.StatusMovedPermanently)
|
||||
return
|
||||
}
|
||||
|
||||
// Service Worker registration request
|
||||
if r.Header.Get("Service-Worker") == "script" {
|
||||
// Disallow Service Worker registration on namespace roots
|
||||
|
||||
@ -161,6 +161,47 @@ func matchPathOrBreadcrumbs(s string, expected string) bool {
|
||||
return matched
|
||||
}
|
||||
|
||||
func TestUriQueryRedirect(t *testing.T) {
|
||||
ts, _, _ := newTestServerAndNode(t, mockNamesys{})
|
||||
|
||||
cid := "QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR"
|
||||
for i, test := range []struct {
|
||||
path string
|
||||
status int
|
||||
location string
|
||||
}{
|
||||
{"/ipfs/?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/" + cid},
|
||||
{"/ipfs/?uri=ipfs%3A%2F%2F" + cid, http.StatusMovedPermanently, "/ipfs/" + cid},
|
||||
{"/ipfs?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/?uri=ipfs://" + cid},
|
||||
{"/ipfs/?uri=ipns://" + cid, http.StatusMovedPermanently, "/ipns/" + cid},
|
||||
{"/ipns?uri=ipns://" + cid, http.StatusMovedPermanently, "/ipns/?uri=ipns://" + cid},
|
||||
{"/ipns/?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/" + cid},
|
||||
{"/ipns/?uri=ipfs://" + cid, http.StatusMovedPermanently, "/ipfs/" + cid},
|
||||
{"/ipfs/?uri=unsupported://" + cid, http.StatusBadRequest, ""},
|
||||
{"/ipfs/?uri=" + cid, http.StatusBadRequest, ""},
|
||||
} {
|
||||
|
||||
r, err := http.NewRequest(http.MethodGet, ts.URL+test.path, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
resp, err := doWithoutRedirect(r)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != test.status {
|
||||
t.Errorf("(%d) got %d, expected %d from %s", i, resp.StatusCode, test.status, ts.URL+test.path)
|
||||
}
|
||||
|
||||
locHdr := resp.Header.Get("Location")
|
||||
if locHdr != test.location {
|
||||
t.Errorf("(%d) location header got %s, expected %s from %s", i, locHdr, test.location, ts.URL+test.path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGatewayGet(t *testing.T) {
|
||||
ns := mockNamesys{}
|
||||
ts, api, ctx := newTestServerAndNode(t, ns)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user