From 30144981b5253b3269cbf186a24f1ef9dd04a452 Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Wed, 10 Apr 2024 17:21:33 -0700 Subject: [PATCH] fix: identity CIDs use contentTypeParser (#49) * fix: identity CIDs use contentTypeParser * chore: fix logged content type * test: handleRaw uses contentTypeParser --- packages/verified-fetch/package.json | 2 +- packages/verified-fetch/src/verified-fetch.ts | 15 +++++---------- .../test/content-type-parser.spec.ts | 18 +++++++++++++++--- .../test/fixtures/create-offline-helia.ts | 3 ++- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/packages/verified-fetch/package.json b/packages/verified-fetch/package.json index c6ac277..81f4067 100644 --- a/packages/verified-fetch/package.json +++ b/packages/verified-fetch/package.json @@ -97,7 +97,7 @@ "@sgtpooki/file-type": "^1.0.1", "@types/sinon": "^17.0.3", "aegir": "^42.2.5", - "blockstore-core": "^4.4.0", + "blockstore-core": "^4.4.1", "browser-readablestream-to-it": "^2.0.5", "datastore-core": "^9.2.9", "helia": "^4.1.0", diff --git a/packages/verified-fetch/src/verified-fetch.ts b/packages/verified-fetch/src/verified-fetch.ts index 598eff0..26dc33a 100644 --- a/packages/verified-fetch/src/verified-fetch.ts +++ b/packages/verified-fetch/src/verified-fetch.ts @@ -423,18 +423,13 @@ export class VerifiedFetch { // if the user has specified an `Accept` header that corresponds to a raw // type, honour that header, so for example they don't request // `application/vnd.ipld.raw` but get `application/octet-stream` - const overriddenContentType = getOverridenRawContentType({ headers: options?.headers, accept }) - if (overriddenContentType != null) { - response.headers.set('content-type', overriddenContentType) - } else { - await this.setContentType(result, path, response) - } + await this.setContentType(result, path, response, getOverridenRawContentType({ headers: options?.headers, accept })) return response } - private async setContentType (bytes: Uint8Array, path: string, response: Response): Promise { - let contentType = 'application/octet-stream' + private async setContentType (bytes: Uint8Array, path: string, response: Response, defaultContentType = 'application/octet-stream'): Promise { + let contentType: string | undefined if (this.contentTypeParser != null) { try { @@ -455,8 +450,8 @@ export class VerifiedFetch { this.log.error('error parsing content type', err) } } - this.log.trace('setting content type to "%s"', contentType) - response.headers.set('content-type', contentType) + this.log.trace('setting content type to "%s"', contentType ?? defaultContentType) + response.headers.set('content-type', contentType ?? defaultContentType) } /** diff --git a/packages/verified-fetch/test/content-type-parser.spec.ts b/packages/verified-fetch/test/content-type-parser.spec.ts index b614529..54deb03 100644 --- a/packages/verified-fetch/test/content-type-parser.spec.ts +++ b/packages/verified-fetch/test/content-type-parser.spec.ts @@ -1,15 +1,15 @@ -import { createHeliaHTTP } from '@helia/http' import { unixfs } from '@helia/unixfs' import { stop } from '@libp2p/interface' import { fileTypeFromBuffer } from '@sgtpooki/file-type' import { expect } from 'aegir/chai' import { filetypemime } from 'magic-bytes.js' +import { CID } from 'multiformats/cid' import Sinon from 'sinon' import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' import { createVerifiedFetch } from '../src/index.js' import { VerifiedFetch } from '../src/verified-fetch.js' +import { createHelia } from './fixtures/create-offline-helia.js' import type { Helia } from '@helia/interface' -import type { CID } from 'multiformats/cid' describe('content-type-parser', () => { let helia: Helia @@ -17,7 +17,7 @@ describe('content-type-parser', () => { let verifiedFetch: VerifiedFetch beforeEach(async () => { - helia = await createHeliaHTTP() + helia = await createHelia() const fs = unixfs(helia) cid = await fs.addByteStream((async function * () { yield uint8ArrayFromString('H4sICIlTHVIACw', 'base64') @@ -132,4 +132,16 @@ describe('content-type-parser', () => { const resp = await verifiedFetch.fetch(cid) expect(resp.headers.get('content-type')).to.equal('application/gzip') }) + + it('can properly set content type for identity CIDs', async () => { + verifiedFetch = new VerifiedFetch({ + helia + }, { + contentTypeParser: async (data) => { + return 'text/plain' + } + }) + const resp = await verifiedFetch.fetch(CID.parse('bafkqablimvwgy3y')) + expect(resp.headers.get('content-type')).to.equal('text/plain') + }) }) diff --git a/packages/verified-fetch/test/fixtures/create-offline-helia.ts b/packages/verified-fetch/test/fixtures/create-offline-helia.ts index 389662e..8b7e3d1 100644 --- a/packages/verified-fetch/test/fixtures/create-offline-helia.ts +++ b/packages/verified-fetch/test/fixtures/create-offline-helia.ts @@ -1,12 +1,13 @@ import { Helia as HeliaClass } from '@helia/utils' import { MemoryBlockstore } from 'blockstore-core' +import { IdentityBlockstore } from 'blockstore-core/identity' import { MemoryDatastore } from 'datastore-core' import type { HeliaHTTPInit } from '@helia/http' import type { Helia } from '@helia/interface' export async function createHelia (init: Partial = {}): Promise { const datastore = new MemoryDatastore() - const blockstore = new MemoryBlockstore() + const blockstore = new IdentityBlockstore(new MemoryBlockstore()) const helia = new HeliaClass({ datastore,