feat: HTTP retrieval by block CID#946
Conversation
|
Where is the logic here that would prevent serving blocks that should not be retrievable by provider policy? |
cmd/booster-http/server.go
Outdated
| } | ||
|
|
||
| func (s *HttpServer) blockBasePath() string { | ||
| return s.path + "/block/" |
There was a problem hiding this comment.
lets have a spec for this interface?
In particular, there are a set of semantics that have become fairly precise around how the IPFS gateways serve a block over HTTP.
We should, unless we have very strong reason otherwise, attempt to replicate those semantics.
Otherwise, we end up having to maintain support for this alternative endpoint with slightly different semantics. that we haven't fully documented anywhere.
There was a problem hiding this comment.
I agree we should replicate the gateway semantics - could you point us to any existing docs about gateway semantics that we can take a look at?
There was a problem hiding this comment.
There was a problem hiding this comment.
So it seems like what's missing is:
- Set Content-Type header to
application/vnd.ipld.raw - Set Content-Disposition header to
attachment; filename="<cid>.car"
Is there anything else I'm missing?
There was a problem hiding this comment.
we should consider path semantics of /ipfs/<cid> rather than /block/<cid> as well
There was a problem hiding this comment.
Sorry I'm not familiar enough with the spec to know what you mean by path semantics - can you point us to a specific section?
There was a problem hiding this comment.
We probably need "X-Content-Type-Options" set as "nosniff" as well
There was a problem hiding this comment.
data is requested by CID, only supported path is /ipfs/{cid}
just that the implemented handler is at the path "/block/" and the gateway spec is expecting it to be at "/ipfs/"
There was a problem hiding this comment.
Oh I see - sure that seems like an easy change to make
There was a problem hiding this comment.
All requested changes done. @willscott and @dirkmc Can you review again?
|
We need to implement provider policy for booster-http, but that's true of all endpoints, so I think it's outside the scope of this PR |
7b31cb5 to
3b9cf50
Compare
230da21 to
387b25c
Compare
cmd/booster-http/server.go
Outdated
| filename := r.URL.Query().Get("filename") | ||
| if filename == "" { | ||
| filename = blockCidStr | ||
| } | ||
|
|
||
| utf8Name := url.PathEscape(filename) | ||
| asciiName := url.PathEscape(regexp.MustCompile("[[:^ascii:]]").ReplaceAllLiteralString(filename, "_")) | ||
| w.Header().Set("Content-Disposition", fmt.Sprintf("%s; filename=\"%s\"; filename*=UTF-8''%s", "attachment", asciiName, utf8Name)) |
There was a problem hiding this comment.
how strongly do we feel we need this additional logic?
this diverges from the headers the gateway spec details, and means you can make a url that downloads as an attacker-controlled filename / includes data not in the block itself.
There was a problem hiding this comment.
Are talking about the filename logic in case user did not specify one? Or filename within the header itself?
There was a problem hiding this comment.
I see what you mean. Let me remove the filename input altogether to avoid this. Filename would be same as block Cid to mitigate this.
cmd/booster-http/server.go
Outdated
| utf8Name := url.PathEscape(filename) | ||
| asciiName := url.PathEscape(regexp.MustCompile("[[:^ascii:]]").ReplaceAllLiteralString(filename, "_")) | ||
| w.Header().Set("Content-Disposition", fmt.Sprintf("%s; filename=\"%s\"; filename*=UTF-8''%s", "attachment", asciiName, utf8Name)) | ||
| w.Header().Set("Content-Type", "application/vnd.ipld.raw") |
There was a problem hiding this comment.
It looks like the Content-Type gets overridden in the parameter passed to serveContent()
|
Could you please do a related PR to the docs so we can see how this appears from a user perspective along with the piece cid endpoints and query params? |
I will update the docs once this PR is merged and a release has the new code. Targeted release for this feature will be v1.5.1-rc1 |
cmd/booster-http/server.go
Outdated
| utf8Name := url.PathEscape(blockCidStr) | ||
| asciiName := url.PathEscape(regexp.MustCompile("[[:^ascii:]]").ReplaceAllLiteralString(blockCidStr, "_")) |
There was a problem hiding this comment.
Instead of doing all the escaping, can you just use blockCid.String()?
There was a problem hiding this comment.
I might be wrong but I think this due to how Go treats a string as slice of bytes(runes). It would still try to use the special characters so forcing them to escape would be a safer choice.
BTW, I picked this directly from Kubo.
https://github.com/ipfs/kubo/blob/1d5e46ac97dbd9862818b191517a4dc04186a26e/core/corehttp/gateway_handler.go#L688-L692
|
@LexLuthr some other PRs got merged into |
6d1bf3a to
3e2126b
Compare
No description provided.