-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: require content-type parser to set content-type #423
feat: require content-type parser to set content-type #423
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self review
packages/verified-fetch/src/index.ts
Outdated
@@ -112,6 +112,26 @@ | |||
* const json = await resp.json() | |||
* ``` | |||
* | |||
* ### Custom content-type parsing | |||
* | |||
* By default, `@helia/verified-fetch` does not set the `Content-Type` header. This is because the `.json()`, `.text()`, `.blob()`, and `.arrayBuffer()` methods will usually work as expected. You can provide a `contentTypeParser` function to the `createVerifiedFetch` function to handle parsing the content type. The function you provide will be passed the first bytes we receive from the network. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could link to #422 if desired.
* By default, `@helia/verified-fetch` does not set the `Content-Type` header. This is because the `.json()`, `.text()`, `.blob()`, and `.arrayBuffer()` methods will usually work as expected. You can provide a `contentTypeParser` function to the `createVerifiedFetch` function to handle parsing the content type. The function you provide will be passed the first bytes we receive from the network. | |
* By default, `@helia/verified-fetch` does not set the `Content-Type` header. This is because the `.json()`, `.text()`, `.blob()`, and `.arrayBuffer()` methods will usually work as expected. You can provide a `contentTypeParser` function to the `createVerifiedFetch` function to handle parsing the content type. The function you provide will be passed the first bytes we receive from the network. See https://github.com/ipfs/helia/issues/422 for our thoughts and reasoning. |
* | ||
* ```typescript | ||
* import { createVerifiedFetch } from '@helia/verified-fetch' | ||
* import { fileTypeFromBuffer } from '@sgtpooki/file-type' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not referencing mime-types
because it only does recognition based on extension, and the troubles @2color mentioned with ipfs-examples/helia-examples#285.
Not referencing file-types
because of the lack of browser support, that has been tested and verified in https://github.com/SgtPooki/file-type
packages/verified-fetch/src/index.ts
Outdated
* routers: ['http://delegated-ipfs.dev'], | ||
* contentTypeParser: async (bytes) => { | ||
* // call to some magic-byte recognition library like magic-bytes, file-type, or your own custom byte recognition | ||
* return fileTypeFromBuffer(bytes)?.mime ?? 'application/octet-stream' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* return fileTypeFromBuffer(bytes)?.mime ?? 'application/octet-stream' | |
* return (await fileTypeFromBuffer(bytes))?.mime ?? 'application/octet-stream' |
* bytes we receive from the network, and should return a string that will be used as the value for the `Content-Type` | ||
* header in the response. | ||
*/ | ||
contentTypeParser?: ContentTypeParser |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to add contentTypeParser to verifiedFetch options? I don't think we need to allow passing it for each call, but we could. LMK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps not in the first instance to keep it simple? We can always add it later.
* bytes we receive from the network, and should return a string that will be used as the value for the `Content-Type` | ||
* header in the response. | ||
*/ | ||
contentTypeParser?: ContentTypeParser |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to accept an options
param here that allows for the VerifiedFetchInit
options and just pass that through? That seems better and less prone to CreateVerifiedFetchWithOptions
growing unnecessarily large.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure, I think maybe we want to create a separation between the createVerifiedFetch
options arg type and the VerifiedFetch
class init arg type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thats why I went with this initially. we could always update if we really need to, but i don't imagine createVerifiedFetch init args will vary much
let verifiedFetch: Awaited<ReturnType<typeof createVerifiedFetch>> | ||
let verifiedFetch: VerifiedFetch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This type is a bit simpler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
I made a few changes, please comment if you disagree with them:
- Split the content type parser tests into their own file
- Defaulted to a
Content-Type
ofapplication/octet-stream
instead of not setting one - I think this would be more consistent with what a web server would do - Added tests that show how to use
@sgtpooki/file-type
and alsomagic-bytes.js
as they both work in browsers - Allows the contentTypeParser to be sync as well as async, and to also return
undefined
in which case we fall back toapplication/octet-stream
Also fixed a few bugs:
- The
contentTypeParser
option wasn't being passed through if you usedcreateVerifiedFetch
- The interop test had guessing the type of an image as
image/png
removed - the file is actuallyimage/jpeg
with a.png
extension , I guess this was throwing the previous content-type guesser off - now the test tests for the correct mime type
This is done now ✅ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm good with the changes
|
||
it('can return an image content-type for unixfs pathed data', async () => { | ||
const resp = await verifiedFetch('ipfs://QmbQDovX7wRe9ek7u6QXe9zgCXkTzoUSsTFJEkrYV1HrVR/1 - Barrel - Part 1.png') | ||
// tediously this is actually a jpeg file with a .png extension |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤣
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inorite
Title
feat: require content-type parser to set content-type
Description
contentTypeParser
function to createVerifiedFetch options & implements it.getStreamAndContentType
togetStreamFromAsyncIterable
that now returns a stream with the firstChunk seen, so we can pass it to thecontentTypeParser
function.Related #416
Fixes #422
Notes & open questions
Change checklist